Skip to content

Commit 197c6b7

Browse files
committed
patch 8.1.2251: ":term command" may not work without a shell
Problem: ":term command" may not work without a shell. Solution: Add the ++shell option to :term. (closes #3340)
1 parent 30efcf3 commit 197c6b7

6 files changed

Lines changed: 52 additions & 10 deletions

File tree

runtime/doc/terminal.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,10 @@ Command syntax ~
210210
no window will be used.
211211
++norestore Do not include this terminal window
212212
in a session file.
213+
++shell Instead of executing {command}
214+
directly, use a shell, like with
215+
`:!command` *E279*
216+
{only works on Unix currently}
213217
++kill={how} When trying to close the terminal
214218
window kill the job with {how}. See
215219
|term_setkill()| for the values.

src/os_unix.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4299,10 +4299,10 @@ may_send_sigint(int c UNUSED, pid_t pid UNUSED, pid_t wpid UNUSED)
42994299
# endif
43004300
}
43014301

4302-
#if !defined(USE_SYSTEM) || (defined(FEAT_GUI) && defined(FEAT_TERMINAL))
4302+
#if !defined(USE_SYSTEM) || defined(FEAT_TERMINAL) || defined(PROTO)
43034303

4304-
static int
4305-
build_argv(
4304+
int
4305+
unix_build_argv(
43064306
char_u *cmd,
43074307
char ***argvp,
43084308
char_u **sh_tofree,
@@ -4369,7 +4369,7 @@ mch_call_shell_terminal(
43694369
aco_save_T aco;
43704370
oparg_T oa; /* operator arguments */
43714371

4372-
if (build_argv(cmd, &argv, &tofree1, &tofree2) == FAIL)
4372+
if (unix_build_argv(cmd, &argv, &tofree1, &tofree2) == FAIL)
43734373
goto theend;
43744374

43754375
init_job_options(&opt);
@@ -4546,7 +4546,7 @@ mch_call_shell_fork(
45464546
if (options & SHELL_COOKED)
45474547
settmode(TMODE_COOK); /* set to normal mode */
45484548

4549-
if (build_argv(cmd, &argv, &tofree1, &tofree2) == FAIL)
4549+
if (unix_build_argv(cmd, &argv, &tofree1, &tofree2) == FAIL)
45504550
goto error;
45514551

45524552
/*

src/proto/os_unix.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ int mch_get_shellsize(void);
5959
int mch_report_winsize(int fd, int rows, int cols);
6060
void mch_set_shellsize(void);
6161
void mch_new_shellsize(void);
62+
int unix_build_argv(char_u *cmd, char ***argvp, char_u **sh_tofree, char_u **shcf_tofree);
6263
int mch_call_shell(char_u *cmd, int options);
6364
void mch_job_start(char **argv, job_T *job, jobopt_T *options, int is_terminal);
6465
char *mch_job_status(job_T *job);

src/terminal.c

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,7 @@ ex_terminal(exarg_T *eap)
703703
{
704704
typval_T argvar[2];
705705
jobopt_T opt;
706+
int opt_shell = FALSE;
706707
char_u *cmd;
707708
char_u *tofree = NULL;
708709

@@ -738,6 +739,8 @@ ex_terminal(exarg_T *eap)
738739
opt.jo_hidden = 1;
739740
else if (OPTARG_HAS("norestore"))
740741
opt.jo_term_norestore = 1;
742+
else if (OPTARG_HAS("shell"))
743+
opt_shell = TRUE;
741744
else if (OPTARG_HAS("kill") && ep != NULL)
742745
{
743746
opt.jo_set2 |= JO2_TERM_KILL;
@@ -831,10 +834,30 @@ ex_terminal(exarg_T *eap)
831834
opt.jo_in_bot = eap->line2;
832835
}
833836

834-
argvar[0].v_type = VAR_STRING;
835-
argvar[0].vval.v_string = cmd;
836-
argvar[1].v_type = VAR_UNKNOWN;
837-
term_start(argvar, NULL, &opt, eap->forceit ? TERM_START_FORCEIT : 0);
837+
if (opt_shell && tofree == NULL)
838+
{
839+
#ifdef UNIX
840+
char **argv = NULL;
841+
char_u *tofree1 = NULL;
842+
char_u *tofree2 = NULL;
843+
844+
// :term ++shell command
845+
if (unix_build_argv(cmd, &argv, &tofree1, &tofree2) == OK)
846+
term_start(NULL, argv, &opt, eap->forceit ? TERM_START_FORCEIT : 0);
847+
vim_free(tofree1);
848+
vim_free(tofree2);
849+
#else
850+
emsg(_("E279: Sorry, ++shell is not supported on this system"));
851+
#endif
852+
}
853+
else
854+
{
855+
argvar[0].v_type = VAR_STRING;
856+
argvar[0].vval.v_string = cmd;
857+
argvar[1].v_type = VAR_UNKNOWN;
858+
term_start(argvar, NULL, &opt, eap->forceit ? TERM_START_FORCEIT : 0);
859+
}
860+
838861
vim_free(tofree);
839862

840863
theend:
@@ -6474,7 +6497,7 @@ winpty_term_and_job_init(
64746497
term_and_job_init(
64756498
term_T *term,
64766499
typval_T *argvar,
6477-
char **argv UNUSED,
6500+
char **argv,
64786501
jobopt_T *opt,
64796502
jobopt_T *orig_opt)
64806503
{

src/testdir/test_terminal.vim

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2214,6 +2214,18 @@ func Test_terminal_altscreen()
22142214
call delete('Xtext')
22152215
endfunc
22162216

2217+
func Test_terminal_shell_option()
2218+
CheckUnix
2219+
" exec is a shell builtin command, should fail without a shell.
2220+
term exec ls runtest.vim
2221+
call WaitForAssert({-> assert_match('job failed', term_getline(bufnr(), 1))})
2222+
bwipe!
2223+
2224+
term ++shell exec ls runtest.vim
2225+
call WaitForAssert({-> assert_match('runtest.vim', term_getline(bufnr(), 1))})
2226+
bwipe!
2227+
endfunc
2228+
22172229
func Test_terminal_setapi_and_call()
22182230
if !CanRunVimInTerminal()
22192231
return

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,8 @@ static char *(features[]) =
741741

742742
static int included_patches[] =
743743
{ /* Add new patch number below this line */
744+
/**/
745+
2251,
744746
/**/
745747
2250,
746748
/**/

0 commit comments

Comments
 (0)