API: nvim_source

This commit is contained in:
Siddhant Gupta
2019-10-06 13:37:54 -07:00
committed by Justin M. Keyes
parent 70b6061666
commit 6aa03e86da
3 changed files with 127 additions and 1 deletions

View File

@@ -25,6 +25,7 @@
#include "nvim/highlight.h" #include "nvim/highlight.h"
#include "nvim/window.h" #include "nvim/window.h"
#include "nvim/types.h" #include "nvim/types.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h" #include "nvim/ex_docmd.h"
#include "nvim/screen.h" #include "nvim/screen.h"
#include "nvim/memline.h" #include "nvim/memline.h"
@@ -72,6 +73,15 @@ void api_vim_free_all_mem(void)
map_free(String, handle_T)(namespace_ids); map_free(String, handle_T)(namespace_ids);
} }
void nvim_source(String command, Error *err)
FUNC_API_SINCE(5)
{
try_start();
do_source_str((char_u *)command.data);
update_screen(VALID);
try_end(err);
}
/// Executes an ex-command. /// Executes an ex-command.
/// ///
/// 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

@@ -1193,7 +1193,7 @@ static void script_dump_profile(FILE *fd)
/// profiled. /// profiled.
bool prof_def_func(void) bool prof_def_func(void)
{ {
if (current_sctx.sc_sid > 0) { if (current_sctx.sc_sid > 0 && current_SID < 999999) {
return SCRIPT_ITEM(current_sctx.sc_sid).sn_pr_force; return SCRIPT_ITEM(current_sctx.sc_sid).sn_pr_force;
} }
return false; return false;
@@ -3015,6 +3015,44 @@ static FILE *fopen_noinh_readbin(char *filename)
return fdopen(fd_tmp, READBIN); return fdopen(fd_tmp, READBIN);
} }
typedef struct {
char_u *buf;
size_t offset;
} GetStrLineCookie;
static char_u *get_str_line(int c, void *cookie, int ident)
{
GetStrLineCookie *p = cookie;
size_t i = p->offset;
if (strlen((char *)p->buf) <= p->offset) {
return NULL;
}
while (!(p->buf[i] == '\n' || p->buf[i] == '\0')) {
i++;
}
char buf[2046];
char *dst;
dst = xstpncpy(buf, (char *)p->buf+p->offset, i - p->offset);
if ((uint32_t)(dst - buf) != i - p->offset) {
smsg(_("nvim_source error parsing command %s"), p->buf);
}
buf[i-p->offset]='\0';
p->offset = i + 1;
return (char_u *)xstrdup(buf);
}
int do_source_str(char_u *cmd)
{
int retval;
GetStrLineCookie cookie = {
.buf = cmd,
.offset = 0,
};
current_SID = 999999;
retval = do_cmdline(NULL, get_str_line, (void *)&cookie,
DOCMD_NOWAIT);
return retval;
}
/// Read the file "fname" and execute its lines as EX commands. /// Read the file "fname" and execute its lines as EX commands.
/// ///

View File

@@ -74,6 +74,84 @@ 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()
it('works with a one-liner', function()
nvim('source', "let x1 = 'a'")
eq(nvim('get_var', 'x1'), 'a')
end)
it('works with stray newline character', function()
nvim('source', "let x2 = 'a'\n")
eq(nvim('get_var', 'x2'),'a')
end)
it('works with multiline command', function()
nvim('source', 'lua <<EOF\ny=3\nEOF')
eq(nvim('command_output', "echo luaeval('y')"),'3')
end)
it('works with multiple stray newline character', function()
nvim('source','lua <<EOF\n\n\n\ny=3\n\n\nEOF')
eq(nvim('command_output', "echo luaeval('y')"), '3')
end)
it('works with utf-8', function()
nvim('command', 'new')
nvim('command', 'normal i ax \n Ax ')
nvim('source', ":%s/ax/--a1234--/g | :%s/Ax/--A1234--/g")
nvim('command','1')
eq(' --a1234-- ',nvim('get_current_line'))
nvim('command','2')
eq(' --A1234-- ',nvim('get_current_line'))
end)
it('works with latin characters', function()
nvim('command', 'new')
nvim('command', "call setline(1,['xxx'])")
nvim('source', "call feedkeys('r')|call feedkeys('ñ', 'xt')")
eq('ñxx',nvim('get_current_line'))
end)
it('nvim_source validation error:fails with specific error', function()
local status, rv = pcall(nvim, "source", "bogus_command")
eq(false, status) -- nvim_command() failed.
eq("E492:", string.match(rv, "E%d*:")) -- VimL error was returned.
eq('', nvim('eval', 'v:errmsg')) -- v:errmsg was not updated.
eq('', eval('v:exception'))
end)
it('nvim_source execution error: fails with specific error', function()
local status, rv = pcall(nvim, "source", "buffer 23487")
eq(false, status) -- nvim_command() failed.
eq("E86: Buffer 23487 does not exist", string.match(rv, "E%d*:.*"))
eq('', eval('v:errmsg')) -- v:errmsg was not updated.
eq('', eval('v:exception'))
end)
it('nvim_source autocommands work', function()
nvim('source','autocmd BufCreate * :let x1 = "Hello"')
local fname = helpers.tmpname()
nvim('command', 'new '..fname)
eq(nvim('command_output','echo x1'),"Hello")
end)
it('nvim_source: recursive source works', function()
local fname = helpers.tmpname()
nvim('command', 'new')
nvim('command','edit '..fname)
nvim('command','normal ilet x1 = "a"')
nvim('command','w')
nvim('source','call nvim_source("source '..fname..'")')
eq(nvim('get_var','x1'),'a')
end)
it('nvim_source: functions work', function()
nvim('source','function Foo()\ncall setline(1,["xxx"])\nendfunction')
nvim('source','call Foo()')
eq(nvim('get_current_line'),'xxx')
end)
end)
describe('nvim_command', function() describe('nvim_command', function()
it('works', function() it('works', function()
local fname = helpers.tmpname() local fname = helpers.tmpname()