36273 Commits

Author SHA1 Message Date
Justin M. Keyes
68ea43cd0c NVIM v0.12.4
Following is a list of commits (fixes/features only) in this release.
See `:help news` in Nvim for release notes.

FEATURES
--------------------------------------------------------------------------------
- fec4045601 lsp: clean up semantic token initialization and debounce #40266
- 55205b3231 lsp: use LspNotify for semantic tokens (#40242)

PERFORMANCE
--------------------------------------------------------------------------------
- fded370b3e lsp: overscan semantic_token range requests #40036
- fa365cedad treesitter: reduce memory usage of _select.lua #40409

FIXES
--------------------------------------------------------------------------------
- e57c37d246 api: nvim_buf_set_text resets changelist to 0 #39965
- ea07b60fb1 api: preserve ArrayOf metadata #40429
- 5ff4e147d0 cmdline: avoid redraw loop after wrapped line #40240
- a0d7e80368 folds: foldcolumn is interrupted for virtual line above nested fold (#39999)
- a4cfded55e health: always set 'modifiable' #40584
- 7fd0f541e7 health: don't check node package via yarn #40572
- 749126de08 highlight: keep guisp underline color in float with 'winblend' #40283
- 5c38490806 lsp: allow specifying bufnr + client_id filter when enabling capabilities #37690
- c81ab6027d lsp: catch another nil buffer state #40285
- bf8d0bef16 lsp: fire LspNotify didChange autocmds after undo/redo #40404
- 41dbb828bd lsp: fix multiline semantic token processing (#40340)
- 3dd3a6ceab lsp: make LspNotify more robust (#40341)
- ecda67662f lsp: refresh codelens despite pending debounce #40177
- 822d96969b lsp: request semantic tokens in BufWinEnter #40513
- fd27246f67 lsp: skip invalid file watcher globs #40376 #40396
- dc6a9170eb lsp: trailing blank line when edit inserts past end of buffer (#40176)
- 93dd8053ee lsp: use LspNotify for document_color (#40575)
- dffacf5c9d man.lua: highlight codeblocks #40310
- 527c7c8c6b messages: "progress" kind for busy messages #39280
- 0b134d8b23 messages: message kind for :recover and swapfile attention #39444
- 304f8ed67a net: set buftype=nofile (again) (#39932)
- f533a17958 pack: do not assert non-nil `stderr` #40544
- 61765b97fe process: avoid inherited stdio for Windows jobs #40074
- ed7acd1391 startup: use `nvim.difftool` for `nvim -d` only for directories #40185
- 83d9b9afca statusline: prevent various buffer overflows with item groups #40219
- c1318ac348 test: support multiple --filter-out #39885
- 2b37c26477 treesitter: incremental selection causes beeps when the bell is enabled #40414
- abaf2a0e93 tui: more compatible way to reset cursor #40234
- 1f82ecf770 tui: patch reset-cursor-style seq regardless of terminfo #40249
- c58e5b73f1 xxd: buffer overread #40236
- 5c75abf790 xxd: signed left-shift overflow in -r mode #40246

VIM PATCHES
--------------------------------------------------------------------------------
- 1b9159a695 9.2.0718: :syn sync without an argument also lists syntax cluster (#40399)
- ad5720eab9 9.2.0735: [security]: arbitrary Ex command execution during C omni-completion (#40441)
- e41b309abe 9.2.0754: repeated completion length lookup in search_for_exact_line (#40511)
- 71343dad79 9.2.0756: Session with multiple tabpages sets 'winminheight' to 0 (#40512)

REFACTOR
--------------------------------------------------------------------------------
- d6476eda40 os: libuv_proc_stdio #40506
stable v0.12.4
2026-07-05 14:05:57 +02:00
Justin M. Keyes
83babc720e Apply suggestion from justinmk 2026-07-05 10:39:22 +00:00
Evgeni Chasnovski
f533a17958 fix(pack): do not assert non-nil stderr #40544
Problem: On some systems `stderr` can be disabled. This results in not
  usable `vim.pack` since it asserted `stderr` to be non-nil.

Solution: Stop asserting non-nil `stderr`. The downside is that
  potential errors are not shown, but this is intentional since `stderr`
  is disabled on system level.

  Still assert non-nil `stdout` as its output is important for
  `vim.pack` to actually do its job. Disabled `stdout` is not something
  that can work with `vim.pack`.

(cherry picked from commit 25d33dd12b)
2026-07-05 10:39:22 +00:00
dqnne
a4cfded55e fix(health): always set 'modifiable' #40584
Problem:
When buffers are by default `nomodifiable`, such as when Nvim starts with
`-M`, the health buffer cannot be updated.

Solution:
Always set `modifiable` before modifying the buffer.

(cherry picked from commit 0f86ea5ed8)
2026-07-05 10:27:04 +00:00
Barrett Ruth
7fd0f541e7 fix(health): don't check node package via yarn #40572
(cherry picked from commit 1aced004ce)
2026-07-04 20:33:10 +00:00
jdrouhard
93dd8053ee fix(lsp): use LspNotify for document_color (#40575)
fix(lsp): use LspNotify for document_color #40571

Problem: The document_color lsp module was already using the capability
framework but was still using raw buffer events to handle requests and
reloading. This means that every keystroke was sending a document_color
request to the server since there was no debounce in the raw handlers.

Solution: Switch to using LspNotify autocmd events. LspNotify fires just
after new document versions are synced with the server and provides a
built in debounce mechanism for changes. It also provides the signal for
when the current state should be cleared (didClose). The detach part is
already handled by the capability framework.

Fixes #39785

(cherry picked from commit 29db6ce84c)
2026-07-04 14:42:45 +00:00
zeertzjq
e41b309abe vim-patch:9.2.0754: repeated completion length lookup in search_for_exact_line (#40511)
Problem:  search_for_exact_line() repeatedly calls ins_compl_len() and
          relies on ternary operator precedence.
Solution: Cache the completion length and parenthesize the ternary
          expression.

closes: vim/vim#20678

ac443b9924

Co-authored-by: glepnir <glephunter@gmail.com>
(cherry picked from commit 3fea2a7fc5)
2026-07-01 00:35:48 +00:00
zeertzjq
71343dad79 vim-patch:9.2.0756: Session with multiple tabpages sets 'winminheight' to 0 (#40512)
Problem:  Session with multiple tabpages sets 'winminheight' to 0.
Solution: Only save 'winminheight' and 'winminwidth' once (zeertzjq).

related: vim/vim#8119
related: neovim/neovim#40493
closes: vim/vim#20673

294dec827d
(cherry picked from commit c040f53dc1)
2026-07-01 00:10:44 +00:00
jdrouhard
822d96969b fix(lsp): request semantic tokens in BufWinEnter #40513
Problem: A previous refactor removed the BufWinEnter autocmd that
initiated a token request. When an LSP server sends a refresh
notification, then buffers that aren't shown in any window lost their
only trigger to request new tokens.

Solution: Add the BufWinEnter autocmd back which simply requests tokens
for all clients attached to the buffer.
2026-06-30 19:15:54 -04:00
Justin M. Keyes
d6476eda40 refactor(os): libuv_proc_stdio #40506
(cherry picked from commit d303617132)
2026-06-30 19:04:59 +00:00
glepnir
e57c37d246 fix(api): nvim_buf_set_text resets changelist to 0 #39965
Problem: changed_lines got a hardcoded 0, so the changelist entry
and '. mark always recorded column 0 instead of where the edit
actually happened.

Solution: pass start_col instead. changelist now tracks the real
column.

(cherry picked from commit 7312df77bb)
2026-06-29 19:01:22 +00:00
Sanzhar Kuandyk
61765b97fe fix(process): avoid inherited stdio for Windows jobs #40074
Problem:
On Windows, channel jobs inherit Nvim's stdio, so a background job
writing to CON (e.g. gutentags) draws onto the TUI and stays until
redraw.

Solution:
Give Windows job stdin/stderr libuv-created pipes (UV_CREATE_PIPE)
instead of inherited fds, so libuv spawns the child with
CREATE_NO_WINDOW and CON writes no longer leak onto the TUI.

(cherry picked from commit 39e9c1754a)
2026-06-29 15:56:30 +00:00
zeertzjq
ad5720eab9 vim-patch:9.2.0735: [security]: arbitrary Ex command execution during C omni-completion (#40441)
Problem:  [security]: With C omni-completion, a crafted tags file can execute
          arbitrary Ex commands when completing a struct/union member
          (cipher-creator)
Solution: Escape the type field before inserting it into the :vimgrep
          pattern so it cannot close the pattern and start a new command
          (Hirohito Higashi).

Github Security Advisory:
https://github.com/vim/vim/security/advisories/GHSA-mf92-v4xw-j45x

6b611b0d15

Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
(cherry picked from commit d844a276bb)
2026-06-27 01:39:24 +00:00
Lewis Russell
ea07b60fb1 fix(api): preserve ArrayOf metadata #40429
ArrayOf metadata existed before the LuaCATS type documentation refactor and is
useful to typed clients consuming api_info().

Keep Tuple metadata normalized to Array, since tuple element types can be mixed,
but preserve ArrayOf(...) for exported API metadata.

Fixes #38734

AI-assisted: Codex
(cherry picked from commit ea0af59854)
2026-06-26 10:14:30 +00:00
Dmytro Meleshko
fa365cedad perf(treesitter): reduce memory usage of _select.lua #40409
Problem:  The table `history` in treesitter/_select.lua stores references
          to previously selected TSNodes, but a TSNode needs to keep its
          whole TSTree alive in memory, which may be kept alive even
          after closing the buffer to which this history corresponds.

Solution: Store just the bits of information from the TSNode we need to
          go back in selection history (the range and ID), without
          referencing the TSNode itself.
(cherry picked from commit bcfc2037ef)
2026-06-25 16:35:51 +00:00
Dmytro Meleshko
2b37c26477 fix(treesitter): incremental selection causes beeps when the bell is enabled #40414
Problem:  The function visual_select() in treesitter/_select.lua is
          executing `:normal! v<Esc>` to ensure that `gv` later goes
          back to character Visual mode, but doing so when mode() is
          already `v` first switches back to the Normal mode, then
          executes <Esc>, which causes a beep.
Solution: Check if the mode() is already `v` and avoid any switching in
          that case.
(cherry picked from commit 9afa8477b3)
2026-06-25 16:02:45 +00:00
Barrett Ruth
fd27246f67 fix(lsp): skip invalid file watcher globs #40376 #40396
Some servers register `workspace/didChangeWatchedFiles` watchers for URI
schemes that cannot be watched locally. Skipping the unsupported glob
and keep the rest of the registration batch active.

(cherry picked from commit 4d9e5acfb5)
2026-06-25 13:43:40 +00:00
Dmytro Meleshko
1b9159a695 vim-patch:9.2.0718: :syn sync without an argument also lists syntax cluster (#40399)
Problem:  :syn sync without an argument also lists every defined cluster
Solution: Fix control flow in syn_cmd_list() so that only the syncing
          items are printed when this function gets called by :syn sync.
          (dmitmel)

closes: vim/vim#20614

f2954c821e
(cherry picked from commit 764e257ae5)
2026-06-25 09:22:02 +00:00
jdrouhard
bf8d0bef16 fix(lsp): fire LspNotify didChange autocmds after undo/redo #40404
Problem: LspNotify autocmds were not being triggered for didChange
requests when being used during undo/redo (and possibly other) actions.
autocmds are blocked when calling on_lines() callbacks while doing the
undo/redo action.

Solution: Defer firing the autocmd until after the action is complete.
This is closer to what existed before, but now there's a check in the
deferred function to only fire the autocmd if the client is still
active and the buffer is still attached, if applicable.

(cherry picked from commit 3c924d13fe)
2026-06-25 08:25:36 +00:00
zeertzjq
6707ad275d test: fix confusing behavior of eq() with context (#40375)
(cherry picked from commit ceaf2baa60)
2026-06-23 10:46:21 +00:00
Justin M. Keyes
3dd3a6ceab backport: fix(lsp): make LspNotify more robust (#40341)
Problem: LspNotify never passed a buffer when executing the autocmds, so
buffer-local LspNotify autocmd subscriptions didn't have the correct buf
in the event metadata. It was also wrapped in a schedule() so the actual
autocmd was delayed until after the event loop.

This could result in the wrong buffer receiving the notification if
multiple LspNotify autocmds with buffer filters were added. Only the
"latest" one would actually receive non-buffer-filtered autocmds, not
the matching one. It also caused listeners to receive the notification
"out of sync" with when the notification is actually sent. If a buffer
is being deleted (which fires a textDocument/didClose notification), the
notification is scheduled and fired after the buffer is already gone.

Solution: For LSP notifications that pertain to a particular buffer, set
it when executing the LspNotify autocmds so the callback functions that
are filtered on that buffer will get the correct notifications and the
metadata buf field will be correct. Additionally, there is no need to
wrap the LspNotify callback in vim.schedule when it can be called inline
when the notification to the rpc server is fired.

This is tested by removing now-unnecessary autocmds from semantic tokens
(InsertEnter and BufWinEnter should no longer be necessary now that
requests are fired by LspNotify). Without this fix, simply modifying a
buffer doesn't actually trigger LspNotify correctly, and the test for
that fails.

(cherry picked from commit 54188fa242)

Co-authored-by: jdrouhard <john@drouhard.dev>
2026-06-20 16:19:02 -04:00
neovim-backports[bot]
41dbb828bd backport: fix(lsp): fix multiline semantic token processing (#40340)
Problem: When multiline semantic token support was introduced, the loop
that finds the end line for a particular token didn't sanitize the token
length sent back by the LSP server. If the server returned an overflowed
length (near uint32 max), neovim would burn cpu and loop for an
extremely long time while trying to find the "end line" represented by
the massively large token, causing neovim to seemingly hang.

Solution: Stop looping once the calculated end_line reaches the actual
last line of the buffer.

Fixes #36257

(cherry picked from commit 6bc6461eac)

Co-authored-by: jdrouhard <john@drouhard.dev>
2026-06-20 13:52:21 -04:00
Justin M. Keyes
aaa85a0149 test: unreliable "with 'statuscolumn' wraps text" #40273
Problem:
flaky test:

    FAILED   ...st_xdg_terminal/test/functional/terminal/window_spec.lua @ 175: :terminal window with 'statuscolumn' wraps text
    ...st_xdg_terminal/test/functional/terminal/window_spec.lua:175: Row 1 did not match.
    Expected:
      |*{121:++ 7  }                                            |
      |*{121:++ 8  }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR|
      |*{121:++ 9  }STUVWXYZ                                    |
      |*{121:++10  }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR|
      |*{121:++11  }STUVWXYZrows: 6, cols: 44                   |
      |*{121:++12  }^                                            |
      |{5:-- TERMINAL --}                                    |
    Actual:
      |*{121:++ 8  }                                            |
      |*{121:++ 9  }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR|
      |*{121:++10  }STUVWXYZ                                    |
      |*{121:++11  }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR|
      |*{121:++12  }STUVWXYZrows: 6, cols: 44                   |
      |*{121:++13  }^                                            |
      |{5:-- TERMINAL --}                                    |

Solution:
Relax the screen test. The `feed_data` + `tty-test` handling is racey;
'statusline' is correctly reporting the line-numbers, and that's all
that matters.

(cherry picked from commit 145b20eb89)
2026-06-20 02:46:12 +00:00
zeertzjq
44ea4cfcc4 test(tui_spec): remove unnecessary job_opts variable (#40334)
This was initially added so that the __NVIM_DETACH environment variable
can be added to the jobs started in this test. That environment variable
is no longer needed, and there is also vim.tbl_extend() that can be used
to add an environment variable to a job anyway.

Also, make a shallow copy of opts.env in setup_child_nvim(), as mutating
the opts.env passed in may mask problems in other tests.

(cherry picked from commit f876fd906e)
2026-06-20 02:32:01 +00:00
Gregory Anders
5c38490806 fix(lsp): allow specifying bufnr + client_id filter when enabling capabilities #37690
Today there is a constraint that these arguments to the enable filter be
mutually exclusive, but I do not know why such a constraint exists (it
is perfectly reasonable to want to enable a capabilility for just one
buffer and just one client).

(cherry picked from commit ed267268b8)
2026-06-20 01:33:47 +00:00
Sam Reynoso
5ff4e147d0 fix(cmdline): avoid redraw loop after wrapped line #40240
Problem:  A wrapped command line and screen width may be redrawn
          repeatedly after calls to `redrawstatus` from lua.

Solution: redrawcmd() redraws the command line, but msg_clr_eos() may
          invalidate cmdline_was_last_drawn during the redraw process.
          Restore cmdline_was_last_drawn when redrawcmd() completes.

Co-authored-by: Sam Reynoso <sam@codeoutpost.com>
Co-authored-by: Luuk van Baal <luukvbaal@gmail.com>
(cherry picked from commit 6be9459d35)
2026-06-19 20:54:40 +00:00
J. Adly
dffacf5c9d fix(man.lua): highlight codeblocks #40310
Problem:
:Man does not syntax highlight codeblocks (injected language).

Analysis:
init_pager() swapped pcall(parse_ref, ref) return values order, so
vim.b.man_sect was set to the manpage name instead of the section
number, so C syntax highlighting did not load.

Solution:
Swap the calls.

(cherry picked from commit 67b3cceaa7)
2026-06-19 00:07:30 +00:00
luukvbaal
0b134d8b23 fix(messages): message kind for :recover and swapfile attention #39444
Problem:  No message kind and multiple events for :recover and
          (non-prompt) swapfile attention messages.
Solution: Assign these the "list_cmd" and "wmsg" kind.
2026-06-17 12:52:51 +00:00
luukvbaal
527c7c8c6b fix(messages): "progress" kind for busy messages #39280
Problem:  The "Scanning:" completion, bufwrite, and indent (there may be
          more) messages which indicate progress can use the "progress" kind
          for their msg_show event. Indent message does not have a kind.

Solution: Emit these messages with the "progress" kind. Set the message id
          to the replaced kind so that a UI knows to replace it (and to provide
          a migration path in case a UI was distinguishing these messages for
          whatever reason).
2026-06-17 12:52:51 +00:00
Steve Huff
c81ab6027d fix(lsp): catch another nil buffer state #40285
(cherry picked from commit 942778c758)
2026-06-17 04:24:16 +00:00
neovim-backports[bot]
fec4045601 backport: feat(lsp): clean up semantic token initialization and debounce #40266
Problem: The refactor to use Capability left around some cruft and
semi-broken configuration for debounce.

Solution: Clean up now-unnecessary helper methods and simplify
deprecated ones to pass through to the non-deprecated ones. `debounce`
now defaults to 200 for all buffers but is overridable via the
deprecated start() method, which continues to take the max value
specified for any client attached to the buffer.

If we wish to expose changing the debounce in a non-deprecated way, we
will need to consider a "configuration" function, or even a bespoke
method to set the debounce time on the main metaclass (or provide
options to override for a particular buffer). General configuration of
specific LSP features is an as-of-yet unsolved problem.

(cherry picked from commit 859790e244)
2026-06-16 16:27:35 -04:00
glepnir
749126de08 fix(highlight): keep guisp underline color in float with 'winblend' #40283
Problem:
A colored (guisp) underline showing through a 'winblend' float
lost its special color and followed the foreground instead.

Solution:
In the blend-through case, blend the underline's special color
only when the cell below sets sp explicitly; otherwise clear it.

(cherry picked from commit 823517ad1d)
2026-06-16 11:54:08 +00:00
Kyle
1f82ecf770 fix(tui): patch reset-cursor-style seq regardless of terminfo #40249
Problem:
Terminfo sucks.

Solution:
Patch Ss/Se (set/reset cursor style) sequences when we know what they
should be.

close #38987

(cherry picked from commit ebc69b387c)
2026-06-15 12:50:00 +00:00
Vadim Misbakh-Soloviov
abaf2a0e93 fix(tui): more compatible way to reset cursor #40234
Problem:
All (tested by me) terminals (xterm, st, ghostty, vte, foot, wezterm, konsole) do support `\x1b[0 q` as "reset cursor to default", but at least konsole and wezterm only understands `\x1b[0 q` as "reset to default", but have different behaviour on `\x1b[ q` (konsole sets "steady block", and wezterm does nothing (do not change cursor shape).

Solution:
Use `\x1b[0 q` would be more widely compatible "reset" sequence than `\x1b[ q`

P.S. actually, `xterm`, `ghostty` and `st` (with default config.h) sets "steady block" for both sequence, but still here `[0` behaves the same as `[`

(cherry picked from commit 224ad8a538)
2026-06-15 00:19:14 +00:00
OrbisAI Security
c58e5b73f1 fix(xxd): buffer overread #40236
Problem
Buffer overflow if lines exceed the expected buffer size.

Solution:
Use snprintf instead of strcpy.

(cherry picked from commit 966e7a98f5)
2026-06-15 00:15:06 +00:00
Justin M. Keyes
5c75abf790 fix(xxd): signed left-shift overflow in -r mode #40246
(AI-assisted)

Problem:
Zig build failing since 966e7a98f5:

    FAILED   ...r/work/neovim/neovim/test/functional/editor/xxd_spec.lua @ 22: xxd handles long lines in revert mode
    Expected values to be equal.
    Expected:
    0
    Actual:
    134
    stack traceback:
    ...r/work/neovim/neovim/test/functional/editor/xxd_spec.lua:26: in function <...r/work/neovim/neovim/test/functional/editor/xxd_spec.lua:22>

`huntype` parses the address column by repeatedly left-shifting
`want_off` (a signed `long`) by 4 bits per hex digit. After 16 hex
digits the value occupies all 64 bits; the next shift moves a non-zero
bit into the sign bit -- signed overflow, i.e. undefined behavior.

This happens on the Zig build because it enables UBSAN. The bug was
pre-existing, but 966e7a98f5 added a test that exercises it.

Solution
Shift through `unsigned long` and cast back to `long`, making the
overflow well-defined wrap-around.

(cherry picked from commit f350e39b77)
2026-06-14 23:59:02 +00:00
neovim-backports[bot]
1d24ca4abb backport: fix(cliff): strip "backport:" prefix from commit subject (#40245)
Problem:
Backport commits may have subjects like "backport: fix(ui): ...".
(e.g. ecda67662f). git-cliff treats them as OTHER.

Solution:
Preprocess the subject to strip a leading "backport:" or "backport ".

(cherry picked from commit 4c3b0ecb46)

Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2026-06-14 13:02:12 -04:00
Justin M. Keyes
55205b3231 backport: feat(lsp): use LspNotify for semantic tokens (#40242)
feat(lsp): use LspNotify for semantic tokens

Problem: The semantic token module is using its own debounce timer for
the buffer on_lines event. If its internal debounce is shorter than the
changetracking module's debounce, it's possible for semantic token
requests to fire for changed buffers before the textDocument/didChange
notification is sent to the server.

Solution: Trigger semantic token requests from the LspNotify autocmd
when the method is the didChange or didOpen notifications, which
enforces a strict happens-before relationship for the sync change
notification followed by a semantic token request.

Note: There is still an internal debounce mechanism in the semantic
token module to handle other debouncing needs specific to its
functionality, such as debouncing server refresh notifications and
handling WinScrolled events when using range requests.

Co-authored-by: jdrouhard <john@drouhard.dev>
2026-06-14 16:43:08 +00:00
neovim-backports[bot]
304f8ed67a backport: fix(net): set buftype=nofile (again) (#39932)
redux 24e00f2844

(cherry picked from commit 1be55d02f5)

Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2026-06-14 11:25:45 -04:00
neovim-backports[bot]
dc6a9170eb backport: fix(lsp): trailing blank line when edit inserts past end of buffer (#40176)
Problem:
A text edit positioned entirely past the last buffer line, with
newText ending in a newline, leaves a stray blank line: the
past-the-end path appends the trailing empty fragment produced by
vim.split() and does not set has_eol_text_edit, so the end-of-buffer
cleanup is skipped. Formatting servers emit such edits whenever
formatting moves text to the end of a document.

Regression from ec94014cd1 (#20137), which split the past-the-end
fast path off the clamp path that sets the flag.

Solution:
Set has_eol_text_edit in the past-the-end path, like the adjacent
path that clamps end_row.

(cherry picked from commit d42f7ee9dc)

Co-authored-by: Aaron Tinio <aptinio@gmail.com>
2026-06-14 11:25:18 -04:00
Justin M. Keyes
ecda67662f backport fix(lsp): refresh codelens despite pending debounce #40177
Problem:
When a server sends workspace/codeLens/refresh while an automatic codelens
request is already scheduled, Nvim ignores the server refresh. This can leave
rendered codelens text stale until another buffer edit triggers a new request.

Solution:
Cancel the pending automatic request and send the server-requested refresh
immediately. This preserves request coalescing while giving explicit server
refreshes priority.

Co-authored-by: Tristan Knight <admin@snappeh.com>
2026-06-14 11:23:32 -04:00
Sébastien Hoffmann
83d9b9afca fix(statusline): prevent various buffer overflows with item groups #40219
Problem:

Various out-of-bounds writes inherited from vim (examples assume MAXPATHL==4096):
- truncated item groups where minwid>maxwid:
    nvim --clean +"set stl=%<%{%repeat('x',4096-11)%}%50.5(12🙂345%)"
  leads to fillchars spilling over the end of the group/buffer while trying to
  compensate for truncating at a multicell character because minwid<=maxwid is assumed
- left-aligned item groups with multi-byte fillchar:
    nvim --clean +"set fillchars+=stl:∙ stl=%<%{%repeat('x',4096-3)%}%-2(X%)"
  wrongly leads to padding at the end of the statusline and `out_p-out==4097`
  because the bounds check assumes a 1-byte fillchar
- right-aligned item groups with 1-byte fillchar:
    nvim --clean +"set stl=%<%{%repeat('x',4096-4)%}%4(XY%)"
  leads to "YX" instead of "XY" at the end of the statusline
  because `memmove` is done before adjusting the offset
- right-aligned item groups with multi-byte fillchar:
    nvim --clean +"set fillchars+=stl:∙ stl=%5(X%)"
  leads to "∙∙∙∙<e2>", i.e. the fillchar is being written over the group contents
  and eventually being overwritten itself at the second byte with the final NUL,
  because the padding counter assumes a 1-byte fillchar; to crash Neovim,
    nvim --clean +"set fillchars+=stl:∙ stl=%<%{%repeat('x',4096-149)%}%50(X%)"

Solution:
Clearer variable names and no recycling of variables for different purposes.

(cherry picked from commit e36659c82f)
2026-06-13 18:14:21 +00:00
Natanael Copa
c1318ac348 fix(test): support multiple --filter-out #39885
fixes regression introduced in commit 55f9c2136e (test: replace busted
with local harness)

(cherry picked from commit 584dfdb76d)
2026-06-12 22:19:44 +00:00
Jay Madden
fded370b3e perf(lsp): overscan semantic_token range requests #40036
Problem:
Flickering may occur when paging up/down in big files, as ranges for semantic
tokens are requested. This happens with LSP servers like gopls which return
"/full" semantic tokens if the file is too big, where we fall back to
viewport-range token retrievals.

Solution:
Broaden the requested ranges to one viewport of "overscan" on each side plus
some padding if possible:

    (viewport_topline - viewport_height)..(viewport_botline + viewport_height)

(cherry picked from commit 3ed78daf83)
2026-06-11 21:40:42 +00:00
Matei Stroia
a0d7e80368 fix(folds): foldcolumn is interrupted for virtual line above nested fold (#39999)
Problem:
`foldcolumn` is empty for virtual lines above the start of a nested
fold.

Solution:
For virtual lines, compute the outer fold level and display it by
reusing the logic from `fill_foldcolumn`.

(cherry picked from commit fe154f4d45)
2026-06-11 14:35:29 +00:00
Tomas Slusny
ed7acd1391 fix(startup): use nvim.difftool for nvim -d only for directories #40185
Problem:
`nvim -u NONE -d <(xxd one) <(xxd two)` has weird behavior.
Process substitution `<(...)` is a pipe and not a seekable file.

Test case:

    cat /dev/random | head -c 10240 > one
    cp one two
    cat /dev/random | head -c 10240 >> two
    nvim -u NONE -d <(xxd one) <(xxd two)

Solution:
Workaround the issue by skipping `nvim.difftool` if the 2 args are not
directories; fall-through to the builtin diff handling.

Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
(cherry picked from commit 2fd2361a9d)
2026-06-11 11:16:21 +00:00
Justin M. Keyes
427fec907b build: version bump 2026-06-11 00:13:45 +02:00
Justin M. Keyes
35b57441b0 NVIM v0.12.3
Following is a list of commits (fixes/features only) in this release.
See `:help news` in Nvim for release notes.

BREAKING
--------------------------------------------------------------------------------
- f54f566bf8 diagnostic: deprecate `format` as a table

FEATURES
--------------------------------------------------------------------------------
- fd1b193d51 :restart: v:starttime, v:exitreason #39319
- c407e3e67b eval: treat Lua string as "blob" in writefile() #39098
- a0dcdcd8a0 treesitter: provide select()
- 49efe692f3 vim.pos: accept buf=0 for current buf #39414
- ad27075c8d vim.pos: pos:to_offset(), pos.offset() (#39639)
- b05675bccc `opts.scope` in `vim.ui.input` (#39906)

PERFORMANCE
--------------------------------------------------------------------------------
- 96d5dd4107 vim.pos: use numeric index internally #39447

FIXES
--------------------------------------------------------------------------------
- e230ff0439 vim._with may silence all cmdline-errors #34301
- 781c43ea05 api: adjust Visual position after nvim_buf_set_text #30690
- 5b8268356a api: don't update 'title' when renaming non-curbuf #39743
- 4df16ecdb9 api: `LuaRef` leak in `nvim_set_keymap` on LHS too long (>=66 bytes) (#39376)
- e5d6d2e769 api: leak `preview` callback `LuaRef` in `nvim_create_user_command` (#39377)
- f0baa18043 channel: stack-buffer-overflow with exit during connection (#39387)
- d9baaf7da1 ci: generate more data to stress output throttling test #39577
- f62ce1a42f difftool: handle filenames containing spaces #39740
- fb56d50032 eval: writestring() handling of null #39328
- 822778f7e5 excmd: use realtime for v:starttime, :uptime #39425
- 8fccb26cd3 fold: virtual lines duplicate foldopen (#39891)
- 10695f44af health: set 'tags' for help filetype #39742
- e069022215 help: fix CTRL character issue for :help {subject} #39537
- 445fe8a6b7 lsp: calc correct screen_width when opts.relative == 'editor' (#39977)
- 93dc301781 lsp: callHierarchy/outgoingCalls ranges are relative to caller, not callee #39336
- 5e6c8d4edf lsp: check window is still valid after async request #39396
- 8919b02eba lsp: dynamic registration for off-spec method #39544
- c4d3a3d363 lsp: filter code_action diagnostics to the cursor #38988
- 27d01f2dbb lsp: handle null id in JSON-RPC responses
- aedbae4ab6 lsp: handle self-mapped methods in supports_method #39383
- 0bd6e62509 lsp: malformed edit if apply_text_edits() is called twice (#39347)
- 378f5f49b3 lsp: show meaningful error on invalid completion response (#39476)
- c9ca59ad28 lsp: util.lua attempt to concatenate userdata #39510
- e67f9c5853 lua: avoid `__index` when deciding if a table is a list #39556
- 731f9743e2 lua: don't strip debuginfo in precompile module #39191
- b0bfce290f lua: fields of `nvim.spellfile.Opts` are optional #39902
- 34bf0472ab marks: don't use spell decorations from other lines (#39441)
- d1cf3ab4c3 marks: read from the correct variable in conceal_lines mark collection (#39991)
- 33b6b0bfe5 messages: avoid recursive rtp build due to msg_show #39888
- d725ead5ec messages: reset redirection message column after :echon #39472
- b490fba786 mouse: mouse=n should not adjust visual selection
- 17ddfde131 net: `:edit <uri>` should set buftype=nofile #39915
- dd95e434e3 pack: only use tags that strictly comply with semver spec #39342
- 585c93204f path: `nvim_get_runtime_file` fails on DOS 8.3 filename #40144
- 42f6c1c443 prompt: handle multi-element lists in prompt_appendbuf #39550
- 915880d252 shada: bdelete'd buffers not stored in oldfiles #39070
- e4a9bd55b2 shada: set correct buffer number for local marks on read #39712
- 2389cf2e39 shell: preserve CR when `:!` outputs to binary-mode buffer #39558
- 98098d8466 startup: emitting useless OptionSet
- ae9f7accdd statusline: no cmdline ruler for autocommand window
- 39e8c584d5 terminal: memory leak in pending TermRequest StringBuilder #39333
- fa69cac7e3 terminal: memory leak when pasting '=' register (#39738)
- 3a3405d964 test: only test for unibilium if a valid compilation string exists
- dcf9e8a98e treesitter: crash in ts_parser_delete after gc #39497
- 4f22640b86 treesitter: get_node_text() inconsistent trailing newline #39409
- 654c964d1a trust: hash unchanged empty buffers as empty files #39027
- 70f22713a1 ui2: entering the pager fails if `<ESC>` is remapped to `:fclose` (#39462)
- 13041a067e ui2: error E518 when typing "vim:" in cmdline #39599
- a0ee5811b1 unittest: preprocess failure when __typeof declarations present #40145
- b9d39f5bb2 vim.fs: fs.dir() may return nil "type" on some filesystems #39749
- be4e7cfd6a vim.hl: range(0,…) highlight not cleared after buffer-switch #40130
- 79fd0b6655 vim.range: empty ranges semantics vs regular ranges #39474
- 2ec758f403 vim.range: validate arguments on all cases #39415
- f83e0dcaf8 vim.secure: read() command injection vulnerability #39918

BUILD
--------------------------------------------------------------------------------
- a612ada984 version bump
- b1b489b316 docs: sort/lint class fields and keysets
- 4f6c711fc0 test: declaration specifier expected near '_Static_assert' #39788

VIM PATCHES
--------------------------------------------------------------------------------
- 964e797fdf 9.2.0395: tests: Test_backupskip() may read from $HOME (#39417)
- b013940391 9.2.0435: [security]: backticks in 'path' may cause shell execution on completion
- f9f2596288 9.2.0436: Buffer overflow when parsing overlong errorformat lines (#39578)
- 0aa77cb78c 9.2.0443: GUI: cancelling save dialog overwrites or discards unnamed buffer (#39617)
- 15a58bb02a 9.2.0444: Cannot set 'path' option via modeline
- 03af1ec931 9.2.0450: [security]: heap buffer overflow in spellfile.c read_compound() (#39660)
- 2902ec0541 9.2.0458: Crash with invalid shellredir/shellpipe value (#39691)
- 647b6be489 9.2.0461: Corrupted undofile causes use-after-free (#39707)
- c8e0af85e0 9.2.0500: filetype: some html files wrongly recognized as htmlangular (#39880)
- d9b8bac435 9.2.0508: completion: cannot complete user cmd :K with 'ignorecase' (#39944)
- 15a3318e13 9.2.0513: [security]: memory safety issues in spellfile.c (#39960)
- cc1982bd06 9.2.0517: quickfix: can set quickfixtextfunc in restricted/sandbox mode (#39970)
- dfd6cd477f bfebd12: runtime(javacc): Check for existence of javaFuncDef syn group before clearing it (#39731)
- a76bcbe3b8 partial:9.2.0315: missing bound-checks (#39334)
v0.12.3
2026-06-11 00:06:57 +02:00
tao
585c93204f fix(path): nvim_get_runtime_file fails on DOS 8.3 filename #40144
Problem:
stdpath() may return a DOS 8.3 "shortened" filename, because Windows
truncates some long usernames into `6ch~N` names. Then features such
as `nvim_get_runtime_file` fail to find the file.

Analysis:
When expanding an 8.3 filename path like `C:/Users/ADMINI~1/AppData/*`,
we treat `~` as a special character and first check whether a directory
named `ADMINI~1` exists under `Users`. Since no such directory actually
exists, the expansion fails.

Solution:
Treat `~` as a literal character in `do_path_expand`. Since the `~/`
case is already handled in `gen_expand_wildcards`, any remaining `~` is
just a literal character and will later be escaped to `\~` by
`file_pat_to_reg_pat` if needed.

(cherry picked from commit 7bf2ab4b87)
2026-06-10 12:08:41 +00:00
James McCoy
a0ee5811b1 fix(unittest): preprocess failure when __typeof declarations present #40145
On Debian's ppc64el build, the unittests are failing during preprocess
with

    test/unit/testutil.lua:298: declaration specifier expected near '__typeof' at line 298
    test/unit/testutil.lua:282: assertion failed!

Running with NVIM_TEST_PRINT_I set shows these lines as being the
problem when trying to preprocess test/unit/fixtures/posix.h.

    690     extern __typeof (strtold) strtold ;
    691     extern __typeof (strtold_l) strtold_l ;
    692     extern __typeof (strfroml) strfroml ;
    693     extern __typeof (qecvt) qecvt ;
    694     extern __typeof (qfcvt) qfcvt ;
    695     extern __typeof (qgcvt) qgcvt ;
    696     extern __typeof (qecvt_r) qecvt_r ;
    697     extern __typeof (qfcvt_r) qfcvt_r ;

(cherry picked from commit 6c2f2b73eb)
2026-06-08 22:52:04 +00:00