Commit Graph

4336 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
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
Yochem van Rosmalen
4a4de73043 fix(help): better align local-additions #38097
Problem:
Descriptions of plugins often contain taglinks which are generally
concealed. This misaligns them by 2 characters with descriptions that
don't have a taglink in them.

Solution:
Don't count "bar" characters (`|`) for the description width.

Example:

Actual buffer content:
```
myplugin.txt                  |lsp| is cool
myplugin.txt        this is a nice plugin
```

Rendered as:
```
myplugin.txt                  lsp is cool
myplugin.txt        this is a nice plugin
```
2026-02-27 17:50:51 -05: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
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
7852993f49 vim-patch:9.2.0061: Not possible to know when a session will be loaded (#38071)
Problem:  Not possible to know when a session will be loaded.
Solution: Add the SessionLoadPre autocommand (Colin Kennedy).

fixes:  vim/vim#19084
closes: vim/vim#19306

1c0d468d72

Co-authored-by: Colin Kennedy <colinvfx@gmail.com>
2026-02-26 21:30:44 +08:00
anondeveg
6ba32713ad feat(secure): allow 'path' parameter for trust action 'allow' (#38001) 2026-02-25 20:55:05 -06:00
Mathias Fußenegger
583308f599 fix(diagnostic): handle stale diagnostic extmark ids #38060
Problem:
If a server is slow with catching up, there can be stale diagnostics
for deleted lines. Then if a user uses `jump` it can error like:

    E5108: Lua: ...runtime/lua/vim/diagnostic.lua:670: attempt to index a nil value
    stack traceback:
            ...runtime/lua/vim/diagnostic.lua:670: in function 'get_logical_pos'
            ...runtime/lua/vim/diagnostic.lua:687: in function 'diagnostic_lines'
            ...runtime/lua/vim/diagnostic.lua:1122: in function 'next_diagnostic'
            ...runtime/lua/vim/diagnostic.lua:1665: in function 'jump'

Solution:
Fallback to diagnostic location. That's better than the failure.
2026-02-25 13:26:56 -05: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
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
zeertzjq
327dcb8970 vim-patch:9.2.0046: filetype: neon files are not recoginzed (#38049)
Problem:  filetype: neon files are not recoginzed
Solution: Detect *.neon files as neon filetype
          (przepompownia)

Reference:
https://doc.nette.org/en/neon/format
https://github.com/fpob/nette.vim

closes: vim/vim#19496

ddd90672f2

Co-authored-by: przepompownia <przepompownia@users.noreply.github.com>
2026-02-25 07:53:43 +08: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
Oleksandr Chekhovskyi
d9d8c660fd fix(watch): invalid joined path #37973
Problem:
When vim._watch.watch() is used to watch a single file, libuv returns
the basename as the filename argument in the callback. The code joins
this with the watched path, producing a nonsensical path like
"/path/to/file.lua/file.lua", which causes ENOTDIR errors on
subsequent fs_stat calls.

Solution:
Check whether the watched path is a directory before joining the
filename. When watching a file, ignore the filename from libuv and
use the watched path directly.
2026-02-23 17:33:13 -05:00
Andrew Braxton
eb90f5d9e3 fix(lsp): only resolve LSP configs once (#38007)
`lsp.config[]` resolves an LSP config the first time it is called, and
returns the cached result on subsequent calls.

The change in #37571 added an extra call to `lsp.config[]` which will
resolve the config *before* the server is added to `_enabled_configs`,
meaning the result is discarded. That means configs will be needlessly
resolved again once `lsp_enable_callback` fires for the first time. That
includes an additional `loadfile()` call which is relatively expensive
and can have unexpected side effects.

Avoid this by storing the result of the initial call to `lsp.config[]`
in `_enabled_configs` so the config is not resolved a second time once
`lsp_enable_callback` is called for the first time.
2026-02-23 11:15:53 -08:00
glepnir
1ec74fa7b1 fix(api): win_config border type #38030
Problem: ArrayOf(String) doesn't cover mixed string/array border chars.

Solution: use Union(Array, Enum(...)) to match parse_border_style behavior.
2026-02-23 11:23:46 -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
Sean Dewar
2478a7fbbd docs(api): nvim_open_win "split" with negative "win" #38032
Acts like :topleft/botright.
2026-02-23 10:10:20 -05:00
Justin M. Keyes
ce5c7111f4 refactor: defer_fn return type #37999 2026-02-23 03:24:14 -05:00
Justin M. Keyes
61678811d8 fix(health): check more "old" files #38028 2026-02-23 03:20:37 -05: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
Justin M. Keyes
4648d89d50 docs: highlight, terminal SGR #37998 2026-02-21 14:52:13 -05:00
zeertzjq
30d9970cd7 vim-patch:9.2.0036: completion: thesaurus completion incorrect with "longest/fuzzy" (#37996)
Problem:  completion: thesaurus completion incorrect with
          "longest/fuzzy" (Mao-Yining)
Solution: Disable fuzzy matching and longest-match insertion
          specifically for thesaurus completion (Girish Palya).

fixes:  vim/vim#19356
closes: vim/vim#19475

26a3f486cc

Co-authored-by: Girish Palya <girishji@gmail.com>
2026-02-21 19:54:25 +08: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
93a8acb1b8 vim-patch:9.2.0033: filetype: sh filetype used for env files
Problem:  filetype: sh filetype used for env files
Solution: Detect *.env and .env.* files as env filetype,
          detect .envrc and .envrc.* as sh filetype,
          include a simple env syntax script (DuckAfire)

Previously, .env files were handled by the shell syntax. While
functional, this limited the ability to support specific .env
implementations, such as CodeIgniter4 which allows dots in keys
(e.g., "foo.bar=0").

The new dedicated 'env' filetype and syntax script improves legibility
and prevents highlighting from breaking when encountering spaces.
Currently, the syntax does not support indentation; fields, variables,
and comments must start at the beginning of the line.

closes: vim/vim#19260

d0fa375629

Co-authored-by: DuckAfire <155199080+duckafire@users.noreply.github.com>
2026-02-20 09:26:07 +08:00
zeertzjq
c78e276881 vim-patch:9.2.0027: filetype: yara files are not recognized
Problem:  filetype: yara files are not recognized
Solution: Detect *.yara and *.yar files as yara filetype
          (Thomas Dupuy).

Reference:
- https://github.com/VirusTotal/yara
- https://github.com/VirusTotal/yara-x

closes: vim/vim#19460

7d93ae57f0

Co-authored-by: Thomas Dupuy <thom4s.d@gmail.com>
2026-02-20 09:17:46 +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
Evgeni Chasnovski
9567fb0507 fix(defaults): silent gx if no textDocument/documentLink support #37969
Problem: If buffer has attached LSP servers and none of them supports
  `textDocument/documentLink` method, typing `gx` results in a warning
  about that.

Solution: Explicitly check that at least one server supports the target
  method before making the LSP request.
2026-02-19 06:59:00 -05:00
zeertzjq
e98a6979ee vim-patch:9.2.0025: filetype: cshtml incorrectly recognized (#37957)
Problem:  filetype: cshtml incorrectly recognized, razor files are not
          recognized
Solution: Detect *.cshtml and *.razor files as razor filetype
          (tris203)

Reference:
https://learn.microsoft.com/en-us/aspnet/core/mvc/views/razor?view=aspnetcore-10.0

closes: vim/vim#19207

68dbb58d51

Co-authored-by: tris203 <admin@snappeh.com>
2026-02-19 02:46:27 +00:00
Maria Solano
c3589753a0 fix(lsp): add vim.deprecate call to vim.lsp.with (#37960) 2026-02-18 18:16:03 -08:00
Maria Solano
6fe68abdf5 fix(lsp): use entire line as completion word (#37949) 2026-02-18 11:40:34 -08:00
Olivia Kinnear
6bb6b47933 fix(lsp): wait to display exit message #37925 2026-02-18 03:03:20 -05:00
Rahul Yedida
9492df027d fix(defaults): 'guifont' "monospace" fallback, trim spaces #37930
Problem:
Some UI clients break if space follows the comma in 'guifont' items.
Also the new 'guifont' default may cause problems if none of the fonts are found.

Solution:
Remove trailing whitespace. 
Add a "monospace" fallback which `fontconfig` can resolve on *nix systems.
2026-02-18 01:57:59 -05: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
luukvbaal
e268760e46 feat(ui2): show active paging keys in dialog float title #37919
Problem:  Paging keys being consumed without obvious indicator
          in the dialog window can be surprising.
Solution: Display a hint with paging keys in the dialog window title
          when paging is active. Recognize <Esc> as mapping to stop
          paging.
2026-02-17 07:28:56 -05:00
luukvbaal
16495e6863 fix(ui2): only set dialog on_key callback once #37905
Problem:  vim.on_key() called for each message while cmdline is open.
          Cursor is on a seemingly random column when pager is entered.
          Entering the pager while the cmdline is expanded can be more
          convenient than pressing "g<".
          Pager window is unnecessarily clamped to half the shell height.
          Setting 'laststatus' while pager is open does not adjust its
          dimensions.
Solution: Only call vim.on_key() once when dialog window is opened.
          Ensure cursor is at the start of the first message when
          entering the pager.
          Enter the pager window when "<CR>" is pressed while the
          cmdline is expanded.
          Don't clamp the pager window height.
          Set message windows dimensions when 'laststatus' changes.
2026-02-16 17:11:32 -05:00
Tristan Knight
13cf80deef fix(lsp): map all LSP methods to server capabilities (#37910) 2026-02-16 13:20:34 -08:00
Maria Solano
05bd4398c5 feat(lsp): support textDocument/documentLink (#37644) 2026-02-16 11:05:33 -08:00
Maria Solano
6e1745e96e feat(lua): support vim.Range:has(vim.pos) #37879 2026-02-16 11:05:38 -05:00
Rahul Yedida
249f305bbc feat(defaults): per-platform 'guifont' default #37175
Problem:
Font rendering and kerning are subpar in GUIs.

Solution:
Set default 'guifont' based on common CSS fonts per:
https://github.com/system-fonts/modern-font-stacks#monospace-code
2026-02-16 09:05:23 -05:00
zeertzjq
cbec4603a0 vim-patch:partial:9.1.1668: items() does not work for Blobs
Problem:  items() does not work for Blobs
Solution: Extend items() to support Blob
          (Yegappan Lakshmanan).

closes: vim/vim#18080

da34f84847

Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
2026-02-16 21:17:02 +08:00
zeertzjq
b51fc202ce vim-patch:3de7384: runtime(doc): Fix :help complete() example (#37891)
closes: vim/vim#18417

3de73844af

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2026-02-16 14:31:51 +08:00
Riley Bruins
4719b94443 feat(statusline): option to specify stacking highlight groups #37153
**Problem:** No easy way to stack highlight groups #35806.

**Solution:** Add a way to specify a new statusline chunk with a
highlight group that inherits from previous highlight attributes.

Also applies to tabline, etc.
2026-02-15 12:16:51 -05:00
Tim Pope
a1895f024a fix(lsp): support workspace/configuation with no section #27510
The [spec for `workspace/configuration`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_configuration)
marks the `section` property of each item in `items` optional.
Therefore, I believe it violates the spec to skip over items without
a section, because then the length of the results won't match the length
of a valid `items` input. The spec does not elaborate on _what_ to
return in this case, but I don't think it would be controversial to say
that returning the full configuration, as done for an empty string, is
the most natural interpretation.

That empty string case, by the way, was initially [added in
response](5da124fc82)
to a real world implementation requesting it. I don't have a similar
real world implementation to point to for the omitted `section`, but
I would note that `getConfiguration()` from `vscode-languageserver-node`
[defaults to a request with no section](d859bb14d1/server/src/common/configuration.ts (L24-L26))
when called with no arguments. I surmise that this is intended as a way
to retrieve the full configuration.
2026-02-15 11:37:24 -05:00
phanium
5c4b64aae5 fix(lsp): wait for exit_timeout on quit #37597
Problem:
When quitting Nvim, LSP servers will not be force-stopped, even if
ClientConfig.exit_timeout is set to an integer.

    pkill emmylua_ls; VIMRUNTIME=runtime/ nvim --clean -u repro.lua repro.lua ; waitpid $(pgrep emmylua_ls)

    vim.lsp.config('foo', { cmd = { 'emmylua_ls' }, exit_timeout = 1000 })
    vim.lsp.enable('foo')
    vim.defer_fn(vim.cmd.quit, 500)

Solution:
On VimExit, wait up to `exit_timeout:integer` milliseconds for servers
to exit. Do this with an explicit `vim.wait()`, because the actual
force-stop is deferred, and won't be attempted if Nvim exits before
then.

Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2026-02-15 07:33:49 -05:00
Tristan Knight
b99cdd08de refactor(lsp): centralize provider capability resolution #37221
- Refactor LSP client to use unified provider-based capability lookup for
  diagnostics and other features.
- Introduce `_provider_value_get` to abstract capability retrieval,
  supporting both static and dynamic registrations.
- Update diagnostic handling and protocol mappings to leverage
  provider-centric logic.
2026-02-14 10:50:48 -05:00
Evgeni Chasnovski
539b8027a3 fix(pack): explicitly close confirmation window #37861
Problem: Executing `nvim_buf_delete()` does not guarantee that the
  window which shows the buffer is going to close after `:write` or
  `:quit`. In particular, if there is no listed buffer present.

Solution: Explicitly close the window that was created for confirmation
  buffer. Use `pcall` to catch cases when the window was already closed
  or when it is the last window.
2026-02-14 08:26:36 -05:00
Dmytro Pletenskyi
01666aae64 feat(diagnostic): fromqflist({merge_lines}) #37416
Problem:
`vim.diagnostic.fromqflist` ignores lines that are `item.valid == 0` (see
`getqflist`). Many qflists have messages that span multiple lines, which look
like this:

    collection/src/Modelling/CdOd/Central.hs|496 col 80| error: [GHC-83865]
    ||     • Couldn't match expected type: InstanceWithForm
    ||                                       (FilePath
    ||                                        -> SelectValidCdInstWithForm
    ...

calling `vim.diagnostic.fromqflist(vim.fn.getqflist)` gets a diagnostic message
like this:

    error: [GHC-83865]

only the first line is kept, but often, the remaing lines are useful as well.

Solution:
Introduce `merge_lines` option, which "squashes" lines from invalid qflist items
into the error message of the previous valid item, so that we get this
diagnostic message instead:

    error: [GHC-83865]
         • Couldn't match expected type: InstanceWithForm
                                           (FilePath
                                            -> SelectValidCdInstWithForm
2026-02-14 06:07:01 -05:00
Yochem van Rosmalen
b5ce7e74dc refactor(help): move local-additions to Lua #37831
Problem:
- ~200 line function of hard-to-maintain C code.
- Local Addition section looks messy because of the varying description
  formats.

Solution:
- Move code to Lua.
- Have a best-effort approach where short descriptions are right
  aligned, giving a cleaner look. Long descriptions are untouched.
2026-02-14 05:30:18 -05:00