3838 * in tl_scrollback are no longer used.
3939 *
4040 * TODO:
41+ * - ":term NONE" does not work in MS-Windows.
4142 * - better check for blinking - reply from Thomas Dickey Aug 22
4243 * - test for writing lines to terminal job does not work on MS-Windows
4344 * - implement term_setsize()
4748 * - do not set bufhidden to "hide"? works like a buffer with changes.
4849 * document that CTRL-W :hide can be used.
4950 * - GUI: when using tabs, focus in terminal, click on tab does not work.
51+ * - When $HOME was set by Vim (MS-Windows), do not pass it to the job.
5052 * - GUI: when 'confirm' is set and trying to exit Vim, dialog offers to save
5153 * changes to "!shell".
5254 * (justrajdeep, 2017 Aug 22)
6264 * shell writing stderr to a file or buffer
6365 * - For the GUI fill termios with default values, perhaps like pangoterm:
6466 * http://bazaar.launchpad.net/~leonerd/pangoterm/trunk/view/head:/main.c#L134
65- * - support ":term NONE" to open a terminal with a pty but not running a job
66- * in it. The pty can be passed to gdb to run the executable in.
6767 * - if the job in the terminal does not support the mouse, we can use the
6868 * mouse in the Terminal window for copy/paste.
6969 * - when 'encoding' is not utf-8, or the job is using another encoding, setup
@@ -163,8 +163,8 @@ static term_T *in_terminal_loop = NULL;
163163/*
164164 * Functions with separate implementation for MS-Windows and Unix-like systems.
165165 */
166- static int term_and_job_init (term_T * term , int rows , int cols ,
167- typval_T * argvar , jobopt_T * opt );
166+ static int term_and_job_init (term_T * term , typval_T * argvar , jobopt_T * opt );
167+ static int create_pty_only ( term_T * term , jobopt_T * opt );
168168static void term_report_winsize (term_T * term , int rows , int cols );
169169static void term_free_vterm (term_T * term );
170170
@@ -256,6 +256,7 @@ term_start(typval_T *argvar, jobopt_T *opt, int forceit)
256256 win_T * old_curwin = curwin ;
257257 term_T * term ;
258258 buf_T * old_curbuf = NULL ;
259+ int res ;
259260
260261 if (check_restricted () || check_secure ())
261262 return ;
@@ -355,7 +356,13 @@ term_start(typval_T *argvar, jobopt_T *opt, int forceit)
355356 char_u * cmd , * p ;
356357
357358 if (argvar -> v_type == VAR_STRING )
359+ {
358360 cmd = argvar -> vval .v_string ;
361+ if (cmd == NULL )
362+ cmd = (char_u * )"" ;
363+ else if (STRCMP (cmd , "NONE" ) == 0 )
364+ cmd = (char_u * )"pty" ;
365+ }
359366 else if (argvar -> v_type != VAR_LIST
360367 || argvar -> vval .v_list == NULL
361368 || argvar -> vval .v_list -> lv_len < 1 )
@@ -400,9 +407,15 @@ term_start(typval_T *argvar, jobopt_T *opt, int forceit)
400407 set_term_and_win_size (term );
401408 setup_job_options (opt , term -> tl_rows , term -> tl_cols );
402409
403- /* System dependent: setup the vterm and start the job in it. */
404- if (term_and_job_init (term , term -> tl_rows , term -> tl_cols , argvar , opt )
405- == OK )
410+ /* System dependent: setup the vterm and maybe start the job in it. */
411+ if (argvar -> v_type == VAR_STRING
412+ && argvar -> vval .v_string != NULL
413+ && STRCMP (argvar -> vval .v_string , "NONE" ) == 0 )
414+ res = create_pty_only (term , opt );
415+ else
416+ res = term_and_job_init (term , argvar , opt );
417+
418+ if (res == OK )
406419 {
407420 /* Get and remember the size we ended up with. Update the pty. */
408421 vterm_get_size (term -> tl_vterm , & term -> tl_rows , & term -> tl_cols );
@@ -553,7 +566,8 @@ free_terminal(buf_T *buf)
553566 if (term -> tl_job != NULL )
554567 {
555568 if (term -> tl_job -> jv_status != JOB_ENDED
556- && term -> tl_job -> jv_status != JOB_FAILED )
569+ && term -> tl_job -> jv_status != JOB_FINISHED
570+ && term -> tl_job -> jv_status != JOB_FAILED )
557571 job_stop (term -> tl_job , NULL , "kill" );
558572 job_unref (term -> tl_job );
559573 }
@@ -839,8 +853,9 @@ term_job_running(term_T *term)
839853 * race condition when updating the title. */
840854 return term != NULL
841855 && term -> tl_job != NULL
842- && term -> tl_job -> jv_status == JOB_STARTED
843- && channel_is_open (term -> tl_job -> jv_channel );
856+ && channel_is_open (term -> tl_job -> jv_channel )
857+ && (term -> tl_job -> jv_status == JOB_STARTED
858+ || term -> tl_job -> jv_channel -> ch_keep_open );
844859}
845860
846861/*
@@ -2842,9 +2857,14 @@ f_term_wait(typval_T *argvars, typval_T *rettv UNUSED)
28422857 ch_log (NULL , "term_wait(): no job to wait for" );
28432858 return ;
28442859 }
2860+ if (buf -> b_term -> tl_job -> jv_channel == NULL )
2861+ /* channel is closed, nothing to do */
2862+ return ;
28452863
28462864 /* Get the job status, this will detect a job that finished. */
2847- if (STRCMP (job_status (buf -> b_term -> tl_job ), "dead" ) == 0 )
2865+ if ((buf -> b_term -> tl_job -> jv_channel == NULL
2866+ || !buf -> b_term -> tl_job -> jv_channel -> ch_keep_open )
2867+ && STRCMP (job_status (buf -> b_term -> tl_job ), "dead" ) == 0 )
28482868 {
28492869 /* The job is dead, keep reading channel I/O until the channel is
28502870 * closed. */
@@ -2976,8 +2996,6 @@ dyn_winpty_init(int verbose)
29762996 static int
29772997term_and_job_init (
29782998 term_T * term ,
2979- int rows ,
2980- int cols ,
29812999 typval_T * argvar ,
29823000 jobopt_T * opt )
29833001{
@@ -3023,7 +3041,8 @@ term_and_job_init(
30233041 if (term -> tl_winpty_config == NULL )
30243042 goto failed ;
30253043
3026- winpty_config_set_initial_size (term -> tl_winpty_config , cols , rows );
3044+ winpty_config_set_initial_size (term -> tl_winpty_config ,
3045+ term -> tl_cols , term -> tl_rows );
30273046 term -> tl_winpty = winpty_open (term -> tl_winpty_config , & winpty_err );
30283047 if (term -> tl_winpty == NULL )
30293048 goto failed ;
@@ -3085,7 +3104,7 @@ term_and_job_init(
30853104 winpty_spawn_config_free (spawn_config );
30863105 vim_free (cmd_wchar );
30873106
3088- create_vterm (term , rows , cols );
3107+ create_vterm (term , term -> tl_rows , term -> tl_cols );
30893108
30903109 channel_set_job (channel , job , opt );
30913110 job_set_options (job , opt );
@@ -3137,6 +3156,13 @@ term_and_job_init(
31373156 return FAIL ;
31383157}
31393158
3159+ static int
3160+ create_pty_only (term_T * term , jobopt_T * opt )
3161+ {
3162+ /* TODO: implement this */
3163+ return FAIL ;
3164+ }
3165+
31403166/*
31413167 * Free the terminal emulator part of "term".
31423168 */
@@ -3185,12 +3211,10 @@ terminal_enabled(void)
31853211 static int
31863212term_and_job_init (
31873213 term_T * term ,
3188- int rows ,
3189- int cols ,
31903214 typval_T * argvar ,
31913215 jobopt_T * opt )
31923216{
3193- create_vterm (term , rows , cols );
3217+ create_vterm (term , term -> tl_rows , term -> tl_cols );
31943218
31953219 /* TODO: if the command is "NONE" only create a pty. */
31963220 term -> tl_job = job_start (argvar , opt );
@@ -3202,6 +3226,26 @@ term_and_job_init(
32023226 && term -> tl_job -> jv_status != JOB_FAILED ? OK : FAIL ;
32033227}
32043228
3229+ static int
3230+ create_pty_only (term_T * term , jobopt_T * opt )
3231+ {
3232+ int ret ;
3233+
3234+ create_vterm (term , term -> tl_rows , term -> tl_cols );
3235+
3236+ term -> tl_job = job_alloc ();
3237+ if (term -> tl_job == NULL )
3238+ return FAIL ;
3239+ ++ term -> tl_job -> jv_refcount ;
3240+
3241+ /* behave like the job is already finished */
3242+ term -> tl_job -> jv_status = JOB_FINISHED ;
3243+
3244+ ret = mch_create_pty_channel (term -> tl_job , opt );
3245+
3246+ return ret ;
3247+ }
3248+
32053249/*
32063250 * Free the terminal emulator part of "term".
32073251 */
0 commit comments