aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2025-01-05 17:10:16 -0800
committerGitHub <noreply@github.com>2025-01-05 17:10:16 -0800
commit5e02a2c47072ec08279b830daa6f82e39ba86c6e (patch)
treeac44f70b814e85c9398b531b577e6ebf203c5340
parent570a8da01b55c3aad1f057be236f55ccf82ed8af (diff)
downloadrneovim-5e02a2c47072ec08279b830daa6f82e39ba86c6e.tar.gz
rneovim-5e02a2c47072ec08279b830daa6f82e39ba86c6e.tar.bz2
rneovim-5e02a2c47072ec08279b830daa6f82e39ba86c6e.zip
"nvim -es": disable shada #21723
Problem: `nvim -es` (and `nvim -Es`) is the recommended way to non-interactively run commands/vimscript. But it enables shada by default, which is usually not wanted. Solution: - Disable shada by default for `nvim -es/-Es`. This can be overridden by `-i foo` if needed. - Do NOT change the 'loadplugins' default. - User config + packages _should_ be enabled by default, for both `nvim -es` and `nvim -l`. Else any Lua packages you have can't be accessed without `-u path/to/config`, which is clumsy. - Use-cases: ``` nvim --headless "+Lazy! sync" +qa would become: nvim -es "+Lazy! sync" nvim --headless +PlugInstall +qall would become: nvim -es +PlugInstall ``` - Opt-out (`--clean` or `-u NONE`) is much easier than opt-in (`-u path/to/config`). - User config/packages are analogous to pip packages, which are expected when doing `python -c ...`. related: 7c94bcd2d77e2e54b8836ab8325460a367b79eae related: ddd0eb6f5120a09b97867d2561ea61309038ccd2
-rw-r--r--runtime/doc/lua.txt14
-rw-r--r--runtime/doc/news.txt1
-rw-r--r--runtime/doc/starting.txt19
-rw-r--r--runtime/doc/vim_diff.txt2
-rw-r--r--src/nvim/main.c6
-rw-r--r--src/nvim/message.c2
-rw-r--r--test/functional/core/startup_spec.lua39
7 files changed, 58 insertions, 25 deletions
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index b7c5a50443..6547a76f56 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -618,20 +618,20 @@ Example: TCP echo-server *tcp-server*
Multithreading *lua-loop-threading*
Plugins can perform work in separate (os-level) threads using the threading
-APIs in luv, for instance `vim.uv.new_thread`. Note that every thread
-gets its own separate Lua interpreter state, with no access to Lua globals
-in the main thread. Neither can the state of the editor (buffers, windows,
-etc) be directly accessed from threads.
+APIs in luv, for instance `vim.uv.new_thread`. Each thread has its own
+separate Lua interpreter state, with no access to Lua globals on the main
+thread. Neither can the editor state (buffers, windows, etc) be directly
+accessed from threads.
-A subset of the `vim.*` API is available in threads. This includes:
+A subset of the `vim.*` stdlib is available in threads, including:
- `vim.uv` with a separate event loop per thread.
- `vim.mpack` and `vim.json` (useful for serializing messages between threads)
- `require` in threads can use Lua packages from the global |package.path|
- `print()` and `vim.inspect`
- `vim.diff`
-- most utility functions in `vim.*` for working with pure Lua values
- like `vim.split`, `vim.tbl_*`, `vim.list_*`, and so on.
+- Most utility functions in `vim.*` that work with pure Lua values, like
+ `vim.split`, `vim.tbl_*`, `vim.list_*`, etc.
- `vim.is_thread()` returns true from a non-main thread.
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
index d573b01baa..b7606e65f5 100644
--- a/runtime/doc/news.txt
+++ b/runtime/doc/news.txt
@@ -295,6 +295,7 @@ PLUGINS
STARTUP
+• |-es| ("script mode") disables shada by default.
• Nvim will fail if the |--listen| or |$NVIM_LISTEN_ADDRESS| address is
invalid, instead of silently skipping an invalid address.
diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt
index 3b0fa2b371..0bfbea75fb 100644
--- a/runtime/doc/starting.txt
+++ b/runtime/doc/starting.txt
@@ -207,12 +207,12 @@ argument.
:print
:set
With |:verbose| or 'verbose', other commands display on stderr: >
- nvim -es +":verbose echo 'foo'"
- nvim -V1 -es +foo
-
-< User |config| is skipped unless |-u| was given.
- Swap file is skipped (like |-n|).
- User |shada| is loaded (unless "-i NONE" is given).
+ nvim -es +"verbose echo 'foo'"
+ nvim -V1 -es +"echo 'foo'"
+<
+ Skips user |config| unless |-u| was given.
+ Disables |shada| unless |-i| was given.
+ Disables swapfile (like |-n|).
*-l*
-l {script} [args]
@@ -235,6 +235,11 @@ argument.
nvim +q -l foo.lua
< This loads Lua module "bar" before executing "foo.lua": >
nvim +"lua require('bar')" -l foo.lua
+< *lua-shebang*
+ You can set the "shebang" of the script so that Nvim executes
+ the script when called with "./" from a shell (remember to
+ "chmod u+x"): >
+ #!/usr/bin/env -S nvim -l
<
Skips user |config| unless |-u| was given.
Disables plugins unless 'loadplugins' was set.
@@ -243,7 +248,7 @@ argument.
*-ll*
-ll {script} [args]
- Execute a Lua script, similarly to |-l|, but the editor is not
+ Executes a Lua script, similarly to |-l|, but the editor is not
initialized. This gives a Lua environment similar to a worker
thread. See |lua-loop-threading|.
diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt
index 9f28b373ee..a92ddf33e6 100644
--- a/runtime/doc/vim_diff.txt
+++ b/runtime/doc/vim_diff.txt
@@ -409,6 +409,8 @@ Startup:
- |-es| and |-Es| have improved behavior:
- Quits automatically, don't need "-c qa!".
- Skips swap-file dialog.
+ - Optimized for non-interactive scripts: disables swapfile, shada.
+- |-l| Executes Lua scripts non-interactively.
- |-s| reads Normal commands from stdin if the script name is "-".
- Reading text (instead of commands) from stdin |--|:
- works by default: "-" file is optional
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 2b55a48c12..58d110e8b2 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -1228,6 +1228,9 @@ static void command_line_scan(mparm_T *parmp)
if (exmode_active) { // "-es" silent (batch) Ex-mode
silent_mode = true;
parmp->no_swap_file = true;
+ if (p_shadafile == NULL || *p_shadafile == NUL) {
+ set_option_value_give_err(kOptShadafile, STATIC_CSTR_AS_OPTVAL("NONE"), 0);
+ }
} else { // "-s {scriptin}" read from script file
want_argument = true;
}
@@ -2085,8 +2088,7 @@ static void source_startup_scripts(const mparm_T *const parmp)
{
// If -u given, use only the initializations from that file and nothing else.
if (parmp->use_vimrc != NULL) {
- if (strequal(parmp->use_vimrc, "NONE")
- || strequal(parmp->use_vimrc, "NORC")) {
+ if (strequal(parmp->use_vimrc, "NONE") || strequal(parmp->use_vimrc, "NORC")) {
// Do nothing.
} else {
if (do_source(parmp->use_vimrc, false, DOSO_NONE, NULL) != OK) {
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 661d0754d4..d45bc147cb 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -2719,7 +2719,7 @@ static msgchunk_T *disp_sb_line(int row, msgchunk_T *smp)
}
/// @return true when messages should be printed to stdout/stderr:
-/// - "batch mode" ("silent mode", -es/-Es)
+/// - "batch mode" ("silent mode", -es/-Es/-l)
/// - no UI and not embedded
int msg_use_printf(void)
{
diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua
index 642e2b0287..8ecd3dca97 100644
--- a/test/functional/core/startup_spec.lua
+++ b/test/functional/core/startup_spec.lua
@@ -136,7 +136,11 @@ describe('startup', function()
vim.list_extend(args, { '-l', (script or 'test/functional/fixtures/startup.lua') })
vim.list_extend(args, lua_args or {})
local out = fn.system(args, input):gsub('\r\n', '\n')
- return eq(dedent(expected), out)
+ if type(expected) == 'function' then
+ return expected(out)
+ else
+ return eq(dedent(expected), out)
+ end
end
it('failure modes', function()
@@ -172,6 +176,7 @@ describe('startup', function()
it('Lua-error sets Nvim exitcode', function()
local proc = n.spawn_wait('-l', 'test/functional/fixtures/startup-fail.lua')
matches('E5113: .* my pearls!!', proc:output())
+ eq(0, proc.signal)
eq(1, proc.status)
eq(0, eval('v:shell_error'))
@@ -282,14 +287,30 @@ describe('startup', function()
eq(0, eval('v:shell_error'))
end)
- it('disables swapfile/shada/config/plugins', function()
+ it('disables swapfile/shada/config/plugins unless overridden', function()
+ local script = [[print(('updatecount=%d shadafile=%s loadplugins=%s scripts=%d'):format(
+ vim.o.updatecount, vim.o.shadafile, tostring(vim.o.loadplugins), math.max(1, #vim.fn.getscriptinfo())))]]
+ finally(function()
+ os.remove('Xtest_shada')
+ end)
+
assert_l_out(
'updatecount=0 shadafile=NONE loadplugins=false scripts=1\n',
nil,
nil,
'-',
- [[print(('updatecount=%d shadafile=%s loadplugins=%s scripts=%d'):format(
- vim.o.updatecount, vim.o.shadafile, tostring(vim.o.loadplugins), math.max(1, #vim.fn.getscriptinfo())))]]
+ script
+ )
+
+ -- User can override.
+ assert_l_out(
+ function(out)
+ return matches('updatecount=99 shadafile=Xtest_shada loadplugins=true scripts=2%d\n', out)
+ end,
+ { '+set updatecount=99', '-i', 'Xtest_shada', '+set loadplugins', '-u', 'NORC' },
+ nil,
+ '-',
+ script
)
end)
end)
@@ -572,19 +593,21 @@ describe('startup', function()
eq(' encoding=utf-8\n', fn.system({ nvim_prog, '-n', '-es' }, { 'set encoding', '' }))
end)
- it('-es/-Es disables swapfile, user config #8540', function()
+ it('-es/-Es disables swapfile/shada/config #8540', function()
for _, arg in ipairs({ '-es', '-Es' }) do
local out = fn.system({
nvim_prog,
arg,
- '+set swapfile? updatecount? shadafile?',
+ '+set updatecount? shadafile? loadplugins?',
'+put =map(getscriptinfo(), {-> v:val.name})',
'+%print',
})
local line1 = string.match(out, '^.-\n')
-- updatecount=0 means swapfile was disabled.
- eq(' swapfile updatecount=0 shadafile=\n', line1)
- -- Standard plugins were loaded, but not user config.
+ eq(' updatecount=0 shadafile=NONE loadplugins\n', line1)
+ -- Standard plugins were loaded, but not user config. #31878
+ local nrlines = #vim.split(out, '\n')
+ ok(nrlines > 20, '>20', nrlines)
ok(string.find(out, 'man.lua') ~= nil)
ok(string.find(out, 'init.vim') == nil)
end