aboutsummaryrefslogtreecommitdiff
path: root/test/functional/core/startup_spec.lua
Commit message (Collapse)AuthorAge
* fix(startup): respect --noplugin when used with --clean #42362Max Coplan4 days
| | | | | | | | | | | | | | | Problem: When starting Nvim with both `--clean` and `--noplugin` (in either order), `--noplugin` is silently ignored and built-in runtime plugins are loaded anyway. `command_line_scan()` sets `p_lpl = false` for `--noplugin`, and `--clean` sets `params.use_vimrc = "NONE"` and `params.clean = true`, which later overwrites `p_lpl` back to `true` via `p_lpl = vimrc_none ? params.clean : p_lpl`. Solution: Only reset `p_lpl = false` when `vimrc_none && !params.clean`, preserving `p_lpl = false` if `--noplugin` was passed. AI-assisted
* fix(lua): regression with `print()` in headless modebfredl2026-10-06
| | | | | | | | | This is a bunch of hacks so we can override msg_puts_printf specifically while still allowing redirecting and "normal" message flow to happen, as this still has observable side-effects (even with no screen attached, screenstring() is still valid..) fixes #42218
* feat(lua): in script mode -l, use raw output for print()bfredl2026-10-02
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | consider the following test_script.lua : print 'hello\n' -- TWO new lines print 'this is \027[31mRED FOR AN AMAZING REASON\027[0m' print 'foo' print '' -- newline despite empty! print 'bar' -- a bit later: os.execute 'sleep 2' -- CPU goes BRR, cursor in column zero print 'more bar' before this PR, `nvim -l test_script.lua` had some weird behaviors compared to `lua test_script.lua` or the now removed `nvim -ll test_script.lua`. - one extra '\n' at the end of a print is ignored, one would need TWO '\n' for a single extra '\n' - an empty print'' is supposed to print an empty line - print'\027[31mRED' is being escaped so it does not work - the cursor gets stuck at the end of a message, instead of after emitting the new line, this looks like the CPU lag has something to do with the _last_ printed message which is likely not the case. I consider these behaviors to be unintentional (a consequence of stragglig through the message.c meta-machine, which is optimized for message handling in _an interative text editor_) and getting closer to plain lua behavior would be better. An alternative would be to restore the builtin print(), but our implemenation still has some benefits, like try `print(setmetatable({}, {__tostring=error})` in plain lua..
* feat(exmode): "1q:", :exmode #41010Justin M. Keyes2026-07-27
| | | | | | | | | Problem: Want `gQ` for _le multicursor_. Solution: - Don't use `gQ` for exmode. - Introduce `:exmode`. - Introduce `[count]q:` as an alias to `:exmode`.
* refactor(exmode): Ex-mode as cmdwin + Lua #40991Justin M. Keyes2026-07-27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: POSIX-compatible Ex-mode requires special-cases all over the codebase to match various quirks that don't actually matter to users. - The main utility of *interactive* Ex-mode is its REPL behavior, and that can be achieved with `cmdwin`, which also gains extra UX benefits. - The main utility of *non-interactive* `nvim -es` is for shell scripting, where Ex-mode quirks are mostly unhelpful (e.g. the "Entering Ex mode" message). Solution: - Reimplement *interactive* Ex-mode as a "persistent, insert-mode cmdwin" in Lua. - "nvim -e/-E" is simply an alias to "gQ". - Reframe *non-interactive* Ex-mode (`nvim -es`) as "script mode". - Drop POSIX Ex-mode quirks. Improvements: - "nvim -V1 -es" output ends with a final newline! - "nvim -V1 -es" no longer shows the "Entering Ex mode" msg. (This was pointless noise, unwanted for scripting purposes.) - stdin is no longer typeahead. Scripts (":lua io.read()") can read stdin as data. - Empty line is a no-op: a stray blank line no longer moves the cursor (deviates from POSIX ex "+1"), no longer exits 1 at EOF (E501). Preserved behavior: - cursor starts at "$" - mode()=="cv" (for non-interactive) - multiline commands (:append/:function/heredoc pull continuation lines) - bare-range print - :print=>stdout - -V1=>stderr - CRLF input - continue-after-error and exit codes Dropped (regressed) POSIX behavior (non-interactive): - Event loop only ticks while/between commands, not while blocked waiting for a stdin line. - ":g/pat/visual...Q" - input()/getchar()/":s/x/y/c" no longer consume stdin lines as answers: Nvim stops at end-of-input, skipping the rest of the script, exit 0. Use ":lua io.read()" instead. - If users care about this they should use interactive Ex-mode (`gQ`). - ":@r" stops at end of the register instead of continuing to read cmdline input from stdin.
* test(harness): migrate away from magic globalsJustin M. Keyes2026-07-21
| | | | | | | | | | | | | | | | | | | | | Problem: The magic globals `it`, `describe`, etc., are more trouble than they are worth. - Hooking into `after_each` requires `getfenv()` hacks. - They confuse luals/emmylua, because the top-level `.luarc.json` isn't merged with `test/.luarc.json` (apparently a luals limitation?) - They totally defeat discoverability because the user just has to "know" about the various magic symbols. So they harm DX, which means they serve no purpose at all. Solution: - Expose the test API from `testutil`, so tests can call `t.it()`, `t.describe()`, etc., in the conventional way. - Drop `getfenv()` hacks. - Drop the `setfenv()` injection in `load_chunk`. - Drop `test/_meta.lua`.
* fix(path): normalize separators (slashes) #39155tao2026-07-12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Continue separators normalization, and try to keep it at the nvim <-> external boundary, e.g., `fn.xxx`, `api.xxx`, `:xxx` Solution: some key changes - normalize `$HOME-windows` - normalize entry points of changing directory - `nvim_set_current_dir()`, `chdir()` - normalize the named pipe - `--listen` arg, `--server` arg, `:restart` - `serverstart()`, `sockconnect()`, `serverstop()` - make `expand()` respect 'shellslash' again - clean up `did_set_shellslash` - replace `forward_slash` with `TO_SLASH` - remove obsolete `TMP_PATHSEPSTR` - remove `slash_adjust` in `do_autocmd_dirchanged`? - make `fnamemodify()` always return `/` (except when substituting separators via `:s`, `:gs` ?) Note: - these funcs still apply `slash_adjust` on return, as before: `:pwd`, `chdir()`, `exepath()`, `getcwd()` - these funcs alwarys return `/`, unlike before the normalization PRs - `getcompletion()`, `finddir()`, `findfile()` Also - clean up code, comments, formatting and tests - move `TO_SLASH` from `f_chdir` to `changedir_func` - move `TO_SLASH` from `f_bufadd` to `buflist_new` Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
* fix(lua): reject process exit in fast callbacks #39937Barrett Ruth2026-06-27
| | | | | | | | | | | | Problem: `os.exit()` in `nvim -l` exits through normal teardown. But, as #39783 shows, when it is called from a libuv callback, teardown polling the main loop when inside `uv_run()` can trip the recursive poll guard and cause a crash. Fast callbacks are not safe to teardown, so it's better to schedule an exit out of a callback rather than convolutedly handle this as I tried before. Solution: Reject `os.exit()` from fast callbacks with `E5560` error.
* refactor(test): move swapfile testJustin M. Keyes2026-06-20
|
* fix(path): open swapfile when using device path #39982tao2026-06-16
| | | | | | | | | | | | | Problem: Can't open swapfile when using a device path starting with `//?/`, because `?` is a reserved char on Widnows. Solution: For device UNC paths, replace `//?/UNC/` and `//./UNC/` with `//`. For other device paths, just strip their prefix (i.e. `//?/`, `//./`). This aligns swapfile naming for device paths with regular UNC and DOS paths. Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
* refactor: introduce nvim_on internally #39883Justin M. Keyes2026-05-20
| | | | | | | | | Problem: `nvim_create_autocmd` is too verbose and its `callback` requires extra "nesting". Solution: Introduce `nvim_on`. Start using it internally. Then we can get a feel for how it should look before making it public.
* fix(messages): avoid recursive rtp build due to msg_show #39888luukvbaal2026-05-20
| | | | | | Problem: If there are pending messages when starting to build the runtime search path, a msg_show callback may invoke runtime_search_path_validate() recursively. Solution: Avoid msg_show callback by ensuring messages are flushed.
* test: run Lua harness with nvim -lLewis Russell2026-05-13
| | | | | | | | | | | | | | | | | | Problem: The Lua test harness still ran through standalone -ll mode, so tests depended on the low-level Lua path instead of the regular Nvim Lua environment. That also meant os.exit() coverage had to carry an ASAN workaround because Lua's raw process exit skipped Nvim teardown and let LeakSanitizer interfere with the observed exit code. Solution: Run the harness and related fixtures with nvim -l. Patch os.exit() in the main Lua state to exit through getout(), so scripts observe normal Nvim shutdown while standalone -ll remains available for generator-style scripts. As a consequence, the startup test can assert os.exit() without disabling leak detection. AI-assisted: Codex
* fix(path): normalize path slashes on Windows #37729tao2026-04-24
| | | | | | | | | | | | | | | | | | | | Problem: On Windows, path separators may become inconsistent for various reasons, which makes normalization quite painful. Solution: Normalize paths to `/` at the entry boundaries and always use it internally, converting back only in rare cases where `\` is really needed (e.g. cmd.exe/bat scripts?). This is the first commit in a series of incremental steps. Note: * some funcs won't respect shellslash. e.g. `expand/fnamemodify` * some funcs still respect shellslash, but will be updated in a follow PR. e.g. `ex_pwd/f_chdir/f_getcwd` * uv's built-in funcs always return `\`. e.g. `uv.cwd/uv.exepath` Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
* fix(trust): always use "/" slashes in filepaths #39355Justin M. Keyes2026-04-24
| | | | | | | | Problem: We should not use "\" (backslashes) except where absolutely required. See references in https://github.com/neovim/neovim/pull/37729 Solution: There is no reason to use "\" slashes in the trust db, so don't.
* test: include test path in summary (#39141)zeertzjq2026-04-17
| | | Ref: https://github.com/neovim/neovim/pull/38486#discussion_r3088483987
* fix(:restart): formalize restart event #35223Sathya Pramodh2026-03-28
| | | | | | | | | | | | | | | | | | | Problem: The "restart" event has some problems: - all UI clients must implement a somewhat complex set of setups - UI must be on the same machine as the server - only works for the "current" UI - race/edge case: If the user config has errors / waiting for input, are all UIs able to attach while Nvim is waiting for input? Solution: - Perform the restart on the server, not the client. - Pass listen address (instead of CLI args) in the UI event. - Simplifies UI logic: they only need to attach to new address. - Opens the door for more enhancements in the future, such as allowing all UIs to reattach instead of only the "current" UI. Co-authored-by: zeertzjq <zeertzjq@outlook.com> Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
* fix(lua): extra CR (\r) in `nvim -l` output #38048Commrade Goad2026-03-10
| | | | | | | | | | | | | | | | | Problem: `nvim -l` prints an extra `\r` to stdout: :=vim.system({'cmd', '/c', "echo print(1) | nvim -l -"}, {}):wait() { code = 0, signal = 0, stderr = "1\r\r\n", stdout = "" } Solution: Check `headless_mode` in `msg_use_crlf`. Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
* feat(terminal): surface exit code via virttext + nvim_get_chan_info #37987Ayaan2026-03-10
| | | | | | | | | | Problem: When a terminal process exits, "[Process Exited]" text is added to the buffer contents. Solution: - Return `exitcode` field from `nvim_get_chan_info`. - Show it in the default 'statusline'. - Show exitcode as virtual text in the terminal buffer.
* Merge pull request #37722 from bfredl/fastpackaddbfredl2026-02-26
|\ | | | | perf(runtime): hardware accelerated "packadd opt_package"
| * perf(runtime): hardware accelerated "packadd opt_package"bfredl2026-02-25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | fixes #37586 when doing `packadd mypackage` up to two exact paths are added to &rtp. Instead of recalculating runtime_search_path from scratch, we can "just" splice these two paths in This is simple in theory, but get complicated in practice as "after" dirs do exist and need some wrangling. Echasnovski did some benchmarking, to show that this reduces overhead of a init.lua configuration style where separate `packadd!` calls are used spread out during the config. In addition, "batched" addition (either using "start" packages or packadd! a lot of opt packages at once) does not regress. A theoretical simplification could be to NEVER explicitly add "after" dirs to &rtp, but implicitly add all existing "after" dirs in reverse order when calculating the effective run time path. This might be tricky to do without breaking 12 tpope plugins again tho. We might also instead consider solutions where &rtp remains fully expanded but no longer is the main source of truth. But this is all post 0.12 work. This PR is an alright stopgap to make 0.12 fully support intended use cases of vim.pack.add() .
* | refactor(test): simplify v:argf tests #38055Justin M. Keyes2026-02-25
|/
* feat(startup): provide v:argf for file arguments #35889Sanzhar Kuandyk2026-02-25
| | | | | | | | | | | | | | | | | | Problem: - `:args` and `argv()` can change after startup. - `v:arg` includes options/commands, not just files. - Plugins (e.g. Oil) may rewrite directory args. Solution: - New read-only var `v:argf`: snapshot of file/dir args at startup. - Unaffected by `:args` or plugins. - Unlike `v:argv`, excludes options/commands. - Paths are resolved to absolute paths when possible Example: nvim file1.txt dir1 file2.txt :echo v:argf " ['/home/user/project/file1.txt', '/home/user/project/dir1', '/home/user/project/file2.txt']
* test: start test runners in Xtest_xdg dir (#37964)zeertzjq2026-02-20
| | | | | | | | | | | | | | This is a better way to prevent parallel tests from interfering with each other, as there are many ways files can be created and deleted in tests, so enforcing different file names is hard. Using $TMPDIR can also work in most cases, but 'backipskip' etc. have special defaults for $TMPDIR. Symlink runtime/, src/, test/ and README.md to Xtest_xdg dir to make tests more convenient (and symlinking test/ is required for busted). Also, use README.md instead of test/README.md in the Ex mode inccommand test, as test/README.md no longer contains 'N' char.
* fix(highlight): refresh highlight attrs before message output #25737glepnir2026-02-17
| | | | | | | | | | | | Problem: When MsgArea highlight is changed, the next message may flash and disappear because msg_start() renders with stale highlight attributes. msg_puts_len() uses HL_ATTR(HLF_MSG) to render message text, which happens before update_screen() calls highlight_changed(). So the message is rendered with outdated attrs. Solution: Call highlight_changed() in msg_start().
* fix(terminal): handle opening terminal on unloaded buffer (#37894)zeertzjq2026-02-16
| | | | | | | | | | | Problem: Strange behavior when opening terminal on unloaded buffer. Solution: For nvim_open_term() ensure the buffer is loaded as it needs to be read into the terminal. For jobstart() just open the memfile as the file content isn't needed. Not going to make nvim_open_term() pass stdin to the terminal when stdin isn't read into a buffer yet, as other APIs don't read stdin on unloaded buffer either. There are also other problems with loading buffer before reading stdin, so it's better to address those in another PR.
* Merge #37424 $XDG_CONFIG_DIRS with init.lua, $NVIM_APPNAMEJustin M. Keyes2026-02-06
|\
| * fix(startup): respect $NVIM_APPNAME in $XDG_CONFIG_DIRS pathsJesse van der Pluijm2026-02-06
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: $NVIM_APPNAME was not respected when searching $XDG_CONFIG_DIRS for config files. Nvim hardcoded "nvim" when constructing paths like `$XDG_CONFIG_DIRS/nvim/init.lua`, ignoring the $NVIM_APPNAME environment variable. This meant that config files like `$XDG_CONFIG_DIRS/myapp/init.lua` were not loaded, even though $NVIM_APPNAME was set to "myapp". Solution: Use `get_appname()` instead of hardcoded "nvim" for $XDG_CONFIG_DIRS paths in `do_system_initialization()` and `do_user_initialization()`. This makes $XDG_CONFIG_DIRS behave consistently with $XDG_CONFIG_HOME, which already respected $NVIM_APPNAME. As documented in `runtime/doc/starting.txt` (L1440-L1441): "In the help wherever `$XDG_CONFIG_…/nvim` is mentioned it is understood as `$XDG_CONFIG_…/$NVIM_APPNAME`." See: https://github.com/neovim/neovim/blob/43339dee40aa7731cc644315c15080e30aa1a67c/runtime/doc/starting.txt#L1440-L1441 Relates to #37405
| * fix(startup): source init.lua from XDG_CONFIG_DIRSJesse van der Pluijm2026-02-06
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: `init.lua` files in `$XDG_CONFIG_DIRS` directories were not being sourced during startup, even though the documentation states they should be searched alongside `init.vim`. See: https://github.com/neovim/neovim/blob/e51f5e17e18429b847be4e0d99698727dec47ca9/runtime/doc/starting.txt#L495-L496 Solution: Modify `do_user_initialization()` to search for `init.lua` in each `$XDG_CONFIG_DIRS` directory before falling back to `init.vim`, matching the behavior for `$XDG_CONFIG_HOME`. Also show `E5422` error if both `init.lua` and `init.vim` exist in the same directory. Fixes #37405
* | ci(test): bump Windows runners to windows-2025 and unskip tests (#37666)zeertzjq2026-02-03
|/ | | | Bumping to windows-2025 seems to fix at least one case of spaces having wrong attributes in TUI tests, which allow unskipping dozens of tests.
* build: ship "_core/*" as bytecode (built-into Nvim binary)Justin M. Keyes2025-12-30
| | | | | | | | | | | | | | | | | | | | | | | | | | Problem: We want to encourage implementing core features in Lua instead of C, but it's clumsy because: - Core Lua code (built into `nvim` so it is available even if VIMRUNTIME is missing/invalid) requires manually updating CMakeLists.txt, or stuffing it into `_editor.lua`. - Core Lua modules are not organized similar to C modules, `_editor.lua` is getting too big. Solution: - Introduce `_core/` where core Lua code can live. All Lua modules added there will automatically be included as bytecode in the `nvim` binary. - Move these core modules into `_core/*`: ``` _defaults.lua _editor.lua _options.lua _system.lua shared.lua ``` TODO: - Move `_extui/ => _core/ui2/`
* test(messages): skip os_delay during testsJustin M. Keyes2025-12-20
| | | | | | | | | | | Problem: Tests that trigger `os_delay` messages may take 1-3 seconds, wasting build/CI time, since this serves no purpose in tests. Solution: - Introduce `msg_delay` for cases where `os_delay` is being used as a "UI feature". - Skip `msg_delay` in tests.
* fix(lua): don't remove first char of non-file stacktrace source (#37008)zeertzjq2025-12-18
|
* fix(input): don't exit on EOF when peeking for input with -es (#36948)zeertzjq2025-12-15
| | | Only exit on EOF when doing a blocking wait for input.
* fix(startup): crash in read_stdin #35699Cameron Ring2025-09-10
| | | | | | | | | Problem: Crash on startup in some situations due to call to `set_curbuf` with the current value of `cur_buf`. Solution: Switch buffers before doing the wipeout of the stdin buffer. Use cmdline cmds instead of raw buffer pointers to avoid lifetime issues.
* fix(diff): set default diff flags properly (#35450)zeertzjq2025-08-24
|
* fix(startup): file buf is lost if stdin is empty and "-" is last #35402Cameron Ring2025-08-20
| | | | | | | | | Problem: Running `echo dummy | nvim file1 file2` closes the file1 buffer if file1 doesn't exist. Solution: Logic changed in 43e8ec9 such that stdin buffer may now be created *after* file args. Handle that case.
* fix(messages): 'exrc' / secure messagesJustin M. Keyes2025-07-28
|
* feat(exrc): user must view and explicitly run ":trust" #35069nyngwang2025-07-28
| | | | | | | | | Problem: It's relatively easy to mispress key `a` to (a)llow arbitrary execution of 'exrc' files. #35050 Solution: - For exrc files (not directories), remove "allow" menu item. Require the user to "view" and then explicitly `:trust` the file.
* test(exrc): lua exrc knows its location #34713Yochem van Rosmalen2025-07-01
| | | Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
* fix(startup): make startup windows if there are only floating windows (#34349)luukvbaal2025-06-07
| | | | | | Problem: If user init creates a floating window, startup windows (e.g. to accomodate arglist files) are no longer created. Solution: Check that firstwin->w_next is not floating when deciding whether to make startup windows.
* fix(eval): winnr('$') counts non-current hidden/unfocusable windows #34207luukvbaal2025-06-01
| | | | | | | | | | | Problem: Non-visible/focusable windows are assigned a window number, whereas commands that use this window number skip over them. Solution: Skip over non-visible/focusable windows when computing the window number, unless it is made the current window through the API in which case an identifiable window number is still useful. This also ensures it matches the window number of the window entered by `<winnr>wincmd w` since 403fcacf.
* feat(exrc): stop searching in parent directories by unsetting 'exrc'Yochem van Rosmalen2025-05-20
| | | | | | | | | | Problem: No way for a user to limit 'exrc' search in parent directories (compare editorconfig.root). Solution: A configuration file can unset 'exrc', disabling the search for its parent directories.
* feat(exrc): search in parent directories (#33889)Yochem van Rosmalen2025-05-11
| | | | | | | | | | feat(exrc): search exrc in parent directories Problem: `.nvim.lua` is only loaded from current directory, which is not flexible when working from a subfolder of the project. Solution: Also search parent directories for configuration file.
* feat(messages): cleanup Lua error messagesJustin M. Keyes2025-05-04
| | | | | "Error" in error messages is redundant. Just provide the context, don't say "Error ...".
* "nvim -es": disable shada #21723Justin M. Keyes2025-01-05
| | | | | | | | | | | | | | | | | | | | | | | | | | | | 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