diff options
author | Evgeni Chasnovski <evgeni.chasnovski@gmail.com> | 2023-03-25 18:58:48 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-25 09:58:48 -0700 |
commit | fe9cbcb3a5c82932ecfb8f49d07e98a1fc2b31e5 (patch) | |
tree | b2828838c29b0a30befd703cf49a8d6cd16b89a0 | |
parent | 257d894d75bc583bb16f4dbe441907eb273d20ad (diff) | |
download | rneovim-fe9cbcb3a5c82932ecfb8f49d07e98a1fc2b31e5.tar.gz rneovim-fe9cbcb3a5c82932ecfb8f49d07e98a1fc2b31e5.tar.bz2 rneovim-fe9cbcb3a5c82932ecfb8f49d07e98a1fc2b31e5.zip |
feat(api): nvim_exec2(), deprecate nvim_exec() #19032
Problem:
The signature of nvim_exec() is not extensible per ":help api-contract".
Solution:
Introduce nvim_exec2() and deprecate nvim_exec().
28 files changed, 218 insertions, 158 deletions
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index 197edf2e81..ea57db22e0 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -1549,11 +1549,11 @@ nvim_command({command}) *nvim_command()* On execution error: fails with VimL error, updates v:errmsg. - Prefer using |nvim_cmd()| or |nvim_exec()| over this. To evaluate multiple - lines of Vim script or an Ex command directly, use |nvim_exec()|. To - construct an Ex command using a structured format and then execute it, use - |nvim_cmd()|. To modify an Ex command before evaluating it, use - |nvim_parse_cmd()| in conjunction with |nvim_cmd()|. + Prefer using |nvim_cmd()| or |nvim_exec2()| over this. To evaluate + multiple lines of Vim script or an Ex command directly, use + |nvim_exec2()|. To construct an Ex command using a structured format and + then execute it, use |nvim_cmd()|. To modify an Ex command before + evaluating it, use |nvim_parse_cmd()| in conjunction with |nvim_cmd()|. Parameters: ~ • {command} Ex command string @@ -1570,7 +1570,7 @@ nvim_eval({expr}) *nvim_eval()* Return: ~ Evaluation result or expanded object -nvim_exec({src}, {output}) *nvim_exec()* +nvim_exec2({src}, {*opts}) *nvim_exec2()* Executes Vimscript (multiline block of Ex commands), like anonymous |:source|. @@ -1580,12 +1580,14 @@ nvim_exec({src}, {output}) *nvim_exec()* On execution error: fails with VimL error, updates v:errmsg. Parameters: ~ - • {src} Vimscript code - • {output} Capture and return all (non-error, non-shell |:!|) output + • {src} Vimscript code + • {opts} Optional parameters. + • output: (boolean, default false) Whether to capture and + return all (non-error, non-shell |:!|) output. Return: ~ - Output (non-error, non-shell |:!|) if `output` is true, else empty - string. + Dictionary containing information about execution, with these keys: + • output: (string|nil) Output if `opts.output` is true. See also: ~ • |execute()| @@ -1738,7 +1740,7 @@ nvim_cmd({*cmd}, {*opts}) *nvim_cmd()* empty string. See also: ~ - • |nvim_exec()| + • |nvim_exec2()| • |nvim_command()| *nvim_create_user_command()* diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt index 84cc415a37..69cec8da53 100644 --- a/runtime/doc/deprecated.txt +++ b/runtime/doc/deprecated.txt @@ -15,10 +15,11 @@ Deprecated features API - *nvim_buf_clear_highlight()* Use |nvim_buf_clear_namespace()| instead. - *nvim_buf_set_virtual_text()* Use |nvim_buf_set_extmark()| instead. -- *nvim_command_output()* Use |nvim_exec()| instead. +- *nvim_command_output()* Use |nvim_exec2()| instead. - *nvim_execute_lua()* Use |nvim_exec_lua()| instead. - *nvim_get_hl_by_name()* Use |nvim_get_hl()| instead. - *nvim_get_hl_by_id()* Use |nvim_get_hl()| instead. +- *nvim_exec()* Use |nvim_exec2()| instead. COMMANDS - *:rv* *:rviminfo* Deprecated alias to |:rshada| command. diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index 018c6ce5a4..0bea2819c9 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -1355,9 +1355,9 @@ cmd({command}) *vim.cmd()* Parameters: ~ • {command} string|table Command(s) to execute. If a string, executes multiple lines of Vim script at once. In this case, it is - an alias to |nvim_exec()|, where `output` is set to false. - Thus it works identical to |:source|. If a table, executes - a single command. In this case, it is an alias to + an alias to |nvim_exec2()|, where `opts.output` is set to + false. Thus it works identical to |:source|. If a table, + executes a single command. In this case, it is an alias to |nvim_cmd()| where `opts` is empty. See also: ~ diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index f3950de683..20af29430a 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -60,6 +60,8 @@ The following changes may require adaptations in user config or plugins. • Renamed vim.pretty_print to vim.print. |deprecated| +• |nvim_exec()| is now deprecated in favor of |nvim_exec2()|. + ============================================================================== NEW FEATURES *news-features* diff --git a/runtime/lua/_vim9script.lua b/runtime/lua/_vim9script.lua index 363d061451..76e427b748 100644 --- a/runtime/lua/_vim9script.lua +++ b/runtime/lua/_vim9script.lua @@ -162,7 +162,7 @@ local vim9 = (function() end end - vim.api.nvim_exec(table.concat(file, '\n'), false) + vim.api.nvim_exec2(table.concat(file, '\n'), { output = false }) end, }) end diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index fd6a5865ce..db7a6c1d17 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -322,8 +322,8 @@ end --- ---@param command string|table Command(s) to execute. --- If a string, executes multiple lines of Vim script at once. In this ---- case, it is an alias to |nvim_exec()|, where `output` is set to ---- false. Thus it works identical to |:source|. +--- case, it is an alias to |nvim_exec2()|, where `opts.output` is set +--- to false. Thus it works identical to |:source|. --- If a table, executes a single command. In this case, it is an alias --- to |nvim_cmd()| where `opts` is empty. ---@see |ex-cmd-index| @@ -338,7 +338,7 @@ vim.cmd = setmetatable({}, { if type(command) == 'table' then return vim.api.nvim_cmd(command, {}) else - return vim.api.nvim_exec(command, false) + return vim.api.nvim_exec2(command, { output = false }).output end end, __index = function(t, command) diff --git a/src/nvim/api/command.c b/src/nvim/api/command.c index 1455f28050..26ee9205b2 100644 --- a/src/nvim/api/command.c +++ b/src/nvim/api/command.c @@ -307,7 +307,7 @@ end: /// /// On execution error: fails with VimL error, updates v:errmsg. /// -/// @see |nvim_exec()| +/// @see |nvim_exec2()| /// @see |nvim_command()| /// /// @param cmd Command to execute. Must be a Dictionary that can contain the same values as diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c index b1e2e6811e..6a12cfe2da 100644 --- a/src/nvim/api/deprecated.c +++ b/src/nvim/api/deprecated.c @@ -27,13 +27,26 @@ # include "api/deprecated.c.generated.h" #endif +/// @deprecated Use nvim_exec2() instead. +/// @see nvim_exec2 +String nvim_exec(uint64_t channel_id, String src, Boolean output, Error *err) + FUNC_API_SINCE(7) + FUNC_API_DEPRECATED_SINCE(11) +{ + Dict(exec_opts) opts = { 0 }; + opts.output = BOOLEAN_OBJ(output); + return exec_impl(channel_id, src, &opts, err); +} + /// @deprecated -/// @see nvim_exec +/// @see nvim_exec2 String nvim_command_output(uint64_t channel_id, String command, Error *err) FUNC_API_SINCE(1) FUNC_API_DEPRECATED_SINCE(7) { - return nvim_exec(channel_id, command, true, err); + Dict(exec_opts) opts = { 0 }; + opts.output = BOOLEAN_OBJ(true); + return exec_impl(channel_id, command, &opts, err); } /// @deprecated Use nvim_exec_lua() instead. diff --git a/src/nvim/api/keysets.lua b/src/nvim/api/keysets.lua index b2b327d73e..ce29001787 100644 --- a/src/nvim/api/keysets.lua +++ b/src/nvim/api/keysets.lua @@ -232,4 +232,7 @@ return { { 'echo_opts', { "verbose"; }}; + { 'exec_opts', { + "output"; + }}; } diff --git a/src/nvim/api/vimscript.c b/src/nvim/api/vimscript.c index 32dcbdec3f..2438a5cf1d 100644 --- a/src/nvim/api/vimscript.c +++ b/src/nvim/api/vimscript.c @@ -45,13 +45,33 @@ /// @see |nvim_cmd()| /// /// @param src Vimscript code -/// @param output Capture and return all (non-error, non-shell |:!|) output +/// @param opts Optional parameters. +/// - output: (boolean, default false) Whether to capture and return +/// all (non-error, non-shell |:!|) output. /// @param[out] err Error details (Vim error), if any -/// @return Output (non-error, non-shell |:!|) if `output` is true, -/// else empty string. -String nvim_exec(uint64_t channel_id, String src, Boolean output, Error *err) - FUNC_API_SINCE(7) +/// @return Dictionary containing information about execution, with these keys: +/// - output: (string|nil) Output if `opts.output` is true. +Dictionary nvim_exec2(uint64_t channel_id, String src, Dict(exec_opts) *opts, Error *err) + FUNC_API_SINCE(11) { + Dictionary result = ARRAY_DICT_INIT; + + String output = exec_impl(channel_id, src, opts, err); + if (ERROR_SET(err)) { + return result; + } + + if (HAS_KEY(opts->output) && api_object_to_bool(opts->output, "opts.output", false, err)) { + PUT(result, "output", STRING_OBJ(output)); + } + + return result; +} + +String exec_impl(uint64_t channel_id, String src, Dict(exec_opts) *opts, Error *err) +{ + Boolean output = api_object_to_bool(opts->output, "opts.output", false, err); + const int save_msg_silent = msg_silent; garray_T *const save_capture_ga = capture_ga; const int save_msg_col = msg_col; @@ -69,7 +89,7 @@ String nvim_exec(uint64_t channel_id, String src, Boolean output, Error *err) const sctx_T save_current_sctx = api_set_sctx(channel_id); - do_source_str(src.data, "nvim_exec()"); + do_source_str(src.data, "nvim_exec2()"); if (output) { capture_ga = save_capture_ga; msg_silent = save_msg_silent; @@ -108,8 +128,8 @@ theend: /// /// On execution error: fails with VimL error, updates v:errmsg. /// -/// Prefer using |nvim_cmd()| or |nvim_exec()| over this. To evaluate multiple lines of Vim script -/// or an Ex command directly, use |nvim_exec()|. To construct an Ex command using a structured +/// Prefer using |nvim_cmd()| or |nvim_exec2()| over this. To evaluate multiple lines of Vim script +/// or an Ex command directly, use |nvim_exec2()|. To construct an Ex command using a structured /// format and then execute it, use |nvim_cmd()|. To modify an Ex command before evaluating it, use /// |nvim_parse_cmd()| in conjunction with |nvim_cmd()|. /// diff --git a/src/nvim/context.c b/src/nvim/context.c index 9de6c16536..b13a331eff 100644 --- a/src/nvim/context.c +++ b/src/nvim/context.c @@ -10,6 +10,7 @@ #include <string.h> #include "nvim/api/private/converter.h" +#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/api/vimscript.h" #include "nvim/context.h" @@ -271,8 +272,10 @@ static inline void ctx_save_funcs(Context *ctx, bool scriptonly) size_t cmd_len = sizeof("func! ") + strlen(name); char *cmd = xmalloc(cmd_len); snprintf(cmd, cmd_len, "func! %s", name); - String func_body = nvim_exec(VIML_INTERNAL_CALL, cstr_as_string(cmd), - true, &err); + Dict(exec_opts) opts = { 0 }; + opts.output = BOOLEAN_OBJ(true); + String func_body = exec_impl(VIML_INTERNAL_CALL, cstr_as_string(cmd), + &opts, &err); xfree(cmd); if (!ERROR_SET(&err)) { ADD(ctx->funcs, STRING_OBJ(func_body)); diff --git a/test/deprecated.lua b/test/deprecated.lua index b162c8fc93..e30dfcf3ab 100644 --- a/test/deprecated.lua +++ b/test/deprecated.lua @@ -3,7 +3,7 @@ local M = {} function M.redir_exec() - error('redir_exec is deprecated, use nvim_exec() or pcall_err()') + error('redir_exec is deprecated, use nvim_exec2() or pcall_err()') end return M diff --git a/test/functional/api/extmark_spec.lua b/test/functional/api/extmark_spec.lua index 30e75b8061..e9a175625b 100644 --- a/test/functional/api/extmark_spec.lua +++ b/test/functional/api/extmark_spec.lua @@ -1413,12 +1413,12 @@ describe('API/extmarks', function() end) it('does not crash with append/delete/undo sequence', function() - meths.exec([[ + meths.exec2([[ let ns = nvim_create_namespace('myplugin') call nvim_buf_set_extmark(0, ns, 0, 0, {}) call append(0, '') %delete - undo]],false) + undo]], { output = false }) assert_alive() end) @@ -1450,7 +1450,7 @@ describe('API/extmarks', function() feed('u') -- handles pasting - meths.exec([[let @a='asdfasdf']], false) + meths.exec2([[let @a='asdfasdf']], { output = false }) feed([["ap]]) eq({ {1, 0, 0}, {2, 0, 8} }, meths.buf_get_extmarks(0, ns, 0, -1, {})) diff --git a/test/functional/api/keymap_spec.lua b/test/functional/api/keymap_spec.lua index 5be4425162..78281be195 100644 --- a/test/functional/api/keymap_spec.lua +++ b/test/functional/api/keymap_spec.lua @@ -681,13 +681,13 @@ describe('nvim_set_keymap, nvim_del_keymap', function() end) it('can set <expr> mappings whose RHS change dynamically', function() - meths.exec([[ + meths.exec2([[ function! FlipFlop() abort if !exists('g:flip') | let g:flip = 0 | endif let g:flip = !g:flip return g:flip endfunction - ]], true) + ]], { output = false }) eq(1, meths.call_function('FlipFlop', {})) eq(0, meths.call_function('FlipFlop', {})) eq(1, meths.call_function('FlipFlop', {})) @@ -827,8 +827,12 @@ describe('nvim_set_keymap, nvim_del_keymap', function() exec_lua [[ vim.api.nvim_set_keymap ('n', 'asdf', '', {callback = function() print('jkl;') end }) ]] - assert.truthy(string.match(exec_lua[[return vim.api.nvim_exec(':nmap asdf', true)]], - "^\nn asdf <Lua %d+>")) + assert.truthy( + string.match( + exec_lua[[return vim.api.nvim_exec2(':nmap asdf', { output = true }).output]], + "^\nn asdf <Lua %d+>" + ) + ) end) it ('mapcheck() returns lua mapping correctly', function() diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index ff1bfef591..162735dbd7 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -89,132 +89,145 @@ describe('API', function() eq({mode='i', blocking=false}, nvim("get_mode")) end) - describe('nvim_exec', function() + describe('nvim_exec2', function() + it('always returns table', function() + -- In built version this results into `vim.empty_dict()` + eq({}, nvim('exec2', 'echo "Hello"', {})) + eq({}, nvim('exec2', 'echo "Hello"', { output = false })) + eq({ output = 'Hello' }, nvim('exec2', 'echo "Hello"', { output = true })) + end) + + it('default options', function() + -- Should be equivalent to { output = false } + nvim('exec2', "let x0 = 'a'", {}) + eq('a', nvim('get_var', 'x0')) + end) + it('one-line input', function() - nvim('exec', "let x1 = 'a'", false) + nvim('exec2', "let x1 = 'a'", { output = false }) eq('a', nvim('get_var', 'x1')) end) it(':verbose set {option}?', function() - nvim('exec', 'set nowrap', false) - eq('nowrap\n\tLast set from anonymous :source', - nvim('exec', 'verbose set wrap?', true)) + nvim('exec2', 'set nowrap', { output = false }) + eq({ output = 'nowrap\n\tLast set from anonymous :source' }, + nvim('exec2', 'verbose set wrap?', { output = true })) -- Using script var to force creation of a script item - nvim('exec', [[ + nvim('exec2', [[ let s:a = 1 set nowrap - ]], false) - eq('nowrap\n\tLast set from anonymous :source (script id 1)', - nvim('exec', 'verbose set wrap?', true)) + ]], { output = false }) + eq({ output = 'nowrap\n\tLast set from anonymous :source (script id 1)' }, + nvim('exec2', 'verbose set wrap?', { output = true })) end) it('multiline input', function() -- Heredoc + empty lines. - nvim('exec', "let x2 = 'a'\n", false) + nvim('exec2', "let x2 = 'a'\n", { output = false }) eq('a', nvim('get_var', 'x2')) - nvim('exec','lua <<EOF\n\n\n\ny=3\n\n\nEOF', false) + nvim('exec2','lua <<EOF\n\n\n\ny=3\n\n\nEOF', { output = false }) eq(3, nvim('eval', "luaeval('y')")) - eq('', nvim('exec', 'lua <<EOF\ny=3\nEOF', false)) + eq({}, nvim('exec2', 'lua <<EOF\ny=3\nEOF', { output = false })) eq(3, nvim('eval', "luaeval('y')")) -- Multiple statements - nvim('exec', 'let x1=1\nlet x2=2\nlet x3=3\n', false) + nvim('exec2', 'let x1=1\nlet x2=2\nlet x3=3\n', { output = false }) eq(1, nvim('eval', 'x1')) eq(2, nvim('eval', 'x2')) eq(3, nvim('eval', 'x3')) -- Functions - nvim('exec', 'function Foo()\ncall setline(1,["xxx"])\nendfunction', false) + nvim('exec2', 'function Foo()\ncall setline(1,["xxx"])\nendfunction', { output = false }) eq('', nvim('get_current_line')) - nvim('exec', 'call Foo()', false) + nvim('exec2', 'call Foo()', { output = false }) eq('xxx', nvim('get_current_line')) -- Autocmds - nvim('exec','autocmd BufAdd * :let x1 = "Hello"', false) + nvim('exec2','autocmd BufAdd * :let x1 = "Hello"', { output = false }) nvim('command', 'new foo') eq('Hello', request('nvim_eval', 'g:x1')) -- Line continuations - nvim('exec', [[ + nvim('exec2', [[ let abc = #{ \ a: 1, "\ b: 2, \ c: 3 - \ }]], false) + \ }]], { output = false }) eq({a = 1, c = 3}, request('nvim_eval', 'g:abc')) -- try no spaces before continuations to catch off-by-one error - nvim('exec', 'let ab = #{\n\\a: 98,\n"\\ b: 2\n\\}', false) + nvim('exec2', 'let ab = #{\n\\a: 98,\n"\\ b: 2\n\\}', { output = false }) eq({a = 98}, request('nvim_eval', 'g:ab')) -- Script scope (s:) - eq('ahoy! script-scoped varrrrr', nvim('exec', [[ + eq({ output = 'ahoy! script-scoped varrrrr' }, nvim('exec2', [[ let s:pirate = 'script-scoped varrrrr' function! s:avast_ye_hades(s) abort return a:s .. ' ' .. s:pirate endfunction echo <sid>avast_ye_hades('ahoy!') - ]], true)) + ]], { output = true })) - eq('ahoy! script-scoped varrrrr', nvim('exec', [[ + eq({ output = "{'output': 'ahoy! script-scoped varrrrr'}" }, nvim('exec2', [[ let s:pirate = 'script-scoped varrrrr' function! Avast_ye_hades(s) abort return a:s .. ' ' .. s:pirate endfunction - echo nvim_exec('echo Avast_ye_hades(''ahoy!'')', 1) - ]], true)) + echo nvim_exec2('echo Avast_ye_hades(''ahoy!'')', {'output': v:true}) + ]], { output = true })) matches('Vim%(echo%):E121: Undefined variable: s:pirate$', - pcall_err(request, 'nvim_exec', [[ + pcall_err(request, 'nvim_exec2', [[ let s:pirate = 'script-scoped varrrrr' - call nvim_exec('echo s:pirate', 1) - ]], false)) + call nvim_exec2('echo s:pirate', {'output': v:true}) + ]], { output = false })) -- Script items are created only on script var access - eq('1\n0', nvim('exec', [[ + eq({ output = '1\n0' }, nvim('exec2', [[ echo expand("<SID>")->empty() let s:a = 123 echo expand("<SID>")->empty() - ]], true)) + ]], { output = true })) - eq('1\n0', nvim('exec', [[ + eq({ output = '1\n0' }, nvim('exec2', [[ echo expand("<SID>")->empty() function s:a() abort endfunction echo expand("<SID>")->empty() - ]], true)) + ]], { output = true })) end) it('non-ASCII input', function() - nvim('exec', [=[ + nvim('exec2', [=[ new exe "normal! i ax \n Ax " :%s/ax/--a1234--/g | :%s/Ax/--A1234--/g - ]=], false) + ]=], { output = false }) nvim('command', '1') eq(' --a1234-- ', nvim('get_current_line')) nvim('command', '2') eq(' --A1234-- ', nvim('get_current_line')) - nvim('exec', [[ + nvim('exec2', [[ new call setline(1,['xxx']) call feedkeys('r') call feedkeys('ñ', 'xt') - ]], false) + ]], { output = false }) eq('ñxx', nvim('get_current_line')) end) it('execution error', function() - eq('nvim_exec(): Vim:E492: Not an editor command: bogus_command', - pcall_err(request, 'nvim_exec', 'bogus_command', false)) + eq('nvim_exec2(): Vim:E492: Not an editor command: bogus_command', + pcall_err(request, 'nvim_exec2', 'bogus_command', {})) eq('', nvim('eval', 'v:errmsg')) -- v:errmsg was not updated. eq('', eval('v:exception')) - eq('nvim_exec(): Vim(buffer):E86: Buffer 23487 does not exist', - pcall_err(request, 'nvim_exec', 'buffer 23487', false)) + eq('nvim_exec2(): Vim(buffer):E86: Buffer 23487 does not exist', + pcall_err(request, 'nvim_exec2', 'buffer 23487', {})) eq('', eval('v:errmsg')) -- v:errmsg was not updated. eq('', eval('v:exception')) end) @@ -222,17 +235,17 @@ describe('API', function() it('recursion', function() local fname = tmpname() write_file(fname, 'let x1 = "set from :source file"\n') - -- nvim_exec + -- nvim_exec2 -- :source - -- nvim_exec - request('nvim_exec', [[ + -- nvim_exec2 + request('nvim_exec2', [[ let x2 = substitute('foo','o','X','g') let x4 = 'should be overwritten' - call nvim_exec("source ]]..fname..[[\nlet x3 = substitute('foo','foo','set by recursive nvim_exec','g')\nlet x5='overwritten'\nlet x4=x5\n", v:false) - ]], false) + call nvim_exec2("source ]]..fname..[[\nlet x3 = substitute('foo','foo','set by recursive nvim_exec2','g')\nlet x5='overwritten'\nlet x4=x5\n", {'output': v:false}) + ]], { output = false }) eq('set from :source file', request('nvim_get_var', 'x1')) eq('fXX', request('nvim_get_var', 'x2')) - eq('set by recursive nvim_exec', request('nvim_get_var', 'x3')) + eq('set by recursive nvim_exec2', request('nvim_get_var', 'x3')) eq('overwritten', request('nvim_get_var', 'x4')) eq('overwritten', request('nvim_get_var', 'x5')) os.remove(fname) @@ -242,35 +255,35 @@ describe('API', function() local fname = tmpname() write_file(fname, 'echo "hello"\n') local sourcing_fname = tmpname() - write_file(sourcing_fname, 'call nvim_exec("source '..fname..'", v:false)\n') - meths.exec('set verbose=2', false) + write_file(sourcing_fname, 'call nvim_exec2("source '..fname..'", {"output": v:false})\n') + meths.exec2('set verbose=2', { output = false }) local traceback_output = 'line 0: sourcing "'..sourcing_fname..'"\n'.. 'line 0: sourcing "'..fname..'"\n'.. 'hello\n'.. 'finished sourcing '..fname..'\n'.. - 'continuing in nvim_exec() called at '..sourcing_fname..':1\n'.. + 'continuing in nvim_exec2() called at '..sourcing_fname..':1\n'.. 'finished sourcing '..sourcing_fname..'\n'.. - 'continuing in nvim_exec() called at nvim_exec():0' - eq(traceback_output, - meths.exec('call nvim_exec("source '..sourcing_fname..'", v:false)', true)) + 'continuing in nvim_exec2() called at nvim_exec2():0' + eq({ output = traceback_output }, + meths.exec2('call nvim_exec2("source '..sourcing_fname..'", {"output": v:false})', { output = true })) os.remove(fname) os.remove(sourcing_fname) end) it('returns output', function() - eq('this is spinal tap', - nvim('exec', 'lua <<EOF\n\n\nprint("this is spinal tap")\n\n\nEOF', true)) - eq('', nvim('exec', 'echo', true)) - eq('foo 42', nvim('exec', 'echo "foo" 42', true)) + eq({ output = 'this is spinal tap' }, + nvim('exec2', 'lua <<EOF\n\n\nprint("this is spinal tap")\n\n\nEOF', { output = true })) + eq({ output = '' }, nvim('exec2', 'echo', { output = true })) + eq({ output = 'foo 42' }, nvim('exec2', 'echo "foo" 42', { output = true })) end) - it('displays messages when output=false', function() + it('displays messages when opts.output=false', function() local screen = Screen.new(40, 8) screen:attach() screen:set_default_attr_ids({ [0] = {bold=true, foreground=Screen.colors.Blue}, }) - meths.exec("echo 'hello'", false) + meths.exec2("echo 'hello'", { output = false }) screen:expect{grid=[[ ^ | {0:~ }| @@ -289,7 +302,7 @@ describe('API', function() screen:set_default_attr_ids({ [0] = {bold=true, foreground=Screen.colors.Blue}, }) - meths.exec("echo 'hello'", true) + meths.exec2("echo 'hello'", { output = true }) screen:expect{grid=[[ ^ | {0:~ }| @@ -300,7 +313,7 @@ describe('API', function() ]]} exec([[ func Print() - call nvim_exec('echo "hello"', v:true) + call nvim_exec2('echo "hello"', { 'output': v:true }) endfunc ]]) feed([[:echon 1 | call Print() | echon 5<CR>]]) @@ -575,7 +588,7 @@ describe('API', function() it('sets previous directory', function() meths.set_current_dir("Xtestdir") - meths.exec('cd -', false) + meths.exec2('cd -', { output = false }) eq(funcs.getcwd(), start_dir) end) end) @@ -2674,7 +2687,7 @@ describe('API', function() eq(' 1 %a "[No Name]" line 1\n'.. ' 3 h "[Scratch]" line 0\n'.. ' 4 h "[Scratch]" line 0', - meths.exec('ls', true)) + meths.exec2('ls', { output = true }).output) -- current buffer didn't change eq({id=1}, meths.get_current_buf()) @@ -2788,7 +2801,7 @@ describe('API', function() end) it('should not crash when echoed', function() - meths.exec("echo nvim_get_all_options_info()", true) + meths.exec2("echo nvim_get_all_options_info()", { output = true }) end) end) @@ -2941,13 +2954,13 @@ describe('API', function() it('can save message history', function() nvim('command', 'set cmdheight=2') -- suppress Press ENTER nvim("echo", {{"msg\nmsg"}, {"msg"}}, true, {}) - eq("msg\nmsgmsg", meths.exec('messages', true)) + eq("msg\nmsgmsg", meths.exec2('messages', { output = true }).output) end) it('can disable saving message history', function() nvim('command', 'set cmdheight=2') -- suppress Press ENTER nvim_async("echo", {{"msg\nmsg"}, {"msg"}}, false, {}) - eq("", meths.exec("messages", true)) + eq("", meths.exec2("messages", { output = true }).output) end) end) @@ -3936,7 +3949,7 @@ describe('API', function() it('sets correct script context', function() meths.cmd({ cmd = "set", args = { "cursorline" } }, {}) - local str = meths.exec([[verbose set cursorline?]], true) + local str = meths.exec2([[verbose set cursorline?]], { output = true }).output neq(nil, str:find("cursorline\n\tLast set from API client %(channel id %d+%)")) end) @@ -3986,7 +3999,7 @@ describe('API', function() line6 ]] meths.cmd({ cmd = "del", range = { 2, 4 }, reg = 'a' }, {}) - meths.exec("1put a", false) + meths.exec2("1put a", { output = false }) expect [[ line1 line2 @@ -4051,11 +4064,11 @@ describe('API', function() { output = true })) end) it('splits arguments correctly', function() - meths.exec([[ + meths.exec2([[ function! FooFunc(...) echo a:000 endfunction - ]], false) + ]], { output = false }) meths.create_user_command("Foo", "call FooFunc(<f-args>)", { nargs = '+' }) eq([=[['a quick', 'brown fox', 'jumps over the', 'lazy dog']]=], meths.cmd({ cmd = "Foo", args = { "a quick", "brown fox", "jumps over the", "lazy dog"}}, diff --git a/test/functional/autocmd/autocmd_oldtest_spec.lua b/test/functional/autocmd/autocmd_oldtest_spec.lua index ad3687d7b0..7d475e5015 100644 --- a/test/functional/autocmd/autocmd_oldtest_spec.lua +++ b/test/functional/autocmd/autocmd_oldtest_spec.lua @@ -6,7 +6,7 @@ local meths = helpers.meths local funcs = helpers.funcs local exec = function(str) - meths.exec(str, false) + meths.exec2(str, { output = false }) end describe('oldtests', function() diff --git a/test/functional/core/exit_spec.lua b/test/functional/core/exit_spec.lua index dc4b45b4d9..d474b77806 100644 --- a/test/functional/core/exit_spec.lua +++ b/test/functional/core/exit_spec.lua @@ -93,14 +93,14 @@ describe(':cquit', function() end) it('exits with redir msg for multiple exit codes after :cquit 1 2', function() - test_cq('cquit 1 2', nil, 'nvim_exec(): Vim(cquit):E488: Trailing characters: 2: cquit 1 2') + test_cq('cquit 1 2', nil, 'nvim_exec2(): Vim(cquit):E488: Trailing characters: 2: cquit 1 2') end) it('exits with redir msg for non-number exit code after :cquit X', function() - test_cq('cquit X', nil, 'nvim_exec(): Vim(cquit):E488: Trailing characters: X: cquit X') + test_cq('cquit X', nil, 'nvim_exec2(): Vim(cquit):E488: Trailing characters: X: cquit X') end) it('exits with redir msg for negative exit code after :cquit -1', function() - test_cq('cquit -1', nil, 'nvim_exec(): Vim(cquit):E488: Trailing characters: -1: cquit -1') + test_cq('cquit -1', nil, 'nvim_exec2(): Vim(cquit):E488: Trailing characters: -1: cquit -1') end) end) diff --git a/test/functional/core/remote_spec.lua b/test/functional/core/remote_spec.lua index 846d79abf3..b2a1679023 100644 --- a/test/functional/core/remote_spec.lua +++ b/test/functional/core/remote_spec.lua @@ -101,7 +101,7 @@ describe('Remote', function() expect(contents) eq(1, #funcs.getbufinfo()) -- Since we didn't pass silent, we should get a complaint - neq(nil, string.find(meths.exec('messages', true), 'E247')) + neq(nil, string.find(meths.exec2('messages', { output = true }).output, 'E247')) end) it('creates server if not found with tabs', function() @@ -110,7 +110,7 @@ describe('Remote', function() eq(2, #funcs.gettabinfo()) eq(2, #funcs.getbufinfo()) -- We passed silent, so no message should be issued about the server not being found - eq(nil, string.find(meths.exec('messages', true), 'E247')) + eq(nil, string.find(meths.exec2('messages', { output = true }).output, 'E247')) end) pending('exits with error on', function() diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua index e9b47a0251..4ae8b1c95e 100644 --- a/test/functional/core/startup_spec.lua +++ b/test/functional/core/startup_spec.lua @@ -58,7 +58,7 @@ describe('startup', function() ^ | | Entering Debug mode. Type "cont" to continue. | - nvim_exec() | + nvim_exec2() | cmd: aunmenu * | > | | @@ -691,7 +691,6 @@ describe('sysinit', function() eq('loaded 1 xdg 0 vim 1', eval('printf("loaded %d xdg %d vim %d", g:loaded, get(g:, "xdg", 0), get(g:, "vim", 0))')) end) - end) describe('user config init', function() @@ -824,7 +823,7 @@ describe('user config init', function() clear{ args_rm={'-u'}, env=xenv } feed('<cr><c-c>') -- Dismiss "Conflicting config …" message. eq(1, eval('g:lua_rc')) - matches('^E5422: Conflicting configs', meths.exec('messages', true)) + matches('^E5422: Conflicting configs', meths.exec2('messages', { output = true }).output) end) end) end) @@ -873,7 +872,7 @@ describe('runtime:', function() eq(2, eval('g:lua_plugin')) -- Check if plugin_file_path is listed in :scriptname - local scripts = meths.exec(':scriptnames', true) + local scripts = meths.exec2(':scriptnames', { output = true }).output assert(scripts:find(plugin_file_path)) -- Check if plugin_file_path is listed in startup profile diff --git a/test/functional/editor/mark_spec.lua b/test/functional/editor/mark_spec.lua index 0670176719..365f8527a0 100644 --- a/test/functional/editor/mark_spec.lua +++ b/test/functional/editor/mark_spec.lua @@ -40,59 +40,59 @@ describe('named marks', function() it("errors when set out of range with :mark", function() command("edit " .. file1) local err = pcall_err(helpers.exec_capture, "1000mark x") - eq("nvim_exec(): Vim(mark):E16: Invalid range: 1000mark x", err) + eq("nvim_exec2(): Vim(mark):E16: Invalid range: 1000mark x", err) end) it("errors when set out of range with :k", function() command("edit " .. file1) local err = pcall_err(helpers.exec_capture, "1000kx") - eq("nvim_exec(): Vim(k):E16: Invalid range: 1000kx", err) + eq("nvim_exec2(): Vim(k):E16: Invalid range: 1000kx", err) end) it("errors on unknown mark name with :mark", function() command("edit " .. file1) local err = pcall_err(helpers.exec_capture, "mark #") - eq("nvim_exec(): Vim(mark):E191: Argument must be a letter or forward/backward quote", err) + eq("nvim_exec2(): Vim(mark):E191: Argument must be a letter or forward/backward quote", err) end) it("errors on unknown mark name with '", function() command("edit " .. file1) local err = pcall_err(helpers.exec_capture, "normal! '#") - eq("nvim_exec(): Vim(normal):E78: Unknown mark", err) + eq("nvim_exec2(): Vim(normal):E78: Unknown mark", err) end) it("errors on unknown mark name with `", function() command("edit " .. file1) local err = pcall_err(helpers.exec_capture, "normal! `#") - eq("nvim_exec(): Vim(normal):E78: Unknown mark", err) + eq("nvim_exec2(): Vim(normal):E78: Unknown mark", err) end) it("errors when moving to a mark that is not set with '", function() command("edit " .. file1) local err = pcall_err(helpers.exec_capture, "normal! 'z") - eq("nvim_exec(): Vim(normal):E20: Mark not set", err) + eq("nvim_exec2(): Vim(normal):E20: Mark not set", err) err = pcall_err(helpers.exec_capture, "normal! '.") - eq("nvim_exec(): Vim(normal):E20: Mark not set", err) + eq("nvim_exec2(): Vim(normal):E20: Mark not set", err) end) it("errors when moving to a mark that is not set with `", function() command("edit " .. file1) local err = pcall_err(helpers.exec_capture, "normal! `z") - eq("nvim_exec(): Vim(normal):E20: Mark not set", err) + eq("nvim_exec2(): Vim(normal):E20: Mark not set", err) err = pcall_err(helpers.exec_capture, "normal! `>") - eq("nvim_exec(): Vim(normal):E20: Mark not set", err) + eq("nvim_exec2(): Vim(normal):E20: Mark not set", err) end) it("errors when moving to a global mark that is not set with '", function() command("edit " .. file1) local err = pcall_err(helpers.exec_capture, "normal! 'Z") - eq("nvim_exec(): Vim(normal):E20: Mark not set", err) + eq("nvim_exec2(): Vim(normal):E20: Mark not set", err) end) it("errors when moving to a global mark that is not set with `", function() command("edit " .. file1) local err = pcall_err(helpers.exec_capture, "normal! `Z") - eq("nvim_exec(): Vim(normal):E20: Mark not set", err) + eq("nvim_exec2(): Vim(normal):E20: Mark not set", err) end) it("can move to them using '", function() @@ -153,7 +153,7 @@ describe('named marks', function() command("next") command("bw! " .. file1 ) local err = pcall_err(helpers.exec_capture, "normal! 'A") - eq("nvim_exec(): Vim(normal):E92: Buffer 1 not found", err) + eq("nvim_exec2(): Vim(normal):E92: Buffer 1 not found", err) os.remove(file1) end) diff --git a/test/functional/ex_cmds/script_spec.lua b/test/functional/ex_cmds/script_spec.lua index bf69ada820..d13268c97c 100644 --- a/test/functional/ex_cmds/script_spec.lua +++ b/test/functional/ex_cmds/script_spec.lua @@ -34,7 +34,7 @@ describe('script_get-based command', function() %s %s endif ]])):format(cmd, garbage))) - eq('', meths.exec('messages', true)) + eq('', meths.exec2('messages', { output = true }).output) if check_neq then neq(0, exc_exec(dedent([[ %s %s @@ -49,7 +49,7 @@ describe('script_get-based command', function() EOF endif ]])):format(cmd, garbage))) - eq('', meths.exec('messages', true)) + eq('', meths.exec2('messages', { output = true }).output) if check_neq then eq(true, pcall(source, (dedent([[ let g:exc = 0 diff --git a/test/functional/ex_cmds/source_spec.lua b/test/functional/ex_cmds/source_spec.lua index 64c3464be7..e12ead240d 100644 --- a/test/functional/ex_cmds/source_spec.lua +++ b/test/functional/ex_cmds/source_spec.lua @@ -96,12 +96,12 @@ describe(':source', function() let d = s:s]]) command('source') - eq('2', meths.exec('echo a', true)) - eq("{'k': 'v'}", meths.exec('echo b', true)) + eq('2', meths.exec2('echo a', { output = true }).output) + eq("{'k': 'v'}", meths.exec2('echo b', { output = true }).output) -- Script items are created only on script var access - eq("1", meths.exec('echo c', true)) - eq("0zBEEFCAFE", meths.exec('echo d', true)) + eq("1", meths.exec2('echo c', { output = true }).output) + eq("0zBEEFCAFE", meths.exec2('echo d', { output = true }).output) exec('set cpoptions+=C') eq('Vim(let):E723: Missing end of Dictionary \'}\': ', exc_exec('source')) @@ -124,14 +124,14 @@ describe(':source', function() -- Source the 2nd line only feed('ggjV') feed_command(':source') - eq('3', meths.exec('echo a', true)) + eq('3', meths.exec2('echo a', { output = true }).output) -- Source from 2nd line to end of file feed('ggjVG') feed_command(':source') - eq('4', meths.exec('echo a', true)) - eq("{'K': 'V'}", meths.exec('echo b', true)) - eq("<SNR>1_C()", meths.exec('echo D()', true)) + eq('4', meths.exec2('echo a', { output = true }).output) + eq("{'K': 'V'}", meths.exec2('echo b', { output = true }).output) + eq("<SNR>1_C()", meths.exec2('echo D()', { output = true }).output) -- Source last line only feed_command(':$source') @@ -147,7 +147,7 @@ describe(':source', function() let a = 123 ]] command('source') - eq('123', meths.exec('echo a', true)) + eq('123', meths.exec2('echo a', { output = true }).output) end) it('multiline heredoc command', function() @@ -157,7 +157,7 @@ describe(':source', function() EOF]]) command('source') - eq('4', meths.exec('echo luaeval("y")', true)) + eq('4', meths.exec2('echo luaeval("y")', { output = true }).output) end) it('can source lua files', function() diff --git a/test/functional/ex_cmds/verbose_spec.lua b/test/functional/ex_cmds/verbose_spec.lua index e55372e993..2482fd912f 100644 --- a/test/functional/ex_cmds/verbose_spec.lua +++ b/test/functional/ex_cmds/verbose_spec.lua @@ -24,11 +24,11 @@ vim.opt.number = true vim.api.nvim_set_keymap('n', '<leader>key1', ':echo "test"<cr>', {noremap = true}) vim.keymap.set('n', '<leader>key2', ':echo "test"<cr>') -vim.api.nvim_exec("augroup test_group\ +vim.api.nvim_exec2("augroup test_group\ autocmd!\ autocmd FileType c setl cindent\ augroup END\ - ", false) + ", { output = false }) vim.api.nvim_command("command Bdelete :bd") vim.api.nvim_create_user_command("TestCommand", ":echo 'Hello'", {}) diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua index b485352c94..de5fe96934 100644 --- a/test/functional/helpers.lua +++ b/test/functional/helpers.lua @@ -533,7 +533,7 @@ function module.feed_command(...) end end --- @deprecated use nvim_exec() +-- @deprecated use nvim_exec2() function module.source(code) module.exec(dedent(code)) end @@ -826,11 +826,11 @@ function module.skip_fragile(pending_fn, cond) end function module.exec(code) - return module.meths.exec(code, false) + module.meths.exec2(code, { output = false }) end function module.exec_capture(code) - return module.meths.exec(code, true) + return module.meths.exec2(code, { output = true }).output end function module.exec_lua(code, ...) diff --git a/test/functional/legacy/assert_spec.lua b/test/functional/legacy/assert_spec.lua index 4829a0bbe1..d49d7d665a 100644 --- a/test/functional/legacy/assert_spec.lua +++ b/test/functional/legacy/assert_spec.lua @@ -145,10 +145,10 @@ describe('assert function:', function() call assert_true('', 'file two') ]]) expected_errors({ - "nvim_exec(): equal assertion failed: Expected 1 but got 100", - "nvim_exec(): true assertion failed: Expected False but got 'true'", - "nvim_exec(): false assertion failed: Expected True but got 'false'", - "nvim_exec(): file two: Expected True but got ''", + "nvim_exec2(): equal assertion failed: Expected 1 but got 100", + "nvim_exec2(): true assertion failed: Expected False but got 'true'", + "nvim_exec2(): false assertion failed: Expected True but got 'false'", + "nvim_exec2(): file two: Expected True but got ''", }) end) end) diff --git a/test/functional/options/keymap_spec.lua b/test/functional/options/keymap_spec.lua index 4fdc6ef4be..7ff86438b2 100644 --- a/test/functional/options/keymap_spec.lua +++ b/test/functional/options/keymap_spec.lua @@ -30,7 +30,7 @@ describe("'keymap' / :lmap", function() command('lmapclear <buffer>') command('set keymap=dvorak') command('set nomore') - local bindings = funcs.nvim_exec('lmap', true) + local bindings = funcs.nvim_exec2('lmap', { output = true }).output eq(dedent([[ l " @_ diff --git a/test/functional/ui/cmdline_highlight_spec.lua b/test/functional/ui/cmdline_highlight_spec.lua index eb5de693bd..d6c8408f04 100644 --- a/test/functional/ui/cmdline_highlight_spec.lua +++ b/test/functional/ui/cmdline_highlight_spec.lua @@ -362,7 +362,7 @@ describe('Command-line coloring', function() {EOB:~ }| :e^ | ]]) - eq('', meths.exec('messages', true)) + eq('', meths.exec2('messages', { output = true }).output) end) it('silences :echon', function() set_color_cb('Echoning') @@ -377,7 +377,7 @@ describe('Command-line coloring', function() {EOB:~ }| :e^ | ]]) - eq('', meths.exec('messages', true)) + eq('', meths.exec2('messages', { output = true }).output) end) it('silences :echomsg', function() set_color_cb('Echomsging') @@ -392,7 +392,7 @@ describe('Command-line coloring', function() {EOB:~ }| :e^ | ]]) - eq('', meths.exec('messages', true)) + eq('', meths.exec2('messages', { output = true }).output) end) it('does the right thing when throwing', function() set_color_cb('Throwing') @@ -858,7 +858,7 @@ describe('Ex commands coloring', function() ]]) feed('<CR>') eq('Error detected while processing :\nE605: Exception not caught: 42\nE749: empty buffer', - meths.exec('messages', true)) + meths.exec2('messages', { output = true }).output) end) it('errors out when failing to get callback', function() meths.set_var('Nvim_color_cmdline', 42) diff --git a/test/functional/ui/messages_spec.lua b/test/functional/ui/messages_spec.lua index a92b55ae5d..81602ef92e 100644 --- a/test/functional/ui/messages_spec.lua +++ b/test/functional/ui/messages_spec.lua @@ -986,7 +986,7 @@ describe('ui/builtin messages', function() -- screen size doesn't affect internal output #10285 eq('ErrorMsg xxx ctermfg=15 ctermbg=1 guifg=White guibg=Red', - meths.exec("hi ErrorMsg", true)) + meths.exec2("hi ErrorMsg", { output = true }).output) end) it(':syntax list langGroup output', function() @@ -1025,7 +1025,7 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim match /\<endif\s\+".*$/ms=s+5,lc=5 contains=@vimCommentGroup,vimCommentString match /\<else\s\+".*$/ms=s+4,lc=4 contains=@vimCommentGroup,vimCommentString links to Comment]], - meths.exec('syntax list vimComment', true)) + meths.exec2('syntax list vimComment', { output = true }).output) -- luacheck: pop end) |