@@ -4912,7 +4912,8 @@ static const char *required_env_vars[] = {
49124912
49134913static dict_T * create_environment (const dictitem_T * job_env ,
49144914 const bool clear_env ,
4915- const bool pty )
4915+ const bool pty ,
4916+ const char * const pty_term_name )
49164917{
49174918 dict_T * env = tv_dict_alloc ();
49184919
@@ -4946,6 +4947,18 @@ static dict_T *create_environment(const dictitem_T *job_env,
49464947 }
49474948 }
49484949
4950+ // For a pty, we need a sane $TERM set. We can't rely on nvim's environment,
4951+ // because the child process is going to be communicating with nvim, not the
4952+ // parent terminal. Set a sane default, but let the user override it in the
4953+ // job's environment if they want.
4954+ if (pty ) {
4955+ dictitem_T * dv = tv_dict_find (env , S_LEN ("TERM" ));
4956+ if (dv ) {
4957+ tv_dict_item_remove (env , dv );
4958+ }
4959+ tv_dict_add_str (env , S_LEN ("TERM" ), pty_term_name );
4960+ }
4961+
49494962 if (job_env ) {
49504963 tv_dict_extend (env , job_env -> di_tv .vval .v_dict , "force" );
49514964 }
@@ -5055,20 +5068,25 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
50555068 }
50565069 }
50575070
5058- env = create_environment (job_env , clear_env , pty );
5059-
50605071 uint16_t width = 0 , height = 0 ;
50615072 char * term_name = NULL ;
50625073
50635074 if (pty ) {
50645075 width = (uint16_t )tv_dict_get_number (job_opts , "width" );
50655076 height = (uint16_t )tv_dict_get_number (job_opts , "height" );
5066- term_name = tv_dict_get_string (job_opts , "TERM" , true);
5077+ // Legacy method, before env option existed, to specify $TERM. No longer
5078+ // documented, but still usable to avoid breaking scripts.
5079+ term_name = tv_dict_get_string (job_opts , "TERM" , false);
5080+ if (!term_name ) {
5081+ term_name = "ansi" ;
5082+ }
50675083 }
50685084
5085+ env = create_environment (job_env , clear_env , pty , term_name );
5086+
50695087 Channel * chan = channel_job_start (argv , on_stdout , on_stderr , on_exit , pty ,
50705088 rpc , overlapped , detach , cwd , width , height ,
5071- term_name , env , & rettv -> vval .v_number );
5089+ env , & rettv -> vval .v_number );
50725090 if (chan ) {
50735091 channel_create_event (chan , NULL );
50745092 }
@@ -7511,7 +7529,7 @@ static void f_rpcstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
75117529 Channel * chan = channel_job_start (argv , CALLBACK_READER_INIT ,
75127530 CALLBACK_READER_INIT , CALLBACK_NONE ,
75137531 false, true, false, false, NULL , 0 , 0 ,
7514- NULL , NULL , & rettv -> vval .v_number );
7532+ NULL , & rettv -> vval .v_number );
75157533 if (chan ) {
75167534 channel_create_event (chan , NULL );
75177535 }
@@ -10618,7 +10636,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
1061810636 }
1061910637 }
1062010638
10621- env = create_environment (job_env , clear_env , pty );
10639+ env = create_environment (job_env , clear_env , pty , "xterm-256color" );
1062210640
1062310641 const bool rpc = false;
1062410642 const bool overlapped = false;
@@ -10627,8 +10645,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
1062710645 Channel * chan = channel_job_start (argv , on_stdout , on_stderr , on_exit ,
1062810646 pty , rpc , overlapped , detach , cwd ,
1062910647 term_width , curwin -> w_height_inner ,
10630- xstrdup ("xterm-256color" ), env ,
10631- & rettv -> vval .v_number );
10648+ env , & rettv -> vval .v_number );
1063210649 if (rettv -> vval .v_number <= 0 ) {
1063310650 return ;
1063410651 }
0 commit comments