mirror of
https://github.com/neovim/neovim.git
synced 2025-10-09 11:26:37 +00:00
feat(lua)!: execute Lua with "nvim -l"
Problem: Nvim has Lua but the "nvim" CLI can't easily be used to execute Lua scripts, especially scripts that take arguments or produce output. Solution: - support "nvim -l [args...]" for running scripts. closes #15749 - exit without +q - remove lua2dox_filter - remove Doxyfile. This wasn't used anyway, because the doxygen config is inlined in gen_vimdoc.py (`Doxyfile` variable). - use "nvim -l" in docs-gen CI job Examples: $ nvim -l scripts/lua2dox.lua --help Lua2DoX (0.2 20130128) ... $ echo "print(vim.inspect(_G.arg))" | nvim -l - --arg1 --arg2 $ echo 'print(vim.inspect(vim.api.nvim_buf_get_text(1,0,0,-1,-1,{})))' | nvim +"put ='text'" -l - TODO? -e executes Lua code -l loads a module -i enters REPL _after running the other arguments_.
This commit is contained in:
2566
src/Doxyfile
2566
src/Doxyfile
File diff suppressed because it is too large
Load Diff
@@ -515,7 +515,7 @@ EXTERN int allbuf_lock INIT(= 0);
|
||||
/// not allowed then.
|
||||
EXTERN int sandbox INIT(= 0);
|
||||
|
||||
/// Batch-mode: "-es" or "-Es" commandline argument was given.
|
||||
/// Batch-mode: "-es", "-Es", "-l" commandline argument was given.
|
||||
EXTERN int silent_mode INIT(= false);
|
||||
|
||||
/// Start position of active Visual selection.
|
||||
|
@@ -323,6 +323,34 @@ static int nlua_thr_api_nvim__get_runtime(lua_State *lstate)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// Copies all args into the Lua `arg` global.
|
||||
///
|
||||
/// Example:
|
||||
/// nvim -l foo.lua -- -e "sin=math.sin" script a b
|
||||
///
|
||||
/// @note `lua` CLI sets _negative_ `arg` indices to the arguments upto "-e".
|
||||
///
|
||||
/// @see https://www.lua.org/pil/1.4.html
|
||||
/// @see https://github.com/premake/premake-core/blob/1c1304637f4f5e50ba8c57aae8d1d80ec3b7aaf2/src/host/premake.c#L563-L594
|
||||
///
|
||||
/// @returns number of args (stops at "--")
|
||||
int nlua_set_argv(char **argv, int argc)
|
||||
{
|
||||
lua_State *const L = global_lstate;
|
||||
lua_newtable(L);
|
||||
int i = 0;
|
||||
for (; i < argc; i++) {
|
||||
if (strequal("--", argv[i])) {
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
lua_pushstring(L, argv[i]);
|
||||
lua_rawseti(L, -2, i + 1);
|
||||
}
|
||||
lua_setglobal(L, "arg");
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
static void nlua_schedule_event(void **argv)
|
||||
{
|
||||
LuaRef cb = (LuaRef)(ptrdiff_t)argv[0];
|
||||
|
@@ -275,14 +275,14 @@ int main(int argc, char **argv)
|
||||
// Check if we have an interactive window.
|
||||
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
|
||||
// argument list "global_alist".
|
||||
command_line_scan(¶ms);
|
||||
|
||||
nlua_init();
|
||||
|
||||
TIME_MSG("init lua interpreter");
|
||||
|
||||
if (embedded_mode) {
|
||||
const char *err;
|
||||
if (!channel_from_stdio(true, CALLBACK_READER_INIT, &err)) {
|
||||
@@ -363,8 +363,7 @@ int main(int argc, char **argv)
|
||||
debug_break_level = params.use_debug_break_level;
|
||||
|
||||
// Read ex-commands if invoked with "-es".
|
||||
if (!params.input_isatty && !params.input_neverscript
|
||||
&& silent_mode && exmode_active) {
|
||||
if (!params.input_isatty && !params.input_istext && silent_mode && exmode_active) {
|
||||
input_start(STDIN_FILENO);
|
||||
}
|
||||
|
||||
@@ -409,14 +408,12 @@ int main(int argc, char **argv)
|
||||
init_default_autocmds();
|
||||
TIME_MSG("init default autocommands");
|
||||
|
||||
bool vimrc_none = params.use_vimrc != NULL && strequal(params.use_vimrc, "NONE");
|
||||
bool vimrc_none = strequal(params.use_vimrc, "NONE");
|
||||
|
||||
// Reset 'loadplugins' for "-u NONE" before "--cmd" arguments.
|
||||
// Allows for setting 'loadplugins' there.
|
||||
if (vimrc_none) {
|
||||
// When using --clean we still want to load plugins
|
||||
p_lpl = params.clean;
|
||||
}
|
||||
// For --clean we still want to load plugins.
|
||||
p_lpl = vimrc_none ? params.clean : p_lpl;
|
||||
|
||||
// Execute --cmd arguments.
|
||||
exe_pre_commands(¶ms);
|
||||
@@ -610,6 +607,11 @@ int main(int argc, char **argv)
|
||||
(void)eval_has_provider("clipboard");
|
||||
}
|
||||
|
||||
if (params.luaf != NULL) {
|
||||
nlua_exec_file(params.luaf);
|
||||
// return 0;
|
||||
}
|
||||
|
||||
TIME_MSG("before starting main loop");
|
||||
ILOG("starting main loop");
|
||||
|
||||
@@ -962,7 +964,7 @@ static bool edit_stdin(mparm_T *parmp)
|
||||
{
|
||||
bool implicit = !headless_mode
|
||||
&& !(embedded_mode && stdin_fd <= 0)
|
||||
&& (!exmode_active || parmp->input_neverscript)
|
||||
&& (!exmode_active || parmp->input_istext)
|
||||
&& !parmp->input_isatty
|
||||
&& parmp->scriptin == NULL; // `-s -` was not given.
|
||||
return parmp->had_stdin_file || implicit;
|
||||
@@ -993,9 +995,9 @@ static void command_line_scan(mparm_T *parmp)
|
||||
} else {
|
||||
parmp->commands[parmp->n_commands++] = &(argv[0][1]);
|
||||
}
|
||||
|
||||
// Optional argument.
|
||||
} else if (argv[0][0] == '-' && !had_minmin) {
|
||||
// Optional argument.
|
||||
|
||||
want_argument = false;
|
||||
char c = argv[0][argv_idx++];
|
||||
switch (c) {
|
||||
@@ -1005,9 +1007,7 @@ static void command_line_scan(mparm_T *parmp)
|
||||
silent_mode = true;
|
||||
parmp->no_swap_file = true;
|
||||
} else {
|
||||
if (parmp->edit_type != EDIT_NONE
|
||||
&& parmp->edit_type != EDIT_FILE
|
||||
&& parmp->edit_type != EDIT_STDIN) {
|
||||
if (parmp->edit_type > EDIT_STDIN) {
|
||||
mainerr(err_too_many_args, argv[0]);
|
||||
}
|
||||
parmp->had_stdin_file = true;
|
||||
@@ -1015,7 +1015,7 @@ static void command_line_scan(mparm_T *parmp)
|
||||
}
|
||||
argv_idx = -1; // skip to next argument
|
||||
break;
|
||||
case '-': // "--" don't take any more option arguments
|
||||
case '-': // "--" No more option arguments.
|
||||
// "--help" give help message
|
||||
// "--version" give version message
|
||||
// "--noplugin[s]" skip plugins
|
||||
@@ -1111,7 +1111,7 @@ static void command_line_scan(mparm_T *parmp)
|
||||
break;
|
||||
case 'E': // "-E" Ex mode
|
||||
exmode_active = true;
|
||||
parmp->input_neverscript = true;
|
||||
parmp->input_istext = true;
|
||||
break;
|
||||
case 'f': // "-f" GUI: run in foreground.
|
||||
break;
|
||||
@@ -1123,10 +1123,6 @@ static void command_line_scan(mparm_T *parmp)
|
||||
p_hkmap = true;
|
||||
set_option_value_give_err("rl", 1L, NULL, 0);
|
||||
break;
|
||||
case 'l': // "-l" lisp mode, 'lisp' and 'showmatch' on.
|
||||
set_option_value_give_err("lisp", 1L, NULL, 0);
|
||||
p_sm = true;
|
||||
break;
|
||||
case 'M': // "-M" no changes or writing of files
|
||||
reset_modifiable();
|
||||
FALLTHROUGH;
|
||||
@@ -1231,6 +1227,7 @@ static void command_line_scan(mparm_T *parmp)
|
||||
FALLTHROUGH;
|
||||
case 'S': // "-S {file}" execute Vim script
|
||||
case 'i': // "-i {shada}" use for ShaDa file
|
||||
case 'l': // "-l {file}" Lua mode
|
||||
case 'u': // "-u {vimrc}" vim inits file
|
||||
case 'U': // "-U {gvimrc}" gvim inits file
|
||||
case 'W': // "-W {scriptout}" overwrite
|
||||
@@ -1311,6 +1308,27 @@ static void command_line_scan(mparm_T *parmp)
|
||||
set_option_value_give_err("shadafile", 0L, argv[0], 0);
|
||||
break;
|
||||
|
||||
case 'l': // "-l" Lua script: args after "-l".
|
||||
silent_mode = true;
|
||||
p_verbose = 1;
|
||||
parmp->no_swap_file = true;
|
||||
parmp->use_vimrc = parmp->use_vimrc ? parmp->use_vimrc : "NONE";
|
||||
if (p_shadafile == NULL || *p_shadafile == NUL) {
|
||||
set_option_value_give_err("shadafile", 0L, "NONE", 0);
|
||||
}
|
||||
parmp->luaf = argv[0];
|
||||
argc--;
|
||||
argv++;
|
||||
// Lua args after "-l <file>" (upto "--").
|
||||
int l_argc = nlua_set_argv(argv, argc);
|
||||
assert(l_argc >= 0);
|
||||
argc = argc - l_argc;
|
||||
if (argc > 0) { // Found "--".
|
||||
argv = argv + l_argc;
|
||||
had_minmin = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 's': // "-s {scriptin}" read from script file
|
||||
if (parmp->scriptin != NULL) {
|
||||
scripterror:
|
||||
@@ -1354,9 +1372,7 @@ scripterror:
|
||||
argv_idx = -1; // skip to next argument
|
||||
|
||||
// Check for only one type of editing.
|
||||
if (parmp->edit_type != EDIT_NONE
|
||||
&& parmp->edit_type != EDIT_FILE
|
||||
&& parmp->edit_type != EDIT_STDIN) {
|
||||
if (parmp->edit_type > EDIT_STDIN) {
|
||||
mainerr(err_too_many_args, argv[0]);
|
||||
}
|
||||
parmp->edit_type = EDIT_FILE;
|
||||
@@ -1421,6 +1437,7 @@ static void init_params(mparm_T *paramp, int argc, char **argv)
|
||||
paramp->listen_addr = NULL;
|
||||
paramp->server_addr = NULL;
|
||||
paramp->remote = 0;
|
||||
paramp->luaf = NULL;
|
||||
}
|
||||
|
||||
/// Initialize global startuptime file if "--startuptime" passed as an argument.
|
||||
@@ -2154,6 +2171,7 @@ static void usage(void)
|
||||
os_msg(_(" + Start at end of file\n"));
|
||||
os_msg(_(" --cmd <cmd> Execute <cmd> before any config\n"));
|
||||
os_msg(_(" +<cmd>, -c <cmd> Execute <cmd> after config and first file\n"));
|
||||
os_msg(_(" -l <script> [args...] Execute Lua <script> (with optional args)\n"));
|
||||
os_msg("\n");
|
||||
os_msg(_(" -b Binary mode\n"));
|
||||
os_msg(_(" -d Diff mode\n"));
|
||||
|
@@ -23,15 +23,17 @@ typedef struct {
|
||||
char cmds_tofree[MAX_ARG_CMDS]; // commands that need free()
|
||||
int n_pre_commands; // no. of commands from --cmd
|
||||
char *pre_commands[MAX_ARG_CMDS]; // commands from --cmd argument
|
||||
char *luaf; // Lua script filename from "-l"
|
||||
|
||||
int edit_type; // type of editing to do
|
||||
char *tagname; // tag from -t argument
|
||||
char *use_ef; // 'errorfile' from -q argument
|
||||
|
||||
bool input_isatty; // stdin is a terminal
|
||||
bool input_istext; // stdin is text, not executable (-E/-Es)
|
||||
bool output_isatty; // stdout is a terminal
|
||||
bool err_isatty; // stderr is a terminal
|
||||
bool input_neverscript; // never treat stdin as script (-E/-Es)
|
||||
|
||||
int no_swap_file; // "-n" argument used
|
||||
int use_debug_break_level;
|
||||
int window_count; // number of windows to use
|
||||
|
@@ -962,6 +962,7 @@ endfunc
|
||||
|
||||
" Test for enabling the lisp mode on startup
|
||||
func Test_l_arg()
|
||||
throw 'Skipped: Nvim -l arg differs from Vim'
|
||||
let after =<< trim [CODE]
|
||||
let s = 'lisp=' .. &lisp .. ', showmatch=' .. &showmatch
|
||||
call writefile([s], 'Xtestout')
|
||||
|
Reference in New Issue
Block a user