@@ -245,30 +245,35 @@ setup_job_options(jobopt_T *opt, int rows, int cols)
245245 opt -> jo_term_cols = cols ;
246246}
247247
248- static void
248+ /*
249+ * Start a terminal window and return its buffer.
250+ * Returns NULL when failed.
251+ */
252+ static buf_T *
249253term_start (typval_T * argvar , jobopt_T * opt , int forceit )
250254{
251255 exarg_T split_ea ;
252256 win_T * old_curwin = curwin ;
253257 term_T * term ;
254258 buf_T * old_curbuf = NULL ;
255259 int res ;
260+ buf_T * newbuf ;
256261
257262 if (check_restricted () || check_secure ())
258- return ;
263+ return NULL ;
259264
260265 if ((opt -> jo_set & (JO_IN_IO + JO_OUT_IO + JO_ERR_IO ))
261266 == (JO_IN_IO + JO_OUT_IO + JO_ERR_IO )
262267 || (!(opt -> jo_set & JO_OUT_IO ) && (opt -> jo_set & JO_OUT_BUF ))
263268 || (!(opt -> jo_set & JO_ERR_IO ) && (opt -> jo_set & JO_ERR_BUF )))
264269 {
265270 EMSG (_ (e_invarg ));
266- return ;
271+ return NULL ;
267272 }
268273
269274 term = (term_T * )alloc_clear (sizeof (term_T ));
270275 if (term == NULL )
271- return ;
276+ return NULL ;
272277 term -> tl_dirty_row_end = MAX_ROW ;
273278 term -> tl_cursor_visible = TRUE;
274279 term -> tl_cursor_shape = VTERM_PROP_CURSORSHAPE_BLOCK ;
@@ -283,13 +288,13 @@ term_start(typval_T *argvar, jobopt_T *opt, int forceit)
283288 {
284289 no_write_message ();
285290 vim_free (term );
286- return ;
291+ return NULL ;
287292 }
288293 if (do_ecmd (0 , NULL , NULL , & split_ea , ECMD_ONE ,
289294 ECMD_HIDE + (forceit ? ECMD_FORCEIT : 0 ), curwin ) == FAIL )
290295 {
291296 vim_free (term );
292- return ;
297+ return NULL ;
293298 }
294299 }
295300 else if (opt -> jo_hidden )
@@ -303,7 +308,7 @@ term_start(typval_T *argvar, jobopt_T *opt, int forceit)
303308 if (buf == NULL || ml_open (buf ) == FAIL )
304309 {
305310 vim_free (term );
306- return ;
311+ return NULL ;
307312 }
308313 old_curbuf = curbuf ;
309314 -- curbuf -> b_nwindows ;
@@ -333,7 +338,7 @@ term_start(typval_T *argvar, jobopt_T *opt, int forceit)
333338 {
334339 /* split failed */
335340 vim_free (term );
336- return ;
341+ return NULL ;
337342 }
338343 }
339344 term -> tl_buffer = curbuf ;
@@ -419,6 +424,7 @@ term_start(typval_T *argvar, jobopt_T *opt, int forceit)
419424 else
420425 res = term_and_job_init (term , argvar , opt );
421426
427+ newbuf = curbuf ;
422428 if (res == OK )
423429 {
424430 /* Get and remember the size we ended up with. Update the pty. */
@@ -453,7 +459,9 @@ term_start(typval_T *argvar, jobopt_T *opt, int forceit)
453459 /* Wiping out the buffer will also close the window and call
454460 * free_terminal(). */
455461 do_buffer (DOBUF_WIPE , DOBUF_FIRST , FORWARD , buf -> b_fnum , TRUE);
462+ return NULL ;
456463 }
464+ return newbuf ;
457465}
458466
459467/*
@@ -688,7 +696,7 @@ write_to_term(buf_T *buffer, char_u *msg, channel_T *channel)
688696 update_screen (0 );
689697 update_cursor (term , TRUE);
690698 }
691- else
699+ else if ( buffer -> b_nwindows > 0 )
692700 redraw_after_callback (TRUE);
693701 }
694702}
@@ -878,6 +886,20 @@ term_job_running(term_T *term)
878886 || term -> tl_job -> jv_channel -> ch_keep_open );
879887}
880888
889+ /*
890+ * Return TRUE if "term" has an active channel and used ":term NONE".
891+ */
892+ int
893+ term_none_open (term_T * term )
894+ {
895+ /* Also consider the job finished when the channel is closed, to avoid a
896+ * race condition when updating the title. */
897+ return term != NULL
898+ && term -> tl_job != NULL
899+ && channel_is_open (term -> tl_job -> jv_channel )
900+ && term -> tl_job -> jv_channel -> ch_keep_open ;
901+ }
902+
881903/*
882904 * Add the last line of the scrollback buffer to the buffer in the window.
883905 */
@@ -2379,6 +2401,8 @@ term_get_status_text(term_T *term)
23792401 }
23802402 else if (term -> tl_title != NULL )
23812403 txt = term -> tl_title ;
2404+ else if (term_none_open (term ))
2405+ txt = (char_u * )_ ("active" );
23822406 else if (term_job_running (term ))
23832407 txt = (char_u * )_ ("running" );
23842408 else
@@ -2858,11 +2882,13 @@ f_term_sendkeys(typval_T *argvars, typval_T *rettv)
28582882f_term_start (typval_T * argvars , typval_T * rettv )
28592883{
28602884 jobopt_T opt ;
2885+ buf_T * buf ;
28612886
28622887 init_job_options (& opt );
28632888 if (argvars [1 ].v_type != VAR_UNKNOWN
28642889 && get_job_options (& argvars [1 ], & opt ,
28652890 JO_TIMEOUT_ALL + JO_STOPONEXIT
2891+ + JO_CALLBACK + JO_OUT_CALLBACK + JO_ERR_CALLBACK
28662892 + JO_EXIT_CB + JO_CLOSE_CALLBACK + JO_OUT_IO ,
28672893 JO2_TERM_NAME + JO2_TERM_FINISH + JO2_HIDDEN + JO2_TERM_OPENCMD
28682894 + JO2_TERM_COLS + JO2_TERM_ROWS + JO2_VERTICAL + JO2_CURWIN
@@ -2871,10 +2897,10 @@ f_term_start(typval_T *argvars, typval_T *rettv)
28712897
28722898 if (opt .jo_vertical )
28732899 cmdmod .split = WSP_VERT ;
2874- term_start (& argvars [0 ], & opt , FALSE);
2900+ buf = term_start (& argvars [0 ], & opt , FALSE);
28752901
2876- if (curbuf -> b_term != NULL )
2877- rettv -> vval .v_number = curbuf -> b_fnum ;
2902+ if (buf != NULL && buf -> b_term != NULL )
2903+ rettv -> vval .v_number = buf -> b_fnum ;
28782904}
28792905
28802906/*
@@ -3359,8 +3385,6 @@ term_and_job_init(
33593385 static int
33603386create_pty_only (term_T * term , jobopt_T * opt )
33613387{
3362- int ret ;
3363-
33643388 create_vterm (term , term -> tl_rows , term -> tl_cols );
33653389
33663390 term -> tl_job = job_alloc ();
@@ -3371,9 +3395,7 @@ create_pty_only(term_T *term, jobopt_T *opt)
33713395 /* behave like the job is already finished */
33723396 term -> tl_job -> jv_status = JOB_FINISHED ;
33733397
3374- ret = mch_create_pty_channel (term -> tl_job , opt );
3375-
3376- return ret ;
3398+ return mch_create_pty_channel (term -> tl_job , opt );
33773399}
33783400
33793401/*
0 commit comments