mirror of
https://github.com/neovim/neovim.git
synced 2025-09-27 21:48:35 +00:00
feat(lua): send "--" literally to Lua "-l" script
Problem: When "-l" is followed by "--", we stop sending args to the Lua script and treat "--" in the usual way. This was for flexibility but didn't have a strong use-case, and has these problems: - prevents Lua "-l" scripts from handling "--" in their own way. - complicates the startup logic (must call nlua_init before command_line_scan) Solution: Don't treat "--" specially if it follows "-l".
This commit is contained in:
@@ -32,7 +32,7 @@ filename One or more file names. The first one will be the current
|
|||||||
an option, precede the arglist with "--", e.g.: >
|
an option, precede the arglist with "--", e.g.: >
|
||||||
nvim -- -filename
|
nvim -- -filename
|
||||||
< All arguments after "--" are interpreted as file names, no
|
< All arguments after "--" are interpreted as file names, no
|
||||||
other options or "+command" argument can follow.
|
other options or "+command" arguments can follow.
|
||||||
|
|
||||||
*--*
|
*--*
|
||||||
`-` Alias for stdin (standard input).
|
`-` Alias for stdin (standard input).
|
||||||
@@ -143,9 +143,9 @@ argument.
|
|||||||
these commands, independently from "-c" commands.
|
these commands, independently from "-c" commands.
|
||||||
|
|
||||||
*-S*
|
*-S*
|
||||||
-S [file] Vimscript or Lua (".lua") [file] will be |:source|d after the
|
-S [file] Executes Vimscript or Lua (".lua") [file] after the first file
|
||||||
first file has been read or "Session.vim" if [file] is not
|
has been read. See also |:source|. If [file] is not given,
|
||||||
given. Equivalent to: >
|
defaults to "Session.vim". Equivalent to: >
|
||||||
-c "source {file}"
|
-c "source {file}"
|
||||||
< Can be repeated like "-c", subject to the same limit of 10
|
< Can be repeated like "-c", subject to the same limit of 10
|
||||||
"-c" arguments. {file} cannot start with a "-".
|
"-c" arguments. {file} cannot start with a "-".
|
||||||
@@ -190,8 +190,9 @@ argument.
|
|||||||
-E reads stdin as text (into buffer 1).
|
-E reads stdin as text (into buffer 1).
|
||||||
|
|
||||||
-es *-es* *-Es* *-s-ex* *silent-mode*
|
-es *-es* *-Es* *-s-ex* *silent-mode*
|
||||||
-Es Silent mode (no UI), for scripting. Unrelated to |-s|.
|
-Es Script mode, aka "silent mode", aka "batch mode". No UI,
|
||||||
Disables most prompts, messages, warnings and errors.
|
disables most prompts and messages. Unrelated to |-s|.
|
||||||
|
See also |-S| to run script files.
|
||||||
|
|
||||||
-es reads/executes stdin as Ex commands. >
|
-es reads/executes stdin as Ex commands. >
|
||||||
printf "put ='foo'\n%%print\n" | nvim -es
|
printf "put ='foo'\n%%print\n" | nvim -es
|
||||||
@@ -215,16 +216,22 @@ argument.
|
|||||||
|
|
||||||
*-l*
|
*-l*
|
||||||
-l {script} [args]
|
-l {script} [args]
|
||||||
Executes Lua {script} file and exits. All [args] (up to "--"
|
Executes Lua {script} non-interactively (no UI) with optional
|
||||||
|---|) are treated as {script} args, not Nvim args: by Lua
|
[args] after processing any preceding Nvim |cli-arguments|,
|
||||||
convention they are set in the `_G.arg` global table. *lua-args*
|
then exits. See |-S| to run multiple Lua scripts without args,
|
||||||
On {script} error, Nvim exits with code 1.
|
or in an interactive session.
|
||||||
|
*lua-args*
|
||||||
|
All [args] are treated as {script} arguments and passed
|
||||||
|
literally to Lua (in the conventional `_G.arg` global table),
|
||||||
|
thus "-l" ends processing of Nvim arguments.
|
||||||
|
|
||||||
|
Exits with code 1 on Lua error.
|
||||||
|
|
||||||
Sets 'verbose' to 1 (like "-V1"), so Lua `print()` writes to
|
Sets 'verbose' to 1 (like "-V1"), so Lua `print()` writes to
|
||||||
output.
|
output.
|
||||||
|
|
||||||
Any |cli-arguments| before "-l" are processed before executing
|
Arguments before "-l" are processed before executing {script}.
|
||||||
{script}. For example this quits before executing "foo.lua": >
|
This example quits before executing "foo.lua": >
|
||||||
nvim +q -l foo.lua
|
nvim +q -l foo.lua
|
||||||
< This loads Lua module "bar" before executing "foo.lua": >
|
< This loads Lua module "bar" before executing "foo.lua": >
|
||||||
nvim +"lua require('bar')" -l foo.lua
|
nvim +"lua require('bar')" -l foo.lua
|
||||||
@@ -256,7 +263,7 @@ argument.
|
|||||||
|
|
||||||
-V[N]{file}
|
-V[N]{file}
|
||||||
Like -V and sets 'verbosefile' to {file} (must not start with
|
Like -V and sets 'verbosefile' to {file} (must not start with
|
||||||
a digit). Messages are not displayed; instead they are
|
a digit). Messages are not displayed, instead they are
|
||||||
written to {file}.
|
written to {file}.
|
||||||
Example: >
|
Example: >
|
||||||
nvim -V20vimlog
|
nvim -V20vimlog
|
||||||
|
@@ -122,9 +122,6 @@ modifications.
|
|||||||
.It Fl b
|
.It Fl b
|
||||||
Binary mode.
|
Binary mode.
|
||||||
.Ic ":help edit-binary"
|
.Ic ":help edit-binary"
|
||||||
.It Fl l
|
|
||||||
Lisp mode.
|
|
||||||
Sets the 'lisp' and 'showmatch' options.
|
|
||||||
.It Fl A
|
.It Fl A
|
||||||
Arabic mode.
|
Arabic mode.
|
||||||
Sets the 'arabic' option.
|
Sets the 'arabic' option.
|
||||||
@@ -144,7 +141,7 @@ is specified, append messages to
|
|||||||
instead of printing them.
|
instead of printing them.
|
||||||
.Ic ":help 'verbose'"
|
.Ic ":help 'verbose'"
|
||||||
.It Fl D
|
.It Fl D
|
||||||
Debug mode for VimL (Vim script).
|
Vimscript debug mode.
|
||||||
Started when executing the first command from a script.
|
Started when executing the first command from a script.
|
||||||
:help debug-mode
|
:help debug-mode
|
||||||
.It Fl n
|
.It Fl n
|
||||||
@@ -268,10 +265,26 @@ but execute
|
|||||||
before processing any vimrc.
|
before processing any vimrc.
|
||||||
Up to 10 instances of these can be used independently from instances of
|
Up to 10 instances of these can be used independently from instances of
|
||||||
.Fl c .
|
.Fl c .
|
||||||
|
.It Fl l Ar script Op Ar args
|
||||||
|
Execute Lua
|
||||||
|
.Ar script
|
||||||
|
with optional
|
||||||
|
.Op Ar args
|
||||||
|
after processing any preceding Nvim startup arguments.
|
||||||
|
All
|
||||||
|
.Op Ar args
|
||||||
|
are treated as script arguments and are passed literally to Lua, that is,
|
||||||
|
.Fl l
|
||||||
|
stops processing of Nvim arguments.
|
||||||
|
.Ic ":help -l"
|
||||||
.It Fl S Op Ar session
|
.It Fl S Op Ar session
|
||||||
Source
|
Execute
|
||||||
.Ar session
|
.Ar session
|
||||||
after the first file argument has been read.
|
after the first file argument has been read. If
|
||||||
|
.Ar session
|
||||||
|
filename ends with
|
||||||
|
.Pa .lua
|
||||||
|
it is executed as Lua instead of Vimscript.
|
||||||
Equivalent to
|
Equivalent to
|
||||||
.Cm -c \(dqsource session\(dq .
|
.Cm -c \(dqsource session\(dq .
|
||||||
.Ar session
|
.Ar session
|
||||||
|
@@ -323,32 +323,28 @@ static int nlua_thr_api_nvim__get_runtime(lua_State *lstate)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Copies all args into the Lua `arg` global.
|
/// Copies args starting at `lua_arg0` into the Lua `arg` global.
|
||||||
///
|
///
|
||||||
/// Example:
|
/// Example:
|
||||||
/// nvim -l foo.lua -- -e "sin=math.sin" script a b
|
/// nvim -l foo.lua --arg1 --arg2
|
||||||
///
|
///
|
||||||
/// @note `lua` CLI sets _negative_ `arg` indices to the arguments upto "-e".
|
/// @note `lua` CLI sets _negative_ `arg` indices to the arguments upto "-e".
|
||||||
///
|
///
|
||||||
/// @see https://www.lua.org/pil/1.4.html
|
/// @see https://www.lua.org/pil/1.4.html
|
||||||
/// @see https://github.com/premake/premake-core/blob/1c1304637f4f5e50ba8c57aae8d1d80ec3b7aaf2/src/host/premake.c#L563-L594
|
/// @see https://github.com/premake/premake-core/blob/1c1304637f4f5e50ba8c57aae8d1d80ec3b7aaf2/src/host/premake.c#L563-L594
|
||||||
///
|
///
|
||||||
/// @returns number of args (stops at "--")
|
/// @returns number of args
|
||||||
int nlua_set_argv(char **argv, int argc)
|
int nlua_set_argv(char **argv, int argc, int lua_arg0)
|
||||||
{
|
{
|
||||||
lua_State *const L = global_lstate;
|
lua_State *const L = global_lstate;
|
||||||
lua_newtable(L);
|
lua_newtable(L); // _G.arg
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (; i < argc; i++) {
|
for (; lua_arg0 >= 0 && i + lua_arg0 < argc; i++) {
|
||||||
if (strequal("--", argv[i])) {
|
lua_pushstring(L, argv[i + lua_arg0]);
|
||||||
i--;
|
lua_rawseti(L, -2, i + 1); // _G.arg[i+1] = "arg1"
|
||||||
break;
|
|
||||||
}
|
|
||||||
lua_pushstring(L, argv[i]);
|
|
||||||
lua_rawseti(L, -2, i + 1);
|
|
||||||
}
|
}
|
||||||
lua_setglobal(L, "arg");
|
lua_setglobal(L, "arg");
|
||||||
return i + 1;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nlua_schedule_event(void **argv)
|
static void nlua_schedule_event(void **argv)
|
||||||
|
@@ -275,14 +275,14 @@ int main(int argc, char **argv)
|
|||||||
// Check if we have an interactive window.
|
// Check if we have an interactive window.
|
||||||
check_and_set_isatty(¶ms);
|
check_and_set_isatty(¶ms);
|
||||||
|
|
||||||
// TODO: should we try to keep param scan before this?
|
|
||||||
nlua_init();
|
|
||||||
TIME_MSG("init lua interpreter");
|
|
||||||
|
|
||||||
// Process the command line arguments. File names are put in the global
|
// Process the command line arguments. File names are put in the global
|
||||||
// argument list "global_alist".
|
// argument list "global_alist".
|
||||||
command_line_scan(¶ms);
|
command_line_scan(¶ms);
|
||||||
|
|
||||||
|
nlua_init();
|
||||||
|
nlua_set_argv(argv, argc, params.lua_arg0);
|
||||||
|
TIME_MSG("init lua interpreter");
|
||||||
|
|
||||||
if (embedded_mode) {
|
if (embedded_mode) {
|
||||||
const char *err;
|
const char *err;
|
||||||
if (!channel_from_stdio(true, CALLBACK_READER_INIT, &err)) {
|
if (!channel_from_stdio(true, CALLBACK_READER_INIT, &err)) {
|
||||||
@@ -1318,14 +1318,9 @@ static void command_line_scan(mparm_T *parmp)
|
|||||||
}
|
}
|
||||||
parmp->luaf = argv[0];
|
parmp->luaf = argv[0];
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
if (argc > 0) { // Lua args after "-l <file>".
|
||||||
// Lua args after "-l <file>" (upto "--").
|
parmp->lua_arg0 = parmp->argc - argc;
|
||||||
int l_argc = nlua_set_argv(argv, argc);
|
argc = 0;
|
||||||
assert(l_argc >= 0);
|
|
||||||
argc = argc - l_argc;
|
|
||||||
if (argc > 0) { // Found "--".
|
|
||||||
argv = argv + l_argc;
|
|
||||||
had_minmin = true;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1438,6 +1433,7 @@ static void init_params(mparm_T *paramp, int argc, char **argv)
|
|||||||
paramp->server_addr = NULL;
|
paramp->server_addr = NULL;
|
||||||
paramp->remote = 0;
|
paramp->remote = 0;
|
||||||
paramp->luaf = NULL;
|
paramp->luaf = NULL;
|
||||||
|
paramp->lua_arg0 = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize global startuptime file if "--startuptime" passed as an argument.
|
/// Initialize global startuptime file if "--startuptime" passed as an argument.
|
||||||
|
@@ -24,6 +24,7 @@ typedef struct {
|
|||||||
int n_pre_commands; // no. of commands from --cmd
|
int n_pre_commands; // no. of commands from --cmd
|
||||||
char *pre_commands[MAX_ARG_CMDS]; // commands from --cmd argument
|
char *pre_commands[MAX_ARG_CMDS]; // commands from --cmd argument
|
||||||
char *luaf; // Lua script filename from "-l"
|
char *luaf; // Lua script filename from "-l"
|
||||||
|
int lua_arg0; // Lua script args start index.
|
||||||
|
|
||||||
int edit_type; // type of editing to do
|
int edit_type; // type of editing to do
|
||||||
char *tagname; // tag from -t argument
|
char *tagname; // tag from -t argument
|
||||||
|
@@ -107,7 +107,8 @@ describe('startup', function()
|
|||||||
-- nvim -l foo.lua -arg1 -- a b c
|
-- nvim -l foo.lua -arg1 -- a b c
|
||||||
assert_l_out([[
|
assert_l_out([[
|
||||||
bufs:
|
bufs:
|
||||||
args: { "-arg1", "--exitcode", "73", "--arg2" }]],
|
nvim args: 8
|
||||||
|
lua args: { "-arg1", "--exitcode", "73", "--arg2" }]],
|
||||||
{},
|
{},
|
||||||
{ '-arg1', "--exitcode", "73", '--arg2' }
|
{ '-arg1', "--exitcode", "73", '--arg2' }
|
||||||
)
|
)
|
||||||
@@ -118,7 +119,8 @@ describe('startup', function()
|
|||||||
-- nvim -l foo.lua -arg1 -- a b c
|
-- nvim -l foo.lua -arg1 -- a b c
|
||||||
assert_l_out([[
|
assert_l_out([[
|
||||||
bufs:
|
bufs:
|
||||||
args: { "-arg1", "--arg2", "arg3" }]],
|
nvim args: 7
|
||||||
|
lua args: { "-arg1", "--arg2", "arg3" }]],
|
||||||
{},
|
{},
|
||||||
{ '-arg1', '--arg2', 'arg3' }
|
{ '-arg1', '--arg2', 'arg3' }
|
||||||
)
|
)
|
||||||
@@ -127,7 +129,8 @@ describe('startup', function()
|
|||||||
-- nvim -l foo.lua --
|
-- nvim -l foo.lua --
|
||||||
assert_l_out([[
|
assert_l_out([[
|
||||||
bufs:
|
bufs:
|
||||||
args: {}]],
|
nvim args: 5
|
||||||
|
lua args: { "--" }]],
|
||||||
{},
|
{},
|
||||||
{ '--' }
|
{ '--' }
|
||||||
)
|
)
|
||||||
@@ -135,8 +138,9 @@ describe('startup', function()
|
|||||||
|
|
||||||
-- nvim file1 file2 -l foo.lua -arg1 -- file3 file4
|
-- nvim file1 file2 -l foo.lua -arg1 -- file3 file4
|
||||||
assert_l_out([[
|
assert_l_out([[
|
||||||
bufs: file1 file2 file3 file4
|
bufs: file1 file2
|
||||||
args: { "-arg1", "arg 2" }]],
|
nvim args: 11
|
||||||
|
lua args: { "-arg1", "arg 2", "--", "file3", "file4" }]],
|
||||||
{ 'file1', 'file2', },
|
{ 'file1', 'file2', },
|
||||||
{ '-arg1', 'arg 2', '--', 'file3', 'file4' }
|
{ '-arg1', 'arg 2', '--', 'file3', 'file4' }
|
||||||
)
|
)
|
||||||
@@ -145,7 +149,8 @@ describe('startup', function()
|
|||||||
-- nvim file1 file2 -l foo.lua -arg1 --
|
-- nvim file1 file2 -l foo.lua -arg1 --
|
||||||
assert_l_out([[
|
assert_l_out([[
|
||||||
bufs: file1 file2
|
bufs: file1 file2
|
||||||
args: { "-arg1" }]],
|
nvim args: 8
|
||||||
|
lua args: { "-arg1", "--" }]],
|
||||||
{ 'file1', 'file2', },
|
{ 'file1', 'file2', },
|
||||||
{ '-arg1', '--' }
|
{ '-arg1', '--' }
|
||||||
)
|
)
|
||||||
@@ -154,7 +159,8 @@ describe('startup', function()
|
|||||||
-- nvim -l foo.lua <vim args>
|
-- nvim -l foo.lua <vim args>
|
||||||
assert_l_out([[
|
assert_l_out([[
|
||||||
bufs:
|
bufs:
|
||||||
args: { "-c", "set wrap?" }]],
|
nvim args: 6
|
||||||
|
lua args: { "-c", "set wrap?" }]],
|
||||||
{},
|
{},
|
||||||
{ '-c', 'set wrap?' }
|
{ '-c', 'set wrap?' }
|
||||||
)
|
)
|
||||||
@@ -167,7 +173,8 @@ describe('startup', function()
|
|||||||
wrap
|
wrap
|
||||||
|
|
||||||
bufs:
|
bufs:
|
||||||
args: { "-c", "set wrap?" }]],
|
nvim args: 8
|
||||||
|
lua args: { "-c", "set wrap?" }]],
|
||||||
{ '-c', 'set wrap?' },
|
{ '-c', 'set wrap?' },
|
||||||
{ '-c', 'set wrap?' }
|
{ '-c', 'set wrap?' }
|
||||||
)
|
)
|
||||||
|
@@ -23,7 +23,8 @@ end
|
|||||||
|
|
||||||
local function main()
|
local function main()
|
||||||
printbufs()
|
printbufs()
|
||||||
print('args:', vim.inspect(_G.arg))
|
print('nvim args:', #vim.v.argv)
|
||||||
|
print('lua args:', vim.inspect(_G.arg))
|
||||||
|
|
||||||
local exitcode = parseargs(_G.arg)
|
local exitcode = parseargs(_G.arg)
|
||||||
if type(exitcode) == 'number' then
|
if type(exitcode) == 'number' then
|
||||||
|
Reference in New Issue
Block a user