diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 73704a143c..a977794230 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -293,6 +293,7 @@ TERMINAL means that the |TermCursorNC| highlight group is no longer supported: an unfocused terminal window will have no cursor at all (so there is nothing to highlight). +• |jobstart()| gained the "term" flag. TREESITTER diff --git a/src/nvim/eval/deprecated.c b/src/nvim/eval/deprecated.c index 0874e4ae76..67c254dac9 100644 --- a/src/nvim/eval/deprecated.c +++ b/src/nvim/eval/deprecated.c @@ -42,4 +42,3 @@ void f_termopen(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) tv_dict_free(argvars[1].vval.v_dict); } } - diff --git a/src/nvim/eval/deprecated.h b/src/nvim/eval/deprecated.h index 69882695e7..04cf60218c 100644 --- a/src/nvim/eval/deprecated.h +++ b/src/nvim/eval/deprecated.h @@ -2,8 +2,8 @@ #include // for true -#include "nvim/message.h" // for semsg #include "nvim/eval/typval_defs.h" // IWYU pragma: keep +#include "nvim/message.h" // for semsg #include "nvim/types_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index e3fb2e7279..b36fd15516 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -3842,7 +3842,7 @@ static const char *required_env_vars[] = { }; dict_T *create_environment(const dictitem_T *job_env, const bool clear_env, const bool pty, - const char * const pty_term_name) + const char * const pty_term_name) { dict_T *env = tv_dict_alloc(); @@ -3992,6 +3992,14 @@ void f_jobstart(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) } } + dictitem_T *const job_term = tv_dict_find(job_opts, S_LEN("term")); + if (job_term && VAR_BOOL != job_term->di_tv.v_type) { + // Restrict "term" field to boolean, in case we want to allow buffer numbers in the future. + semsg(_(e_invarg2), "'term' must Boolean"); + shell_free_argv(argv); + return; + } + if (pty && rpc) { semsg(_(e_invarg2), "job cannot have both 'pty' and 'rpc' options set"); shell_free_argv(argv); @@ -4111,8 +4119,7 @@ void f_jobstart(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) channel_terminal_open(curbuf, chan); channel_create_event(chan, NULL); channel_decref(chan); - } - else if (chan) { + } else if (chan) { channel_create_event(chan, NULL); } } diff --git a/test/functional/core/job_spec.lua b/test/functional/core/job_spec.lua index 20b7ab0f13..7820ee7e1e 100644 --- a/test/functional/core/job_spec.lua +++ b/test/functional/core/job_spec.lua @@ -65,6 +65,31 @@ describe('jobs', function() ]]) end) + it('validation', function() + matches( + "E475: Invalid argument: job cannot have both 'pty' and 'rpc' options set", + pcall_err(command, "let j = jobstart(['cat', '-'], { 'pty': v:true, 'rpc': v:true })") + ) + matches( + 'E475: Invalid argument: expected valid directory', + pcall_err(command, "let j = jobstart(['cat', '-'], { 'cwd': 1 })") + ) + matches( + 'E475: Invalid argument: expected valid directory', + pcall_err(command, "let j = jobstart(['cat', '-'], { 'cwd': 'bogusssssss/bogus' })") + ) + matches( + "E475: Invalid argument: 'term' must Boolean", + pcall_err(command, "let j = jobstart(['cat', '-'], { 'term': 'bogus' })") + ) + matches( + "E475: Invalid argument: 'term' must Boolean", + pcall_err(command, "let j = jobstart(['cat', '-'], { 'term': 1 })") + ) + command("let j = jobstart(['cat', '-'], { 'term': v:true })") + command("let j = jobstart(['cat', '-'], { 'term': v:false })") + end) + it('must specify env option as a dict', function() command('let g:job_opts.env = v:true') local _, err = pcall(function() @@ -969,13 +994,6 @@ describe('jobs', function() eq({ 'notification', 'exit', { 0, 143 } }, next_msg()) end) - it('cannot have both rpc and pty options', function() - command('let g:job_opts.pty = v:true') - command('let g:job_opts.rpc = v:true') - local _, err = pcall(command, "let j = jobstart(['cat', '-'], g:job_opts)") - matches("E475: Invalid argument: job cannot have both 'pty' and 'rpc' options set", err) - end) - it('does not crash when repeatedly failing to start shell', function() source([[ set shell=nosuchshell