API: rename nvim_source => nvim_exec

- Eliminate nvim_source_output(): add boolean `output` param to
  nvim_exec() instead.
This commit is contained in:
Justin M. Keyes
2019-12-01 22:26:36 -08:00
parent bd43e011b5
commit b1991f66d5
4 changed files with 72 additions and 74 deletions

View File

@@ -73,28 +73,29 @@ void api_vim_free_all_mem(void)
map_free(String, handle_T)(namespace_ids); map_free(String, handle_T)(namespace_ids);
} }
/// Executes a multiline block of ex-commands from a string. /// Executes Vimscript (multiline block of Ex-commands), like anonymous
/// |:source|.
///
/// Optionally returns (non-error, non-shell |:!|) output.
/// ///
/// On execution error: fails with VimL error, does not update v:errmsg. /// On execution error: fails with VimL error, does not update v:errmsg.
/// ///
/// @param src String containing the ex-commands /// @see |execute()|
/// @see |nvim_command()|
///
/// @param src Vimscript code
/// @param output Capture and return all (non-error, non-shell |:!|) output
/// @param[out] err Error details (Vim error), if any /// @param[out] err Error details (Vim error), if any
void nvim_source(String src, Error *err) FUNC_API_SINCE(7) String nvim_exec(String src, Boolean output, Error *err)
FUNC_API_SINCE(7)
{ {
try_start(); if (!output) {
do_source_str(src.data, "nvim_source(..)"); try_start();
try_end(err); do_source_str(src.data, "nvim_exec()");
} try_end(err);
return (String)STRING_INIT;
}
/// Executes a multiline block of ex-commands from a string and returns its
/// (non-error) output. Shell |:!| output is not captured.
///
/// On execution error: fails with VimL error, does not update v:errmsg.
///
/// @param src String containing the ex-commands
/// @param[out] err Error details (Vim error), if any
String nvim_source_output(String src, Error *err) FUNC_API_SINCE(7)
{
const int save_msg_silent = msg_silent; const int save_msg_silent = msg_silent;
garray_T *const save_capture_ga = capture_ga; garray_T *const save_capture_ga = capture_ga;
garray_T capture_local; garray_T capture_local;
@@ -103,7 +104,7 @@ String nvim_source_output(String src, Error *err) FUNC_API_SINCE(7)
try_start(); try_start();
msg_silent++; msg_silent++;
capture_ga = &capture_local; capture_ga = &capture_local;
do_source_str(src.data, "nvim_source_output(..)"); do_source_str(src.data, "nvim_exec()");
capture_ga = save_capture_ga; capture_ga = save_capture_ga;
msg_silent = save_msg_silent; msg_silent = save_msg_silent;
try_end(err); try_end(err);
@@ -134,6 +135,8 @@ theend:
/// ///
/// On execution error: fails with VimL error, does not update v:errmsg. /// On execution error: fails with VimL error, does not update v:errmsg.
/// ///
/// @see |nvim_exec()|
///
/// @param command Ex-command string /// @param command Ex-command string
/// @param[out] err Error details (Vim error), if any /// @param[out] err Error details (Vim error), if any
void nvim_command(String command, Error *err) void nvim_command(String command, Error *err)
@@ -436,7 +439,7 @@ theend:
return (String)STRING_INIT; return (String)STRING_INIT;
} }
/// Evaluates a VimL expression (:help expression). /// Evaluates a VimL |expression|.
/// Dictionaries and Lists are recursively expanded. /// Dictionaries and Lists are recursively expanded.
/// ///
/// On execution error: fails with VimL error, does not update v:errmsg. /// On execution error: fails with VimL error, does not update v:errmsg.

View File

