aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2023-01-02 15:34:14 +0100
committerJustin M. Keyes <justinkz@gmail.com>2023-01-05 17:10:02 +0100
commitadef308a5925a3b967af3bd7c598074e5b6cae18 (patch)
tree10bb0dc4b3801eb53b56023542283c20aff7e967
parent45549f031ee52a01601c33acc411f3111cfc4e95 (diff)
downloadrneovim-adef308a5925a3b967af3bd7c598074e5b6cae18.tar.gz
rneovim-adef308a5925a3b967af3bd7c598074e5b6cae18.tar.bz2
rneovim-adef308a5925a3b967af3bd7c598074e5b6cae18.zip
feat(lua): exit 1 on Lua "-l" script error
-rw-r--r--src/nvim/globals.h2
-rw-r--r--src/nvim/lua/executor.c11
-rw-r--r--src/nvim/main.c23
-rw-r--r--test/functional/core/startup_spec.lua21
-rw-r--r--test/functional/fixtures/startup-fail.lua7
-rw-r--r--test/functional/vimscript/system_spec.lua2
6 files changed, 43 insertions, 23 deletions
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index b5ffabf57c..bb7c519b7c 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -1042,7 +1042,7 @@ EXTERN int vim_ignored;
// stdio is an RPC channel (--embed).
EXTERN bool embedded_mode INIT(= false);
-// Do not start a UI nor read/write to stdio (unless embedding).
+// Do not start UI (--headless, -l) nor read/write to stdio (unless embedding).
EXTERN bool headless_mode INIT(= false);
// uncrustify:on
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 20c901004a..4b08603dd0 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -325,10 +325,11 @@ static int nlua_thr_api_nvim__get_runtime(lua_State *lstate)
/// Copies args starting at `lua_arg0` into the Lua `arg` global.
///
-/// Example:
+/// Example (`lua_arg0` points to "--arg1"):
/// nvim -l foo.lua --arg1 --arg2
///
-/// @note `lua` CLI sets _negative_ `arg` indices to the arguments upto "-e".
+/// @note Lua CLI sets arguments upto "-e" as _negative_ `_G.arg` indices, but we currently don't
+/// follow that convention.
///
/// @see https://www.lua.org/pil/1.4.html
/// @see https://github.com/premake/premake-core/blob/1c1304637f4f5e50ba8c57aae8d1d80ec3b7aaf2/src/host/premake.c#L563-L594
@@ -1710,10 +1711,10 @@ void ex_luafile(exarg_T *const eap)
nlua_exec_file((const char *)eap->arg);
}
-/// execute lua code from a file.
+/// Executes Lua code from a file.
///
-/// Note: we call the lua global loadfile as opposed to calling luaL_loadfile
-/// in case loadfile has been overridden in the users environment.
+/// Note: we call the Lua global loadfile as opposed to calling luaL_loadfile
+/// in case loadfile was overridden in the user's environment.
///
/// @param path path of the file
///
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 908395655f..616cf1b4b6 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -608,8 +608,9 @@ int main(int argc, char **argv)
}
if (params.luaf != NULL) {
- nlua_exec_file(params.luaf);
- // return 0;
+ bool lua_ok = nlua_exec_file(params.luaf);
+ TIME_MSG("executing Lua -l script");
+ getout(lua_ok ? 0 : 1);
}
TIME_MSG("before starting main loop");
@@ -659,9 +660,8 @@ void getout(int exitval)
{
exiting = true;
- // When running in Ex mode an error causes us to exit with a non-zero exit
- // code. POSIX requires this, although it's not 100% clear from the
- // standard.
+ // On error during Ex mode, exit with a non-zero code.
+ // POSIX requires this, although it's not 100% clear from the standard.
if (exmode_active) {
exitval += ex_exitval;
}
@@ -752,6 +752,7 @@ void getout(int exitval)
if (did_emsg) {
// give the user a chance to read the (error) message
no_wait_return = false;
+ // TODO(justinmk): this may call getout(0), clobbering exitval...
wait_return(false);
}
@@ -775,10 +776,9 @@ void getout(int exitval)
os_exit(exitval);
}
-/// Preserve files and exit.
-/// @note IObuff must contain a message.
-/// @note This may be called from deadly_signal() in a signal handler, avoid
-/// unsafe functions, such as allocating memory.
+/// Preserve files, print contents of `IObuff`, and exit 1.
+///
+/// May be called from deadly_signal().
void preserve_exit(void)
FUNC_ATTR_NORETURN
{
@@ -1309,6 +1309,7 @@ static void command_line_scan(mparm_T *parmp)
break;
case 'l': // "-l" Lua script: args after "-l".
+ headless_mode = true;
silent_mode = true;
p_verbose = 1;
parmp->no_swap_file = true;
@@ -1403,8 +1404,8 @@ scripterror:
}
}
- if (embedded_mode && silent_mode) {
- mainerr(_("--embed conflicts with -es/-Es"), NULL);
+ if (embedded_mode && (silent_mode || parmp->luaf)) {
+ mainerr(_("--embed conflicts with -es/-Es/-l"), NULL);
}
// If there is a "+123" or "-c" command, set v:swapcommand to the first one.
diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua
index dbd517995c..455de08548 100644
--- a/test/functional/core/startup_spec.lua
+++ b/test/functional/core/startup_spec.lua
@@ -88,11 +88,11 @@ describe('startup', function()
end)
describe('-l Lua', function()
- local function assert_l_out(expected, args_before, args_after)
+ local function assert_l_out(expected, nvim_args, lua_args)
local args = { nvim_prog, '--clean' }
- vim.list_extend(args, args_before or {})
+ vim.list_extend(args, nvim_args or {})
vim.list_extend(args, { '-l', 'test/functional/fixtures/startup.lua' })
- vim.list_extend(args, args_after or {})
+ vim.list_extend(args, lua_args or {})
local out = funcs.system(args):gsub('\r\n', '\n')
return eq(dedent(expected), out)
end
@@ -115,6 +115,13 @@ describe('startup', function()
eq(73, eval('v:shell_error'))
end)
+ it('Lua error sets Nvim exitcode', function()
+ eq(0, eval('v:shell_error'))
+ matches('E5113: .* my pearls!!',
+ funcs.system({ nvim_prog, '-l', 'test/functional/fixtures/startup-fail.lua' }))
+ eq(1, eval('v:shell_error'))
+ end)
+
it('sets _G.arg', function()
-- nvim -l foo.lua -arg1 -- a b c
assert_l_out([[
@@ -396,11 +403,13 @@ describe('startup', function()
{ 'put =mode(1)', 'print', '' }))
end)
- it('fails on --embed with -es/-Es', function()
- matches('nvim[.exe]*: %-%-embed conflicts with %-es/%-Es',
+ it('fails on --embed with -es/-Es/-l', function()
+ matches('nvim[.exe]*: %-%-embed conflicts with %-es/%-Es/%-l',
funcs.system({nvim_prog, '--embed', '-es' }))
- matches('nvim[.exe]*: %-%-embed conflicts with %-es/%-Es',
+ matches('nvim[.exe]*: %-%-embed conflicts with %-es/%-Es/%-l',
funcs.system({nvim_prog, '--embed', '-Es' }))
+ matches('nvim[.exe]*: %-%-embed conflicts with %-es/%-Es/%-l',
+ funcs.system({nvim_prog, '--embed', '-l', 'foo.lua' }))
end)
it('does not crash if --embed is given twice', function()
diff --git a/test/functional/fixtures/startup-fail.lua b/test/functional/fixtures/startup-fail.lua
new file mode 100644
index 0000000000..adcfe2a201
--- /dev/null
+++ b/test/functional/fixtures/startup-fail.lua
@@ -0,0 +1,7 @@
+-- Test "nvim -l foo.lua …" with a Lua error.
+
+local function main()
+ error('my pearls!!')
+end
+
+main()
diff --git a/test/functional/vimscript/system_spec.lua b/test/functional/vimscript/system_spec.lua
index dbf734b51a..f099b4a36e 100644
--- a/test/functional/vimscript/system_spec.lua
+++ b/test/functional/vimscript/system_spec.lua
@@ -1,3 +1,5 @@
+-- Tests for system() and :! shell.
+
local helpers = require('test.functional.helpers')(after_each)
local assert_alive = helpers.assert_alive