aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/ex_cmds.lua2
-rw-r--r--src/nvim/viml/executor/executor.c37
-rw-r--r--test/functional/lua/commands_spec.lua28
3 files changed, 65 insertions, 2 deletions
diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua
index 25e74ebf9b..ad2fb642d4 100644
--- a/src/nvim/ex_cmds.lua
+++ b/src/nvim/ex_cmds.lua
@@ -1554,7 +1554,7 @@ return {
command='luafile',
flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN),
addr_type=ADDR_LINES,
- func='ex_ni',
+ func='ex_luafile',
},
{
command='lvimgrep',
diff --git a/src/nvim/viml/executor/executor.c b/src/nvim/viml/executor/executor.c
index df63667102..a01bf9966d 100644
--- a/src/nvim/viml/executor/executor.c
+++ b/src/nvim/viml/executor/executor.c
@@ -161,7 +161,7 @@ static int nlua_exec_luado_string(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
{
const String *const str = (const String *)lua_touserdata(lstate, 1);
const linenr_T *const range = (const linenr_T *)lua_touserdata(lstate, 2);
- lua_pop(lstate, 1);
+ lua_pop(lstate, 2);
#define DOSTART "return function(line, linenr) "
#define DOEND " end"
@@ -225,6 +225,26 @@ static int nlua_exec_luado_string(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
return 0;
}
+/// Evaluate lua file
+///
+/// Expects one value on the stack: file to evaluate. Always returns nothing
+/// (from the lua point of view).
+static int nlua_exec_lua_file(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
+{
+ const char *const filename = (const char *)lua_touserdata(lstate, 1);
+ lua_pop(lstate, 1);
+
+ if (luaL_loadfile(lstate, filename)) {
+ nlua_error(lstate, _("E5112: Error while creating lua chunk: %.*s"));
+ return 0;
+ }
+ if (lua_pcall(lstate, 0, 0, 0)) {
+ nlua_error(lstate, _("E5113: Error while calling lua chunk: %.*s"));
+ return 0;
+ }
+ return 0;
+}
+
/// Initialize lua interpreter state
///
/// Called by lua interpreter itself to initialize state.
@@ -402,3 +422,18 @@ void ex_luado(exarg_T *const eap)
NLUA_CALL_C_FUNCTION_2(global_lstate, nlua_exec_luado_string, 0,
(void *)&cmd, (void *)range);
}
+
+/// Run lua file
+///
+/// Used for :luafile.
+///
+/// @param eap VimL command being run.
+void ex_luafile(exarg_T *const eap)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (global_lstate == NULL) {
+ global_lstate = init_lua();
+ }
+ NLUA_CALL_C_FUNCTION_1(global_lstate, nlua_exec_lua_file, 0,
+ (void *)eap->arg);
+}
diff --git a/test/functional/lua/commands_spec.lua b/test/functional/lua/commands_spec.lua
index 41a5a8d9e0..80fac07f8c 100644
--- a/test/functional/lua/commands_spec.lua
+++ b/test/functional/lua/commands_spec.lua
@@ -9,6 +9,7 @@ local funcs = helpers.funcs
local source = helpers.source
local dedent = helpers.dedent
local exc_exec = helpers.exc_exec
+local write_file = helpers.write_file
local redir_exec = helpers.redir_exec
local curbufmeths = helpers.curbufmeths
@@ -121,3 +122,30 @@ describe(':luado command', function()
eq({s}, curbufmeths.get_lines(0, -1, false))
end)
end)
+
+describe(':luafile', function()
+ local fname = 'Xtest-functional-lua-commands-luafile'
+
+ after_each(function()
+ os.remove(fname)
+ end)
+
+ it('works', function()
+ write_file(fname, [[
+ vim.api.nvim_buf_set_lines(1, 1, 2, false, {"ETTS"})
+ vim.api.nvim_buf_set_lines(1, 2, 3, false, {"TTSE"})
+ vim.api.nvim_buf_set_lines(1, 3, 4, false, {"STTE"})
+ ]])
+ eq('', redir_exec('luafile ' .. fname))
+ eq({'', 'ETTS', 'TTSE', 'STTE'}, curbufmeths.get_lines(0, 100, false))
+ end)
+
+ it('correctly errors out', function()
+ write_file(fname, '()')
+ eq(("Vim(luafile):E5112: Error while creating lua chunk: %s:1: unexpected symbol near ')'"):format(fname),
+ exc_exec('luafile ' .. fname))
+ write_file(fname, 'vimm.api.nvim_buf_set_lines(1, 1, 2, false, {"ETTS"})')
+ eq(("Vim(luafile):E5113: Error while calling lua chunk: %s:1: attempt to index global 'vimm' (a nil value)"):format(fname),
+ exc_exec('luafile ' .. fname))
+ end)
+end)