Commit Graph

7740 Commits

Author SHA1 Message Date
glepnir
3e8a4e1092 feat(lsp): show color preview in completion items #32138
Problem: Color completion items display as plain text without visual preview

Solution: Parse RGB/hex colors from documentation and render with colored symbol ■
2026-02-28 10:02:52 -05:00
Nicknamess96
c1e60f36f3 fix(difftool): don't reset quickfix list when closing quickfix window #38088
Closing the quickfix window previously triggered a WinClosed autocmd
that deleted all difftool autocmds and pushed an empty quickfix list,
making the difftool non-functional. Users who close the quickfix window
to gain screen real estate for viewing diffs had no way to continue
navigating entries.

Remove the qf_win tracking and its associated WinClosed autocmd so that
closing the quickfix window no longer tears down the difftool state.
Closing either diff window still performs full cleanup as before.

The BufWinEnter handler no longer passes with_qf to diff_files, so
navigating entries while the quickfix window is closed reuses the
existing diff layout without forcing a layout rebuild.

Fixes #37388
2026-02-28 09:59:53 -05:00
luukvbaal
32e0d05d53 feat(ui2): configure targets per message kind #38091
Problem:  Unable to configure message targets based on message kind.
Solution: Add cfg.msg.targets mapping message kinds to "cmd/msg/pager".
          Check the configured target when writing the message.
          cfg.msg = { target = 'cmd', targets = { progress = 'msg', list_cmd = 'pager' } }
          will for example use the 'msg' target for progress messages,
          immediately open the pager for 'list_cmd' and use the cmdline
          for all other message kinds.
2026-02-28 08:31:02 -05:00
Sanzhar Kuandyk
b40ca5a01c fix(channel): support :detach, :restart on Windows #37977
fix: allocate hidden console for detached server

Starting the server with UV_PROCESS_DETACHED results in DETACHED_PROCESS, leaving the child without a console. Without a console:

CONIN$ / CONOUT$ cannot resolve, causing channel_from_stdio to fail.

ConPTY cannot attach, breaking :terminal.

This patch allocates a hidden console via AllocConsole() when the server has none, restoring working stdio and enabling ConPTY.

Also updates os_set_cloexec to clear HANDLE_FLAG_INHERIT on the RPC pipe
handles, matching the Unix F_DUPFD_CLOEXEC behavior.
2026-02-28 08:21:13 -05:00
glepnir
5943a81fe7 fix(float): style=minimal leaks into normal windows #25185
Problem: closing a minimal float saves its style-imposed options into
buffer's wininfo, which get picked up by normal windows on :bnext.

Solution: don't save window options to wininfo for style=minimal windows.
2026-02-28 13:20:56 +00:00
Yochem van Rosmalen
dc5d313d66 fix(vim.fs): joinpath() should ignore empty items #38077
Problem:
vim.fs.joinpath treats empty string as a path segment
(it adds a path separator for each empty item):

    print(vim.fs.joinpath('', 'after/lsp', '')) -- '/after/lsp/'
    print(vim.fs.joinpath('', '')) -- '/'

Especially problematic if the empty segment is the first segment, as
that converts the path to an absolute path.

Solution:
Ignore empty (length of 0) path segments.

Benchmark:

    local function test(func)
      local t = vim.uv.hrtime()
      for _ = 1, 100000, 1 do
        func('', 'this/is', 'a/very/long/path', '', 'it', 'really', 'is')
      end
      print(math.floor((vim.uv.hrtime() - t) / 1e6), 'ms')
    end

- with Iter():filter() --> 370 ms
- building new segments table --> 208 ms
- with vim.tbl_filter --> 232 ms
- Instead of gsub split on `/` in all parts --> 1870 ms
2026-02-27 17:45:07 -05:00
Kyle
5cbb9d613b fix(startup): wait for bg detection before user config #37075
Problem:
Automatic background detection sets the background option too late,
which loads colorschemes twice and causes problems when the user's
terminal background doesn't match the default (#32109, #36211, #36416).

Solution:
Use a DA1 query to determine whether the TTY supports OSC 11. Wait for
background detection and setting to complete before processing user
config.

Note: To preserve the existing behavior as much as possible, this triggers
OptionSet manually on VimEnter (since it won't trigger automatically if
we set bg during startup). However, I'm unsure if this behavior is
truly desired given that the documentation says OptionSet is triggered
"After setting an option (except during |startup|)."