@@ -3047,6 +3047,9 @@ static char_u *get_str_line(int c, void *cookie, int indent, bool do_concat)
return (char_u *)xstrdup(buf); return (char_u *)xstrdup(buf);
} }
/// Executes lines in `src` as Ex commands.
///
/// @see do_source()
int do_source_str(const char *cmd, const char *traceback_name) int do_source_str(const char *cmd, const char *traceback_name)
{ {
char_u *save_sourcing_name = sourcing_name; char_u *save_sourcing_name = sourcing_name;
@@ -3055,7 +3058,7 @@ int do_source_str(const char *cmd, const char *traceback_name)
if (save_sourcing_name == NULL) { if (save_sourcing_name == NULL) {
sourcing_name = (char_u *)traceback_name; sourcing_name = (char_u *)traceback_name;
} else { } else {
snprintf((char *)sourcing_name_buf, sizeof sourcing_name_buf, snprintf((char *)sourcing_name_buf, sizeof(sourcing_name_buf),
"%s called at %s:%"PRIdLINENR, traceback_name, save_sourcing_name, "%s called at %s:%"PRIdLINENR, traceback_name, save_sourcing_name,
save_sourcing_lnum); save_sourcing_lnum);
sourcing_name = sourcing_name_buf; sourcing_name = sourcing_name_buf;
@@ -3070,24 +3073,20 @@ int do_source_str(const char *cmd, const char *traceback_name)
current_sctx.sc_sid = SID_STR; current_sctx.sc_sid = SID_STR;
current_sctx.sc_seq = 0; current_sctx.sc_seq = 0;
current_sctx.sc_lnum = save_sourcing_lnum; current_sctx.sc_lnum = save_sourcing_lnum;
int retval = FAIL; int retval = do_cmdline(NULL, get_str_line, (void *)&cookie,
do_cmdline(NULL, get_str_line, (void *)&cookie, DOCMD_VERBOSE | DOCMD_NOWAIT | DOCMD_REPEAT);
DOCMD_VERBOSE | DOCMD_NOWAIT | DOCMD_REPEAT);
retval = OK;
if (got_int) {
EMSG(_(e_interr));
}
current_sctx = save_current_sctx; current_sctx = save_current_sctx;
sourcing_lnum = save_sourcing_lnum; sourcing_lnum = save_sourcing_lnum;
sourcing_name = save_sourcing_name; sourcing_name = save_sourcing_name;
return retval; return retval;
} }
/// Read the file "fname" and execute its lines as EX commands. /// Reads the file `fname` and executes its lines as Ex commands.
/// ///
/// This function may be called recursively! /// This function may be called recursively!
/// ///
/// @see do_source_str
///
/// @param fname /// @param fname
/// @param check_other check for .vimrc and _vimrc /// @param check_other check for .vimrc and _vimrc
/// @param is_vimrc DOSO_ value /// @param is_vimrc DOSO_ value

View File

@@ -421,13 +421,12 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
// If force_abort is set, we cancel everything. // If force_abort is set, we cancel everything.
did_emsg = false; did_emsg = false;
/* // KeyTyped is only set when calling vgetc(). Reset it here when not
* KeyTyped is only set when calling vgetc(). Reset it here when not // calling vgetc() (sourced command lines).
* calling vgetc() (sourced command lines).
*/
if (!(flags & DOCMD_KEYTYPED) if (!(flags & DOCMD_KEYTYPED)
&& !getline_equal(fgetline, cookie, getexline)) && !getline_equal(fgetline, cookie, getexline)) {
KeyTyped = false; KeyTyped = false;
}
/* /*
* Continue executing command lines: * Continue executing command lines:

View File

@@ -16,6 +16,7 @@ local parse_context = helpers.parse_context
local request = helpers.request local request = helpers.request
local source = helpers.source local source = helpers.source
local next_msg = helpers.next_msg local next_msg = helpers.next_msg
local tmpname = helpers.tmpname
local write_file = helpers.write_file local write_file = helpers.write_file
local pcall_err = helpers.pcall_err local pcall_err = helpers.pcall_err
@@ -75,131 +76,127 @@ describe('API', function()
eq({mode='i', blocking=false}, nvim("get_mode")) eq({mode='i', blocking=false}, nvim("get_mode"))
end) end)
describe('nvim_source', function() describe('nvim_exec', function()
it('one-line input', function() it('one-line input', function()
nvim('source', "let x1 = 'a'") nvim('exec', "let x1 = 'a'", false)
eq('a', nvim('get_var', 'x1')) eq('a', nvim('get_var', 'x1'))
end) end)
it(':verbose set {option}?', function() it(':verbose set {option}?', function()
nvim('source', 'set nowrap') nvim('exec', 'set nowrap', false)
eq('nowrap\n\tLast set from :source (no file)', eq('nowrap\n\tLast set from :source (no file)',
nvim('source_output', 'verbose set wrap?')) nvim('exec', 'verbose set wrap?', true))
end) end)
it('multiline input', function() it('multiline input', function()
-- Heredoc + empty lines. -- Heredoc + empty lines.
nvim('source', "let x2 = 'a'\n") nvim('exec', "let x2 = 'a'\n", false)
eq('a', nvim('get_var', 'x2')) eq('a', nvim('get_var', 'x2'))
nvim('source','lua <<EOF\n\n\n\ny=3\n\n\nEOF') nvim('exec','lua <<EOF\n\n\n\ny=3\n\n\nEOF', false)
eq(3, nvim('eval', "luaeval('y')")) eq(3, nvim('eval', "luaeval('y')"))
nvim('source', 'lua <<EOF\ny=3\nEOF') eq('', nvim('exec', 'lua <<EOF\ny=3\nEOF', false))
eq(3, nvim('eval', "luaeval('y')")) eq(3, nvim('eval', "luaeval('y')"))
-- Multiple statements -- Multiple statements
nvim('source', 'let x1=1\nlet x2=2\nlet x3=3\n') nvim('exec', 'let x1=1\nlet x2=2\nlet x3=3\n', false)
eq(1, nvim('eval', 'x1')) eq(1, nvim('eval', 'x1'))
eq(2, nvim('eval', 'x2')) eq(2, nvim('eval', 'x2'))
eq(3, nvim('eval', 'x3')) eq(3, nvim('eval', 'x3'))
-- Functions -- Functions
nvim('source', 'function Foo()\ncall setline(1,["xxx"])\nendfunction') nvim('exec', 'function Foo()\ncall setline(1,["xxx"])\nendfunction', false)
eq(nvim('get_current_line'), '') eq(nvim('get_current_line'), '')
nvim('source', 'call Foo()') nvim('exec', 'call Foo()', false)
eq(nvim('get_current_line'), 'xxx') eq(nvim('get_current_line'), 'xxx')
-- Autocmds -- Autocmds
nvim('source','autocmd BufAdd * :let x1 = "Hello"') nvim('exec','autocmd BufAdd * :let x1 = "Hello"', false)
nvim('command', 'new foo') nvim('command', 'new foo')
eq('Hello', request('nvim_eval', 'g:x1')) eq('Hello', request('nvim_eval', 'g:x1'))
end) end)
it('non-ASCII input', function() it('non-ASCII input', function()
nvim('source', [=[ nvim('exec', [=[
new new
exe "normal! i ax \n Ax " exe "normal! i ax \n Ax "
:%s/ax/--a1234--/g | :%s/Ax/--A1234--/g :%s/ax/--a1234--/g | :%s/Ax/--A1234--/g
]=]) ]=], false)
nvim('command', '1') nvim('command', '1')
eq(' --a1234-- ', nvim('get_current_line')) eq(' --a1234-- ', nvim('get_current_line'))
nvim('command', '2') nvim('command', '2')
eq(' --A1234-- ', nvim('get_current_line')) eq(' --A1234-- ', nvim('get_current_line'))
nvim('source', [[ nvim('exec', [[
new new
call setline(1,['xxx']) call setline(1,['xxx'])
call feedkeys('r') call feedkeys('r')
call feedkeys('ñ', 'xt') call feedkeys('ñ', 'xt')
]]) ]], false)
eq('ñxx', nvim('get_current_line')) eq('ñxx', nvim('get_current_line'))
end) end)
it('execution error', function() it('execution error', function()
eq('Vim:E492: Not an editor command: bogus_command', eq('Vim:E492: Not an editor command: bogus_command',
pcall_err(request, 'nvim_source', 'bogus_command')) pcall_err(request, 'nvim_exec', 'bogus_command', false))
eq('', nvim('eval', 'v:errmsg')) -- v:errmsg was not updated. eq('', nvim('eval', 'v:errmsg')) -- v:errmsg was not updated.
eq('', eval('v:exception')) eq('', eval('v:exception'))
eq('Vim(buffer):E86: Buffer 23487 does not exist', eq('Vim(buffer):E86: Buffer 23487 does not exist',
pcall_err(request, 'nvim_source', 'buffer 23487')) pcall_err(request, 'nvim_exec', 'buffer 23487', false))
eq('', eval('v:errmsg')) -- v:errmsg was not updated. eq('', eval('v:errmsg')) -- v:errmsg was not updated.
eq('', eval('v:exception')) eq('', eval('v:exception'))
end) end)
it('recursion', function() it('recursion', function()
local fname = helpers.tmpname() local fname = tmpname()
write_file(fname, 'let x1 = "set from :source file"\n') write_file(fname, 'let x1 = "set from :source file"\n')
-- nvim_source -- nvim_exec
-- :source -- :source
-- nvim_source -- nvim_exec
request('nvim_source', [[ request('nvim_exec', [[
let x2 = substitute('foo','o','X','g') let x2 = substitute('foo','o','X','g')
let x4 = 'should be overwritten' let x4 = 'should be overwritten'
call nvim_source("source ]]..fname..[[\nlet x3 = substitute('foo','foo','set by recursive nvim_source','g')\nlet x5='overwritten'\nlet x4=x5\n") 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)
eq('set from :source file', request('nvim_get_var', 'x1')) eq('set from :source file', request('nvim_get_var', 'x1'))
eq('fXX', request('nvim_get_var', 'x2')) eq('fXX', request('nvim_get_var', 'x2'))
eq('set by recursive nvim_source', request('nvim_get_var', 'x3')) eq('set by recursive nvim_exec', request('nvim_get_var', 'x3'))
eq('overwritten', request('nvim_get_var', 'x4')) eq('overwritten', request('nvim_get_var', 'x4'))
eq('overwritten', request('nvim_get_var', 'x5')) eq('overwritten', request('nvim_get_var', 'x5'))
os.remove(fname) os.remove(fname)
end) end)
it('traceback', function() it('traceback', function()
local fname = helpers.tmpname() local fname = tmpname()
write_file(fname, 'echo "hello"\n') write_file(fname, 'echo "hello"\n')
local sourcing_fname = helpers.tmpname() local sourcing_fname = tmpname()
write_file(sourcing_fname, 'call nvim_source("source '..fname..'")\n') write_file(sourcing_fname, 'call nvim_exec("source '..fname..'", v:false)\n')
meths.source('set verbose=2') meths.exec('set verbose=2', false)
print()
local traceback_output = 'line 0: sourcing "'..sourcing_fname..'"\n'.. local traceback_output = 'line 0: sourcing "'..sourcing_fname..'"\n'..
'line 0: sourcing "'..fname..'"\n'.. 'line 0: sourcing "'..fname..'"\n'..
'hello\n'.. 'hello\n'..
'finished sourcing '..fname..'\n'.. 'finished sourcing '..fname..'\n'..
'continuing in nvim_source(..) called at '..sourcing_fname..':1\n'.. 'continuing in nvim_exec() called at '..sourcing_fname..':1\n'..
'finished sourcing '..sourcing_fname..'\n'.. 'finished sourcing '..sourcing_fname..'\n'..
'continuing in nvim_source(..) called at nvim_source_output(..):0' 'continuing in nvim_exec() called at nvim_exec():0'
eq(traceback_output, meths.source_output('call nvim_source("source '..sourcing_fname..'")')) eq(traceback_output,
meths.exec('call nvim_exec("source '..sourcing_fname..'", v:false)', true))
os.remove(fname) os.remove(fname)
os.remove(sourcing_fname) os.remove(sourcing_fname)
end) end)
end)
describe('nvim_source_output', function() it('returns output', function()
it('multiline input', function()
eq('this is spinal tap', eq('this is spinal tap',
nvim('source_output', 'lua <<EOF\n\n\nprint("this is spinal tap")\n\n\nEOF')) nvim('exec', 'lua <<EOF\n\n\nprint("this is spinal tap")\n\n\nEOF', true))
end) eq('', nvim('exec', 'echo', true))
eq('foo 42', nvim('exec', 'echo "foo" 42', true))
it('empty output', function()
eq('', nvim('source_output', 'echo'))
end) end)
end) end)
describe('nvim_command', function() describe('nvim_command', function()
it('works', function() it('works', function()
local fname = helpers.tmpname() local fname = tmpname()
nvim('command', 'new') nvim('command', 'new')
nvim('command', 'edit '..fname) nvim('command', 'edit '..fname)
nvim('command', 'normal itesting\napi') nvim('command', 'normal itesting\napi')