mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
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)
This commit is contained in:
@@ -210,6 +210,10 @@ Command syntax ~
|
|||||||
no window will be used.
|
no window will be used.
|
||||||
++norestore Do not include this terminal window
|
++norestore Do not include this terminal window
|
||||||
in a session file.
|
in a session file.
|
||||||
|
++shell Instead of executing {command}
|
||||||
|
directly, use a shell, like with
|
||||||
|
`:!command` *E279*
|
||||||
|
{only works on Unix currently}
|
||||||
++kill={how} When trying to close the terminal
|
++kill={how} When trying to close the terminal
|
||||||
window kill the job with {how}. See
|
window kill the job with {how}. See
|
||||||
|term_setkill()| for the values.
|
|term_setkill()| for the values.
|
||||||
|
@@ -4299,10 +4299,10 @@ may_send_sigint(int c UNUSED, pid_t pid UNUSED, pid_t wpid UNUSED)
|
|||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(USE_SYSTEM) || (defined(FEAT_GUI) && defined(FEAT_TERMINAL))
|
#if !defined(USE_SYSTEM) || defined(FEAT_TERMINAL) || defined(PROTO)
|
||||||
|
|
||||||
static int
|
int
|
||||||
build_argv(
|
unix_build_argv(
|
||||||
char_u *cmd,
|
char_u *cmd,
|
||||||
char ***argvp,
|
char ***argvp,
|
||||||
char_u **sh_tofree,
|
char_u **sh_tofree,
|
||||||
@@ -4369,7 +4369,7 @@ mch_call_shell_terminal(
|
|||||||
aco_save_T aco;
|
aco_save_T aco;
|
||||||
oparg_T oa; /* operator arguments */
|
oparg_T oa; /* operator arguments */
|
||||||
|
|
||||||
if (build_argv(cmd, &argv, &tofree1, &tofree2) == FAIL)
|
if (unix_build_argv(cmd, &argv, &tofree1, &tofree2) == FAIL)
|
||||||
goto theend;
|
goto theend;
|
||||||
|
|
||||||
init_job_options(&opt);
|
init_job_options(&opt);
|
||||||
@@ -4546,7 +4546,7 @@ mch_call_shell_fork(
|
|||||||
if (options & SHELL_COOKED)
|
if (options & SHELL_COOKED)
|
||||||
settmode(TMODE_COOK); /* set to normal mode */
|
settmode(TMODE_COOK); /* set to normal mode */
|
||||||
|
|
||||||
if (build_argv(cmd, &argv, &tofree1, &tofree2) == FAIL)
|
if (unix_build_argv(cmd, &argv, &tofree1, &tofree2) == FAIL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -59,6 +59,7 @@ int mch_get_shellsize(void);
|
|||||||
int mch_report_winsize(int fd, int rows, int cols);
|
int mch_report_winsize(int fd, int rows, int cols);
|
||||||
void mch_set_shellsize(void);
|
void mch_set_shellsize(void);
|
||||||
void mch_new_shellsize(void);
|
void mch_new_shellsize(void);
|
||||||
|
int unix_build_argv(char_u *cmd, char ***argvp, char_u **sh_tofree, char_u **shcf_tofree);
|
||||||
int mch_call_shell(char_u *cmd, int options);
|
int mch_call_shell(char_u *cmd, int options);
|
||||||
void mch_job_start(char **argv, job_T *job, jobopt_T *options, int is_terminal);
|
void mch_job_start(char **argv, job_T *job, jobopt_T *options, int is_terminal);
|
||||||
char *mch_job_status(job_T *job);
|
char *mch_job_status(job_T *job);
|
||||||
|
@@ -703,6 +703,7 @@ ex_terminal(exarg_T *eap)
|
|||||||
{
|
{
|
||||||
typval_T argvar[2];
|
typval_T argvar[2];
|
||||||
jobopt_T opt;
|
jobopt_T opt;
|
||||||
|
int opt_shell = FALSE;
|
||||||
char_u *cmd;
|
char_u *cmd;
|
||||||
char_u *tofree = NULL;
|
char_u *tofree = NULL;
|
||||||
|
|
||||||
@@ -738,6 +739,8 @@ ex_terminal(exarg_T *eap)
|
|||||||
opt.jo_hidden = 1;
|
opt.jo_hidden = 1;
|
||||||
else if (OPTARG_HAS("norestore"))
|
else if (OPTARG_HAS("norestore"))
|
||||||
opt.jo_term_norestore = 1;
|
opt.jo_term_norestore = 1;
|
||||||
|
else if (OPTARG_HAS("shell"))
|
||||||
|
opt_shell = TRUE;
|
||||||
else if (OPTARG_HAS("kill") && ep != NULL)
|
else if (OPTARG_HAS("kill") && ep != NULL)
|
||||||
{
|
{
|
||||||
opt.jo_set2 |= JO2_TERM_KILL;
|
opt.jo_set2 |= JO2_TERM_KILL;
|
||||||
@@ -831,10 +834,30 @@ ex_terminal(exarg_T *eap)
|
|||||||
opt.jo_in_bot = eap->line2;
|
opt.jo_in_bot = eap->line2;
|
||||||
}
|
}
|
||||||
|
|
||||||
argvar[0].v_type = VAR_STRING;
|
if (opt_shell && tofree == NULL)
|
||||||
argvar[0].vval.v_string = cmd;
|
{
|
||||||
argvar[1].v_type = VAR_UNKNOWN;
|
#ifdef UNIX
|
||||||
term_start(argvar, NULL, &opt, eap->forceit ? TERM_START_FORCEIT : 0);
|
char **argv = NULL;
|
||||||
|
char_u *tofree1 = NULL;
|
||||||
|
char_u *tofree2 = NULL;
|
||||||
|
|
||||||
|
// :term ++shell command
|
||||||
|
if (unix_build_argv(cmd, &argv, &tofree1, &tofree2) == OK)
|
||||||
|
term_start(NULL, argv, &opt, eap->forceit ? TERM_START_FORCEIT : 0);
|
||||||
|
vim_free(tofree1);
|
||||||
|
vim_free(tofree2);
|
||||||
|
#else
|
||||||
|
emsg(_("E279: Sorry, ++shell is not supported on this system"));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
argvar[0].v_type = VAR_STRING;
|
||||||
|
argvar[0].vval.v_string = cmd;
|
||||||
|
argvar[1].v_type = VAR_UNKNOWN;
|
||||||
|
term_start(argvar, NULL, &opt, eap->forceit ? TERM_START_FORCEIT : 0);
|
||||||
|
}
|
||||||
|
|
||||||
vim_free(tofree);
|
vim_free(tofree);
|
||||||
|
|
||||||
theend:
|
theend:
|
||||||
@@ -6474,7 +6497,7 @@ failed:
|
|||||||
term_and_job_init(
|
term_and_job_init(
|
||||||
term_T *term,
|
term_T *term,
|
||||||
typval_T *argvar,
|
typval_T *argvar,
|
||||||
char **argv UNUSED,
|
char **argv,
|
||||||
jobopt_T *opt,
|
jobopt_T *opt,
|
||||||
jobopt_T *orig_opt)
|
jobopt_T *orig_opt)
|
||||||
{
|
{
|
||||||
|
@@ -2214,6 +2214,18 @@ func Test_terminal_altscreen()
|
|||||||
call delete('Xtext')
|
call delete('Xtext')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_terminal_shell_option()
|
||||||
|
CheckUnix
|
||||||
|
" exec is a shell builtin command, should fail without a shell.
|
||||||
|
term exec ls runtest.vim
|
||||||
|
call WaitForAssert({-> assert_match('job failed', term_getline(bufnr(), 1))})
|
||||||
|
bwipe!
|
||||||
|
|
||||||
|
term ++shell exec ls runtest.vim
|
||||||
|
call WaitForAssert({-> assert_match('runtest.vim', term_getline(bufnr(), 1))})
|
||||||
|
bwipe!
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_terminal_setapi_and_call()
|
func Test_terminal_setapi_and_call()
|
||||||
if !CanRunVimInTerminal()
|
if !CanRunVimInTerminal()
|
||||||
return
|
return
|
||||||
|
@@ -741,6 +741,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
2251,
|
||||||
/**/
|
/**/
|
||||||
2250,
|
2250,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user