Also fixes flickering issue #28667. To check for flickering:

    nvim --clean --cmd "set termguicolors" --cmd "echo \"foo\"" --cmd "sleep 10"

On master, this gives me a black screen for 10 seconds, but on this
branch, the background is dark or light depending on the terminal
background (since the option is now set during startup rather than after
VimEnter).
2026-02-27 04:52:52 -05:00
glepnir
f45c550f4e fix(restart): drop "-s <scriptfile>" from v:argv on :restart #38058
Problem: When nvim is started with "-s -" (read from stdin), ":restart"
drops the "-" argument but keeps "-s", leaving an orphaned "-s" in the
restarted server's argv, causing a crash.

Solution: Drop "-s" and its scriptfile argument when copying v:argv for
the restarted server. Like "-- [files…]", the scriptfile is a one-shot
startup input that should not be replayed on restart
2026-02-27 04:30:45 -05:00
Riccardo Mazzarini
ea5007b37f fix(lps): separate namespaces for pull/push diagnostics #37938
Problem:
Regression from b99cdd0:
Pull diagnostics (from `textDocument/diagnostic`) and push diagnostics
(from `textDocument/publishDiagnostics`) use the same namespace, which
is a problem when using language servers that publish two different sets
of diagnostics on push vs pull, like rust-analyzer (see
https://github.com/rust-lang/rust-analyzer/issues/18709#issuecomment-2551394047).

Solution:
Rename `is_pull` to `pull_id` which accepts a pull namespace instead of
just a boolean.
2026-02-26 12:05:30 -05:00
zeertzjq
34b3bd1ac5 test(treesitter/fold_spec): fix flaky test (#38075) 2026-02-26 21:28:52 +08:00
luukvbaal
e63346dfe9 fix(messages): reset redirection message column at message start #38068
Problem:  Leading message newlines (not emitted with ext_messages since
          4260f73) were responsible for resetting the redirection message
          column (while the newline itself is later pruned...).
Solution: Ensure the redirection column is reset at the start of a message.
          (Instead of re-adjusting all the newline callsites which can
          themselves hopefully be pruned if ext_messages is enabled by
          default.)
2026-02-26 07:45:33 -05:00
bfredl
3a4a7a7efb Merge pull request #37722 from bfredl/fastpackadd
perf(runtime): hardware accelerated "packadd opt_package"
2026-02-26 10:29:49 +01:00
anondeveg
6ba32713ad feat(secure): allow 'path' parameter for trust action 'allow' (#38001) 2026-02-25 20:55:05 -06:00
zeertzjq
e86ccdbeae test: remove remaining use of feed_command() in terminal/ (#38069)
Also deduplicate screen lines in some other tests.
2026-02-26 10:06:34 +08:00
luukvbaal
4ef217e272 fix(ui2): leftover empty lines in msg window #38059
Problem:  Timer removing a message from the msg buffer does not remove
          empty lines if window is closed (col([ui.wins.msg]) fails).
Solution: Use nvim_buf_get_text() to check if line is empty.
2026-02-25 13:21:30 -05:00
Justin M. Keyes
c0f8b3fb66 refactor(test): simplify v:argf tests #38055 2026-02-25 13:06:53 -05:00
zeertzjq
1983c70d10 test(lsp): flaky lsp/semantic_tokens_spec #38063
The wait added in #37853 doesn't seem to do anything as request is sent
immediately on InsertLeave, and the number 4 also seems wrong. Instead,
the actual cause for the flakiness that the feed() (and hence the buffer
change) may arrive before the scheduled initialization of capabilities,
causing there be only only one textDocument/semanticTokens/full request
instead of two.
2026-02-25 13:04:31 -05:00
bfredl
3aa04f7ee4 perf(runtime): hardware accelerated "packadd opt_package"
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() .
2026-02-25 09:39:54 +01:00
Sanzhar Kuandyk
cf874cee33 feat(startup): provide v:argf for file arguments #35889
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']
2026-02-25 03:38:08 -05:00
luukvbaal
844caca881 fix(ui2): multiline/color replaced message, expanded cmdline, error messages #38044
Problem:  - Unintentionally inserting lines for a replaced multiline
          message that also has multiple highlights.
          - Scheduled check to see if the expanded cmdline window was
          entered makes it difficult to keep track of what happens when
          the key pressed to dismiss it results in a message.
          - Reading the first line of an error message should be enough
          notice for something going wrong.
          - "search_cmd" messages should not be shown with 0 'cmdheight'.
          - Unable to configure dynamically changed pager height.
          - Enabling UI2 doesn't make sense with no UIs attached.

Solution: - Only insert a line for the first chunk after a newline.
          - Use getmousepos() to check if the expanded cmdline was
          clicked to enter the pager.
          entering the pager to serve as a configuration interface.
          - Don't expand the cmdline for error messages; user can press g<.
          - Don't show "search_cmd" messages with 'cmdheight' set to 0.
          - Change 'eventignorewin' to ensure WinEnter is fired when
          - Have enable() return early when no UIs are attached.
2026-02-24 17:05:38 -05:00
phanium
16aab4cb48 fix(treesitter): InspectTree only show the largest injection #37906
Problem:
:InspectTree don't show luadoc injection lua file. Since luadoc share
the same "root" with comment in their common primary (lua) tree.
Current logic simply show the largest (comment injection) and ignore all
smaller one (luadoc injection).

Solution:
Handle different lang injections separately. Then sort them by
byte_length to ensure the draw tree consistent.
2026-02-24 16:22:30 -05:00
luukvbaal
39c4e0f336 fix(messages): unwanted ext_messages newlines for confirm() #38045
Problem:  Newlines emitted with ext_messages intended to position
          the message/prompt on the message grid.
Solution: Don't emit these newlines with ext_messages, followup to 4260f73e.
2026-02-24 13:01:31 -05:00
glepnir
3115a18a80 refactor(test): lsp completion spec cleanup #38041
Problem: retry/feed/tbl_map patterns duplicated everywhere, detach check was a false negative

Solution: extract wait_for_pum/extract_word_abbr/word_sorter helpers,
fix assert_cleanup_after_detach with positive+negative pum confirmation
2026-02-24 09:20:58 -05:00
glepnir
5eb1c4df54 refactor(test): avoid deprecated functions #37017
Problem:
Tests are using some deprecated functions.

Solution:
Replace with command, pcall_err, etc.
2026-02-24 07:15:24 -05:00
Sean Dewar
32d3dd0650 fix(statusline): broken statusline on error #38000
Problem: after #33036, an error from evaluating 'statusline' clears it and
doesn't draw the statusline. (causing glitchy redraws)

Solution: use the default value instead. If 'stl' is somehow ever empty, still
call redraw_custom_statusline to at least draw an empty statusline.

Ideally our default 'stl' shouldn't itself error too! :-)
Also adjust some prior screen:expect()s to avoid immediate success warnings.
2026-02-23 11:22:13 -05:00
zeertzjq
f1490b5fe9 test: don't test overriding argv[0] using FFI (#38012)
Instead, test this by adding a new functionality to shell-test, allowing
reuse in other future tests.
2026-02-23 21:43:44 +08:00
zeertzjq
250d77cce7 test(terminal/scrollback_spec): fix flaky test (#38026)
When using feed_data() with hidden buffer, terminal refresh may arrive
during may_restore_curbuf(), causing "last cursor" positions to change.
Get the two "last cursor" positions in the same RPC call.
2026-02-23 13:51:37 +08:00
zeertzjq
ec24746406 test(core/channels_spec): fix flaky test (#38025)
If the last nvim_eval arrives on RPC channel before rpc_close_event() is
processed, it will be scheduled immediately after rpc_close_event() and
before free_channel_event(), causing the test to fail.
2026-02-23 04:26:38 +00:00
zeertzjq
1b013adff3 test(terminal/channel_spec): fix flaky test (#38023)
Adding input doesn't help here, as the important part here is processing
main_loop.events, not running the main loop. Instead, use a non-fast API
request to ensure that previously queued events are processed.
2026-02-23 01:48:15 +00:00
glepnir
f90cd620c5 fix(lsp): vim.lsp.completion clean up triggers on client detach (#38009)
Problem: LspDetach didn't clean up stale client refs in triggers table.

Solution: create LspDetach autocmd and call disable_completion.
2026-02-22 11:43:32 -08:00
wjyoung65
9aa936d892 test(ui): failure in lua/ui_spec.lua in headless OS (no GUI) #37975 2026-02-21 15:00:06 -05:00
Riccardo Mazzarini
cb8c9186e6 feat(highlight): support more SGR attributes #37901
Problem:
TUI does not support several standard SGR text attributes:
- dim/faint (SGR 2)
- blink (SGR 5)
- conceal (SGR 8)
- overline (SGR 53)
This means that when a program running in the embedded terminal emits
one of these escape codes, we drop it and don't surface it to the
outer terminal.

Solution:
- Add support for those attributes.
- Also add corresponding flags to `nvim_set_hl` opts, so users can set
  these attributes in highlight groups.
  - refactor(highlight): widen `HlAttrFlags` from `int16_t` to `int32_t`
    Widen the `rgb_ae_attr` and `cterm_ae_attr` fields in HlAttrs from
    int16_t to int32_t to make room for new highlight attribute flags,
    since there was only one spare bit left.
  - The C flag is named HL_CONCEALED to avoid colliding with the
    existing HL_CONCEAL in syntax.h (which is a syntax group flag, not
    an SGR attribute).
- Also note that libvterm doesn't currently support the dim and overline
  attributes, so e.g. `printf '\e[2mThis should be dim\n'` and `printf
  '\e[53mThis should have an overline\n'` are still not rendered
  correctly when run from the embedded terminal.
2026-02-20 18:35:55 -05:00
zeertzjq
e3d46a6337 test: start test runners in Xtest_xdg dir (#37964)
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.
2026-02-20 06:53:33 +08:00
luukvbaal
2de284e50b fix(message): set replace_last for completion "scanning" messages #37967
Problem:  UIs put ins-completion "scanning" messages one after another,
          which are meant to overwrite the previous message.
Solution: Ensure the msg_show "replace_last" parameter is set.
2026-02-19 16:01:43 -05:00
zeertzjq
dec3c6fa34 test(lsp): fix fake LSP server timeout not working (#37970)
Problem:  Fake LSP server does not timeout or respond to SIGTERM as it
          does not run the event loop.
Solution: Instead of io.read(), use stdioopen()'s on_stdin callback to
          accumulate input and use vim.wait() to wait for input.

Also, in the test suite, don't stop a session when it's not running, as
calling uv.stop() outside uv.run() will instead cause the next uv.run()
to stop immediately, which cancels the next RPC request.
2026-02-19 10:38:14 -08:00
zeertzjq
08f4811061 fix(treesitter): :InspectTree wrong title for non-relative path #37965
Problem:  :InspectTree sets wrong title for file with non-relative path.
Solution: Use full path if relpath() returns nil.
2026-02-19 12:05:48 -05:00
zeertzjq
f0137bf443 test(terminal/channel_spec): fix test still flaky on Windows (#37968)
FAILED   1 test, listed below:
FAILED   test/functional/terminal/channel_spec.lua @ 133: chansend sends lines to terminal channel in proper order
test/functional/terminal\channel_spec.lua:141: retry() attempts: 3
test/functional/terminal\channel_spec.lua:143: Failed to match any screen lines.
Expected (anywhere): "echo "hello".*echo "world""
Actual:
  |^PowerShell 7.4.13                                                                                   |
  |PS D:\a\neovim\neovim> {UNEXPECTED foreground = tonumber('0xffff40'), fg_indexed = true:echo }{UNEXPECTED foreground = tonumber('0x00e0e0'), fg_indexed = true:"hello"}                                                                 |
  |hello                                                                                               |
  |PS D:\a\neovim\neovim> {UNEXPECTED foreground = tonumber('0xffff40'), fg_indexed = true:echo }{UNEXPECTED foreground = tonumber('0x00e0e0'), fg_indexed = true:"world"}                                                                 |
  |{UNEXPECTED foreground = Screen.colors.Gray88, fg_indexed = true:>> }                                                                                                 |
  |world                                                                                               |
  |PS D:\a\neovim\neovim> {UNEXPECTED foreground = tonumber('0xffff40'), fg_indexed = true:echo }{UNEXPECTED foreground = tonumber('0x00e0e0'), fg_indexed = true:"hello"}                                                                 |
  |{UNEXPECTED foreground = Screen.colors.Gray88, fg_indexed = true:>> }                                                                                                 |
  |hello                                                                                               |
  |PS D:\a\neovim\neovim> {UNEXPECTED foreground = tonumber('0xffff40'), fg_indexed = true:echo }{UNEXPECTED foreground = tonumber('0x00e0e0'), fg_indexed = true:"world"}                                                                 |
  |{UNEXPECTED foreground = Screen.colors.Gray88, fg_indexed = true:>> }                                                                                                 |
  |world                                                                                               |
  |PS D:\a\neovim\neovim> {UNEXPECTED foreground = tonumber('0xffff40'), fg_indexed = true:echo }{UNEXPECTED foreground = tonumber('0x00e0e0'), fg_indexed = true:"hello"}                                                                 |
  |{UNEXPECTED foreground = Screen.colors.Gray88, fg_indexed = true:>> }                                                                                                 |
  |hello                                                                                               |
  |PS D:\a\neovim\neovim> {UNEXPECTED foreground = tonumber('0xffff40'), fg_indexed = true:echo }{UNEXPECTED foreground = tonumber('0x00e0e0'), fg_indexed = true:"world"}                                                                 |
  |{UNEXPECTED foreground = Screen.colors.Gray88, fg_indexed = true:>> }                                                                                                 |
  |world                                                                                               |
  |{1:term://D:\a\neovim\neovim//9056:pwsh.exe -nop [-]                                                   }|
  |                                                                                                    |
2026-02-19 19:31:33 +08:00
zeertzjq
2605ce9377 test: fix flaky tests in terminal/{buffer,channel}_spec.lua (#37966)
In buffer_spec.lua, wait for a bit more than the refresh delay.
In channel_spec.lua, retry sending lines on Windows.
2026-02-19 17:57:02 +08:00
zeertzjq
76db55c137 test(ex_cmds/write_spec): don't create files under test/ (#37963) 2026-02-19 06:30:26 +00:00
zeertzjq
ea3942f222 test: remove duplicate test file 078_swapfile_recover_spec.lua (#37961)
This is now covered by Test_swap_file() in test_recover.vim.
2026-02-19 04:14:39 +00:00
Bartłomiej Maryńczak
761fbc155a test(lsp): add entire-line completion word case (#37927)
Problem:
Multiword completion items used to be cut at a first word.

Solution:
Add a test that ensures this does not regress in the future
2026-02-18 13:13:38 -08:00
Justin M. Keyes
0e4fa55200 Merge #37928 prompt-buffer cursor, undo 2026-02-18 14:19:25 -05:00
Justin M. Keyes
abfe6c9ef7 feat(logging): rename ".nvimlog" => "nvim.log" #37935
- Rename ".nvimlog" to "nvim.log"
  - doesn't need to be "hidden"/dotfile
  - ".log" extension helps with filetype detection
- Also rename "nvim/log" => "nvim/nvim.log"
2026-02-18 11:58:34 -05:00
zeertzjq
d23f28cca2 test(win_scrolled_resized_spec): fix flaky test (#37942) 2026-02-18 21:10:22 +08:00
zeertzjq
d0c699ec7b test(screen): fix minimal timeout too small for "intermediate" (#37933)
After #27620 flags.timeout is no longer used as the minimal timeout for
"intermediate", but the default minimal timeout shouldn't be too small.
2026-02-18 19:10:08 +08:00
zeertzjq
a520d9c4ea test: fix test failure causing following tests to fail (#37932) 2026-02-18 17:08:08 +08:00
zeertzjq
496eca22b3 test: support running functionaltests in parallel by directory (#37918)
Define a CMake target for every subdirectory of test/functional that
contains functional tests, and a functionaltest_parallel target that
depends on all those targets, allowing multiple test runners to run in
parallel.

On CI, use at most 2 parallel test runners, as using more may increase
system load and make tests unstable.
2026-02-18 15:56:50 +08:00
Sean Dewar
a5eb023a53 fix(prompt): clear undo when changing/appending prompt
Problem: undoing after the prompt is changed breaks it (and causes init_prompt
to abort it and append a new one), as the undo history contains the old prompt.

Solution: like submitting, clear the undo buffer. Don't do it in init_prompt if
the line was empty; that may not result in a new prompt, and causes commands
like "S" to lose the history.

As u_save, etc. wasn't being called by prompt_setprompt, undoing after it fixes
the prompt usually gave undesirable results anyway.

Remove the added undo_spec.lua test, as its approach no longer works as a repro,
and finding a new one seems fiddly.
2026-02-17 23:43:37 +00:00
Sean Dewar
602cbbe1d9 fix(prompt): prompt_setprompt cursor col adjustment
Problem: prompt_setprompt adjusted cursor col may be negative (<=0 when
1-based), and doesn't check the col of ':

Solution: avoid negative col and adjust correctly if ': col differs from old
prompt's length.
2026-02-17 23:43:05 +00:00
luukvbaal
29a46a11aa fix(ui2): don't change configured message target implicitly #37924
Problem:  Implicitly setting message target when 'cmdheight' changes.
Solution: Just use the user configured target. Support "cmd" target
          with 'cmdheight' set to 0.
2026-02-17 13:12:49 -05:00