Commit Graph

10324 Commits

Author SHA1 Message Date
zeertzjq
f0baa18043 fix(channel): stack-buffer-overflow with exit during connection (#39387)
Problem:  When Nvim exits while connecting to a socket it leads to
          stack-buffer-overflow.
Solution: Associate the handle with the Stream and use the Stream's
          internal_close_cb to update the "closed" status.
(cherry picked from commit 4ed2e66d2e)
2026-04-25 12:38:20 +00:00
zeertzjq
e5114d03b5 test: add finally() to meta file (#39388)
(cherry picked from commit df8cf0ed25)
2026-04-25 10:10:25 +00:00
Tristan Knight
aedbae4ab6 fix(lsp): handle self-mapped methods in supports_method #39383
Problem:
The LSP client incorrectly checks for server capabilities when determining
support for self-mapped methods (e.g., 'shutdown'), which do not have
corresponding capabilities in the server's response. This leads to false
negatives when checking if such methods are supported.
This was handled correctly for dynamic registrations, but not for static.

Methods such as 'shutdown', do not have a related server capability and should
be assumed to be supported.

Solution:
Update the `supports_method` logic to always return true for self-mapped
methods.

(cherry picked from commit f83d0b9653)
2026-04-24 23:19:16 +00:00
neovim-backports[bot]
e5d6d2e769 backport: fix(api): leak preview callback LuaRef in nvim_create_user_command (#39377)
Problem:
Invalid `nvim_create_user_command` calls can leak the
`preview` callback reference after Neovim has taken ownership of it.

1. build with {a,l}san
2. run:
    ```sh
    <path/to/nvim> --headless -u NONE --clean +'lua
    for i = 1, 100 do
      pcall(vim.api.nvim_create_user_command,
        "some very epic stuff" .. i,
        {}, -- NOTE: this is INVALID (not a function or string)
        { preview = function() end })
    end
    vim.cmd("qa!")
    ' +qa
    ```
3. see:
    ```
    100 lua references were leaked!
    ```

Solution:
Clear `preview_luaref` in `err:`.

(cherry picked from commit 393f687503)

Co-authored-by: Barrett Ruth <62671086+barrettruth@users.noreply.github.com>
2026-04-24 17:27:46 -04:00
neovim-backports[bot]
4df16ecdb9 backport: fix(api): LuaRef leak in nvim_set_keymap on LHS too long (>=66 bytes) (#39376)
Problem: `nvim_set_keymap` leaks the `callback` `LuaRef` when the
LHS is too long.

Solution: Make `set_maparg_lhs_rhs` transfer `rhs_lua` to
`MapArguments` up front so the caller always owns the ref.

(cherry picked from commit 58aad59e1c)

Co-authored-by: Barrett Ruth <62671086+barrettruth@users.noreply.github.com>
2026-04-24 17:27:14 -04:00
Justin M. Keyes
3b69e3d0cf test: fix merge conflict 2026-04-24 20:18:19 +02:00
glepnir
3d923bfa50 test: curbuf initialized in describe-block
Problem: curbuf was initialized at describe-block load time
before any Nvim session existed.

Solution: Replace with 0 directly at call sites.
2026-04-24 15:33:31 +02:00
Barrett Ruth
654c964d1a fix(trust): hash unchanged empty buffers as empty files #39027
Problem:
`vim.secure.trust()` hashes an unchanged empty buffer as
a newline, so trusting an empty file by buffer never works.

Solution:
Hash unchanged empty-buffers `''` so buffer-based
trust matches the on-disk empty file.

(cherry picked from commit 0a8218a2b4)
2026-04-23 23:38:56 +00:00
Barrett Ruth
c4d3a3d363 fix(lsp): filter code_action diagnostics to the cursor #38988
Problem:
Cursor-position `vim.lsp.buf.code_action()` requests include all diagnostics on the current line, so unrelated same-line diagnostics affect the returned actions.

Solution:
Filter same-line diagnostics to the cursor position for cursor-position requests.

(cherry picked from commit ecb8402197)
2026-04-23 23:07:26 +00:00
Ashley Hauck
93dc301781 fix(lsp): callHierarchy/outgoingCalls ranges are relative to caller, not callee #39336
Problem:
The fromRanges field of the result of callHierarchy/outgoingCalls is
documented as being relative to the caller. Using
vim.lsp.buf.outgoing_calls() opened the qflist with an entry with the
callee's filename, but the caller's line number.

Solution:
Open the qflist with the callers file (the bufnr from the request),
rather than the callees (the uri from the resulting CallHierarchyItem)

(cherry picked from commit 7e006b06c4)
2026-04-23 23:07:07 +00:00
Barrett Ruth
39e8c584d5 fix(terminal): memory leak in pending TermRequest StringBuilder #39333
Problem: Destroying a terminal with pending `TermRequest` events leaks
memory.

Solution: Make `emit_termrequest` the sole owner of its `pending_send`
allocation.

(cherry picked from commit 19ef632dec)
2026-04-23 23:05:20 +00:00
Justin M. Keyes
f945aa451b refactor(test): deduplicate trust tests 2026-04-23 23:01:15 +02:00
atusy
27d01f2dbb fix(lsp): handle null id in JSON-RPC responses
Problem:
LSP spec allows response message to have a null request-id.
This may happen when for example client sends unparseable request.
https://github.com/microsoft/language-server-protocol/issues/196

Solution:
Guard the server response branches against id=vim.NIL (json null),
and handle error responses with null id by logging a warning
and dispatching on error.

Problem:
CI (ubuntu asan, ubuntu tsan, windows) reports `uv_loop_close()
hang?` from the two new null-id response tests. The leaked
handle is the server-side accepted TCP socket created inside
`server:listen` callback. The tests closed only the listener
but not the accepted socket, so libuv could not finish shutting
down the loop and each test session took ~2s extra to exit.

Solution:
Hoist the accepted socket to the outer `exec_lua` scope and
close it at teardown before closing the listener. The close
runs synchronously inside `exec_lua`, so the loop has time to
dispose the handle before the session exits.

* test(lsp): close accepted socket on read-loop exit/error

Match the precedent in the handler test ("handler can return
false as response") and the shared `_create_tcp_server` helper
in `test/functional/plugin/lsp/testutil.lua`: close the
accepted socket from inside the `create_read_loop` exit/error
callbacks. The teardown close added in the previous commit
remains as belt-and-suspenders, so the socket is disposed
whether the server goes away first or the client does.
2026-04-23 23:00:25 +02:00
Evgeni Chasnovski
dd95e434e3 fix(pack): only use tags that strictly comply with semver spec #39342
Problem: Using `version=vim.version.range(...)` in plugin specification
  is meant to use semver-like tags. Whether a tag is semver-like was
  decided by a plain `vim.version.parse` which is not strict by default.
  This allowed treating tags like `nvim-0.6` (which is usually reserved
  for the latest revision compatible with Nvim<=0.6 version) like semver
  tags and resulted in confusing behavior (preferring `nvim-0.6` tag
  over `v0.2.2`, for example).

Solution: Use `vim.version.range(x, { strict = true })` to decide if the
  tag name is semver-like or not. This allows tags like both `v1.2.3`
  and `1.2.3` while being consistent in what Nvim thinks is a semver
  string.

  This is technically not a breaking change since it was documented that
  only tags like `v<major>.<minor>.<patch>` will be recognized as
  semver.

(cherry picked from commit f8c94bb8cf)
2026-04-23 15:55:14 +00:00
Justin M. Keyes
14eea10ec5 ci: drop cirrus #39321
Problem:
cirrus will shutdown soon, and we are running out of minutes anyway,
which causes ci failures.

Solution:
Drop cirrus config.

(cherry picked from commit 82198d0a66)
2026-04-22 23:01:00 +00:00
Justin M. Keyes
b46688feee backport feat(treesitter): expand selection to sibling node (#39323)
Problem:
Can't expand treesitter-incremental-selection to the next and previous
sibling nodes.

Solution:
Pressing `]N` in visual mode will expand the selection to the next
sibling node, and `[N` will do the same with the previous node.

Co-authored-by: altermo <107814000+altermo@users.noreply.github.com>
2026-04-22 21:40:12 +00:00
Justin M. Keyes
fd1b193d51 feat(:restart): v:starttime, v:exitreason #39319 2026-04-22 18:58:47 +00:00
Barrett Ruth
c407e3e67b feat(eval): treat Lua string as "blob" in writefile() #39098
Problem:
vim.fn.writefile() treats Lua strings as Vimscript strings instead of a "binary clean" string.

Solution:
Treat Lua-originated strings as blob data.

(cherry picked from commit fb6aeaba2d)
2026-04-22 17:56:29 +00:00
glepnir
915880d252 fix(shada): bdelete'd buffers not stored in oldfiles #39070
Problem:
b98eefd added `!b_p_bl` to `ignore_buf()`, which also
skips bdelete'd buffers since bdelete unsets `b_p_bl`.

Solution:
Check `b_p_initialized` together with `b_p_bl` so that
bdelete'd buffers (which have b_p_initialized=false) are not
filtered out. Keep `b_p_bl` check only in `shada_get_buflist()`.

(cherry picked from commit 496374e951)
2026-04-22 17:39:22 +00:00
luukvbaal
9e1c542b55 fix(cmdline): avoid 'incsearch' recursion after redraw #39303
Problem:  A vim.ui_attach() callback that redraws to show a 'verbose'
          regex message during 'incsearch' results in recusive redrawing.

Solution: Check that curwin was redrawn instead of just any window when
          determining if 'incsearch' highlighting was cleared.
(cherry picked from commit 61fb88992d)
2026-04-22 13:58:56 +00:00
neovim-backports[bot]
b6a3ad3979 backport: fix(ui2): ensure msg window is visible after closing tab (#39245)
fix(ui2): ensure msg window is visible after closing tab

Problem:  After closing a tabpage while the msg window is showing a
          message, it is hidden while the msg window still contains a
          message.
Solution: Unhide the msg window after entering a tabpage and it still
          contains a message.


(cherry picked from commit 607fcfb37a)

Co-authored-by: Luuk van Baal <luukvbaal@gmail.com>
Co-authored-by: Linykq <yukunlin590@gmail.com>
2026-04-22 13:43:04 +00:00
neovim-backports[bot]
6ae6cf5d61 fix(float): don't unload 'hidden' float buffer with :close! (#39304)
Problem:  When closing floating windows to close a tabpage, if the current
          buffer will unload, buffers contained in those floating windows
          will too (unexpectedly).
Solution: Don't pass along "free_buf" argument; check 'bufhidden' for
          the buffer in the to be closed float.
(cherry picked from commit 5b0ad4a060)

Co-authored-by: luukvbaal <luukvbaal@gmail.com>
2026-04-22 08:18:03 -04:00
neovim-backports[bot]
39ecf31da3 test(tui_spec): fix "Uncaught Error" with PUC Lua (#39301)
RUN      T339 TUI :restart ZR: Uncaught Error: test/client/uv_stream.lua:111: ECONNRESET
stack traceback:
	[C]: in function 'error'
	test/client/uv_stream.lua:111: in function <test/client/uv_stream.lua:109>
	[C]: in function 'run'
	test/client/session.lua:240: in function '_run'
	test/client/session.lua:216: in function '_blocking_request'
	test/client/session.lua:117: in function 'request'
	...t_xdg_terminal/test/functional/terminal/tui_spec.lua:223: in function <...t_xdg_terminal/test/functional/terminal/tui_spec.lua:215>
	[C]: in function 'pcall'
	test/testutil.lua:82: in function 'retry'
	...t_xdg_terminal/test/functional/terminal/tui_spec.lua:215: in function 'assert_restarted'
	...t_xdg_terminal/test/functional/terminal/tui_spec.lua:275: in function <...t_xdg_terminal/test/functional/terminal/tui_spec.lua:232>
	[C]: in function 'xpcall'
	/home/runner/work/neovim/neovim/test/harness.lua:693: in function 'run_callable'
	/home/runner/work/neovim/neovim/test/harness.lua:1008: in function 'run_test'
	/home/runner/work/neovim/neovim/test/harness.lua:1083: in function 'run_suite'
	/home/runner/work/neovim/neovim/test/harness.lua:1081: in function 'run_suite'
	/home/runner/work/neovim/neovim/test/harness.lua:1081: in function 'run_suite'
	/home/runner/work/neovim/neovim/test/harness.lua:1507: in function 'run_test_file'
	/home/runner/work/neovim/neovim/test/harness.lua:1577: in function 'run_iteration'
	/home/runner/work/neovim/neovim/test/harness.lua:1665: in function 'main'
	/home/runner/work/neovim/neovim/test/runner.lua:30: in main chunk
-- Tests exited non-zero: 255
CMake Error at /home/runner/work/neovim/neovim/cmake/RunTests.cmake:135 (message):
  functional tests failed with error: 255

(cherry picked from commit ead1478b69)

Co-authored-by: zeertzjq <zeertzjq@outlook.com>
2026-04-22 08:16:25 -04:00
Nick Krichevsky
4d4e196447 fix(options): default 'titlestring' shows CWD #39233
Problem:
In the default 'titlestring', if the containing directory is the CWD, it renders as "."

Solution:
Add `:p` to the titlestring.

(cherry picked from commit e68e769352)
2026-04-22 11:52:02 +00:00
neovim-backports[bot]
b3b5674ac7 fix(:restart): --listen reusage on windows #39281
Problem:
On Windows, :restart cannot immediately reuse the canonical --listen
address because named pipe release is asynchronous.

Solution:
Start the new Nvim server on a temporary address; in the new Nvim,
retry serverstart() with the original ("canonical") address until it
succeeds.

(cherry picked from commit 5891f2f3dc)

Co-authored-by: Sanzhar Kuandyk <92693103+SanzharKuandyk@users.noreply.github.com>
2026-04-22 06:22:12 -04:00
fleesk
6583833ee2 fix(pack): GIT_DIR/GIT_WORK_TREE env vars may interfere #39279
Problem:
With GIT_DIR/GIT_WORK_TREE set, the LSP on the vim.pack.update()
confirmation buffer does not show the correct git log on hover.

Solution:
Temporarily remove the git vars from the environment.

(cherry picked from commit e53e728c92)
2026-04-22 09:24:45 +00:00
glepnir
ba3de79ccb fix(cmd): ++p, ++edit should match "word" boundary #39146
Problem: `:write ++patate foo` doesn't error out, instead it turns on
mkdir_p and uses "atate foo" as the filename. Same with ++edit.
The parser just does strncmp without checking what comes after.

Solution: require the next char after the option name to not be a
letter

(cherry picked from commit 44770bb924)
2026-04-22 09:16:36 +00:00
zeertzjq
15d824e5d6 vim-patch:9.2.0385: Integer overflow with "ze" and large 'sidescrolloff' (#39289)
Problem:  Integer overflow with "ze" and large 'sidescrolloff'.
Solution: Check for overflow to avoid negative w_leftcol (zeertzjq).

closes: vim/vim#20026

33f3965087
(cherry picked from commit 1569a71c8a)
2026-04-22 02:35:11 +00:00
Justin M. Keyes
e767b4843b backport: refactor(test): drop deprecated exc_exec #39255 2026-04-21 16:22:05 +00:00
zeertzjq
ffb0ebb752 fix(substitute): don't crash with very large count (#39272)
(cherry picked from commit ac8459a09c)
2026-04-21 12:05:56 +00:00
luukvbaal
c6b5eb30de fix(ui2): don't dismiss expanded messages for non-typed key #39247
Problem:  Invalid check for non-typed key to dismiss expanded cmdline.
          Unable to delay the timer that removes a message from the msg
          window.
Solution: Check for empty string instead of nil to determine whether a
          key is typed.
          Restart the timer if it expires while the user is in the msg
          window. Allow entering the msg window with a mouse click.
(cherry picked from commit faa7c15b5a)
2026-04-20 19:13:17 +00:00
Justin M. Keyes
eaa8cff0bd fix(api): expose fg_indexed/bg_indexed in nvim_get_hl (#39240)
Problem: fg_indexed/bg_indexed were dropped from nvim_get_hl output due
to a wrong short_keys guard. HL_FG_INDEXED also wasn't cleared in
hl_blend_attrs, and HLATTRS_DICT_SIZE was too small.

Solution: Remove the short_keys guard, clear HL_FG_INDEXED in
hl_blend_attrs, bump HLATTRS_DICT_SIZE to 24, and clarify docs that
these flags mean rgb is an approximation of the cterm palette index.

(cherry picked from commit 01861c2f95)

Co-authored-by: glepnir <glephunter@gmail.com>
2026-04-20 09:46:55 +00:00
zeertzjq
5153006747 vim-patch:9.2.0364: tests: test_smoothscroll_textoff_showbreak() fails
Problem:  tests: test_smoothscroll_textoff_showbreak() fails
          (after v9.2.0363)
Solution: Add missing CheckRunVimInTerminal

related: vim/vim#20011

618a327ce6

Co-authored-by: Christian Brabandt <cb@256bit.org>
(cherry picked from commit 2ee25ba41b)
2026-04-20 02:17:54 +00:00
Jaehwang Jung
898ccbc68a fix(smoothscroll): crash when resizing to textoff with showbreak
vim-patch:9.2.0362: division by zero with smoothscroll and small windows

Problem:  Resizing a smoothscrolled wrapped window to its textoff width
          with 'showbreak' can leave wrapped continuation lines with
          zero text width. win_lbr_chartabsize() still runs the partial max_head_vcol calculation in
          that state and divides by width2, crashing during redraw.
Solution: Skip that partial head calculation when the wrapped
          continuation width is zero, matching the other width2 guards
          in charset.c (Jaehwang Jung)

closes: vim/vim#20012

AI-assisted: Codex

0e31fb024c
(cherry picked from commit 79a7a4abe1)
2026-04-20 02:17:54 +00:00
Jaehwang Jung
9966afbc9d fix(drawline): hang while redrawing diff filler above fold #39219
Problem:
win_line() falls into infinite loop when a diff window has top filler
above its first visible buffer line, that first visible buffer line is a
closed fold, and the folded line uses normal non-empty foldtext.

Solution:
Allow flushing pending diff filler rows even when the underlying buffer
line is folded with foldtext.

AI-assisted: Codex

Co-authored-by: zeertzjq <zeertzjq@outlook.com>
(cherry picked from commit f2cc0a249d)
2026-04-19 21:30:33 +00:00
Justin M. Keyes
43398547ec backport docs: misc (#39206)
docs: misc


(cherry picked from commit 54398c5874)
2026-04-19 12:36:19 +00:00
Ashley Hauck
15991abaa7 backport: feat(events): trigger MarkSet autocmd in :delmarks (#39218)
Problem:
`api.nvim_buf_del_mark` already emits a `MarkSet` event with `col` and `line` set to 0. However, `:delmarks` currently emits no events.

Solution:
Change `:delmarks` to emit the same `col==line==0` event.
2026-04-19 12:20:56 +00:00
Jaehwang Jung
5907307662 fix(lsp): skip codelens refresh redraw for deleted buffer #39193
Problem:
After on_refresh() sends a textDocument/codeLens request, the buffer may
be deleted before the response arrives. The response callback then tries
to redraw that deleted buffer and raises Invalid buffer id error.

Solution:
Check buffer validity before redrawing.

AI-assisted: Codex
Co-authored-by: Yi Ming <ofseed@foxmail.com>
(cherry picked from commit 97caa88972)
2026-04-18 22:34:59 +00:00
glepnir
34cbfeca9c fix(lsp): show CompletionItem.detail in info popup #38904
Problem: completionItem/resolve response's `detail` field is silently
dropped. Only `documentation` is shown in the popup.

Solution: Prepend `detail` as a fenced code block before `documentation`
in the info popup, skipping if documentation already contains it.

(cherry picked from commit b351afb1b1)
2026-04-18 20:42:42 +00:00
Evgeni Chasnovski
9aadbed770 fix(lua): make vim._with() work with buf=0 and win=0 context #39151
Problem: Using `buf=0`/`win=0` context in `vim._with` should be
  equivalent to using explicit buffer/window identifier respectively.

Solution: Explicitly adjust context in case of `buf=0` or `win=0`.
(cherry picked from commit 3a4cc5db0b)
2026-04-18 20:34:47 +00:00
zeertzjq
20c6edbc12 test(tui_spec): don't run tty-test in a shell (#39186)
(cherry picked from commit 48d11681c2)
2026-04-18 12:30:01 +00:00
luukvbaal
f2a5c90cbc fix(marks): adjust marks when unloading "nofile" buffer #39118
Problem:  Marks are not adjusted unloading a buffer that doesn't exist
          on disk. E.g. extmarks are still valid (and will be beyond the
          end of the buffer if the buffer is reloaded), even though the
          text is lost.
Solution: Adjust marks for a cleared buffer when unloading a buffer that
          doesn't exist on disk.
(cherry picked from commit 68f7acaaae)
2026-04-18 11:49:58 +00:00
Evgeni Chasnovski
c6578ea28b fix(vim.filetype): match() fails if g:ft_ignore_pat is not defined #39158
Problem: Calling `vim.filetype.match({ filename = '...', buf = ... })`
  during startup results in an error due to not yet defined
  `g:ft_ignore_pat`.

Solution: Add a guard to check `g:ft_ignore_pat` related properties only
  if the variable is defined. This also allows to simplify other tests
  which did not depend on `g:ft_ignore_pat` but required it explicitly
  set to work.
(cherry picked from commit 6b9b4a1377)
2026-04-18 11:44:54 +00:00
Justin M. Keyes
55d3d1bbeb backport: test(lsp): extract buf/util parts from lsp_spec.lua (#39170)
test(lsp): extract buf/util parts from lsp_spec.lua

Problem:
`test/functional/plugin/lsp_spec.lua` had grown into a large catch-all file that mixed core LSP client lifecycle coverage, `vim.lsp.buf.*` behavior, and `vim.lsp.util.*` behavior in one place.

Solution:
Split the large tests into more focused test files without changing test coverage or intended behavior.

After this change, `lsp_spec.lua` is more focused on core LSP client/config/dynamic-registration behavior.

Co-authored-by: Yi Ming <ofseed@foxmail.com>
2026-04-18 03:01:28 +00:00
zeertzjq
d3ef77639a fix(terminal): forward streamed bracketed paste properly (#39152)
(cherry picked from commit 4eaf782bb6)
2026-04-17 23:22:18 +00:00
zeertzjq
f93561723c test: include test path in summary (#39141)
Ref: https://github.com/neovim/neovim/pull/38486#discussion_r3088483987
(cherry picked from commit fefad0721a)
2026-04-17 14:08:02 +00:00
zeertzjq
e4dc08da1a fix(completion): update CursorColumn during completion (#39159)
Since Nvim uses a compositor, redrawing windows won't lead to flicker in
the popup menu, so the pum_visible() checks in move.c can be removed.

(cherry picked from commit 724fccd46f)
2026-04-17 13:45:21 +00:00
altermo
111c7f434e fix(treesitter): TSNode:id() with NUL byte causes unreliable select() #39134
Problem:
`TSNode:id()` returns the underlying c pointer as a string, which may include
NUL bytes. In PUC Lua, `('%s'):format('\0a\0')` returns `''` and not `'\0a\0'`
(i.e. treats the string as a c-string (which terminates at the NUL byte)).

This resulted in two different nodes being able to have the same id.

Solution:
Use concatenation `..` instead of `string.format()`.

(cherry picked from commit bb2284d75e)
2026-04-16 22:48:50 +00:00
luukvbaal
b08c289a45 fix(ui2): dialog paging is inconsistent #39128
Problem:  - Paging keys in the dialog window consume input when the user
            may not expect it. The dismissable title hint intended to
            mitigate that results in having to press Escape twice to
            abandon the prompt.
          - Mimicked "msgsep" float border is taking up unnecessary
            space when window takes up the entire screen.

Solution: - Use (conventional, albeit less convenient) keys intended
            for scrolling to page the dialog window:
            <(Mousewheel/Page)Up/Down>, <Home/End>.
          - Only set the float top border when separation is actually
            necessary, i.e. window does not reach the first row.
(cherry picked from commit f0a8e6f337)
2026-04-16 21:01:25 +00:00
Evgeni Chasnovski
5f23c0a1cf test(pack): increase retry timeout for startup test #39125
Problem: Unreliable test on Windows which sometimes fails with too many
  failed retries.

Solution: Increase timeout in hopes that it will be enough to make it
  pass more frequently. This should not affect fast and already working
  platforms.
(cherry picked from commit df6a0827fb)
2026-04-16 15:18:20 +00:00