Problem: Plugins may want to have a way to show more details about items
when using `vim.ui.select`. This is a fairly common problem that
prompts plugin authors to implement dedicated sources/pickers for
fuzzy picker plugins that are popular at the moment.
Solution: Document a way for `vim.ui.select` to provide preview:
- `vim.ui.select` users can provide `opts.preview_item` function that
creates/uses a buffer and its contents at certain position to show
more details about an item.
- `vim.ui.select` implementations may use `opts.preview_item` in the
way they see fit (like show the buffer in a separate/same window
interactively/on-demand or do nothing) if they have a way to show
more information about an item.
(cherry picked from commit c44df255aa)
Co-authored-by: Evgeni Chasnovski <evgeni.chasnovski@gmail.com>
Problem:
Since `foldclose` is async, it must wait for the request to return before actually executing, at which point the original window may no longer be valid.
Solution:
Check whether the window is valid before actually performing `foldclose`.
(cherry picked from commit 775c7d1b53)
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)
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)
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>
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>
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)
Problem:
Use vim.lsp.util.apply_text_edits to re-apply the same textedit causes
an incorrect edit, because apply_text_edits silently modifies the
parameter.
Solution:
- Avoid changing `text_edit._index`.
- Document this fun feature.
Helped-by: Riley Bruins <ribru17@hotmail.com>
Helped-by: Yi Ming <ofseed@foxmail.com>
(cherry picked from commit 790a8be5f3)
Co-authored-by: geril07 <62308020+geril07@users.noreply.github.com>
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
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)
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)
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)
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.
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)
Problem: missing bound-checks
Solution: Add defensive guards against potential buffer overflow
(Yasuhiro Matsumoto)
Add bounds checking and integer overflow guards across multiple files
as a defensive measure. While these code paths are unlikely to be
exploitable in practice, the guards prevent undefined behavior in
edge cases.
- libvterm/vterm.c: use heap tmpbuffer instead of stack buffer in
vsprintf() fallback path
- channel.c: validate len in channel_consume() before mch_memmove()
- spell.c: use long instead of int for addlen to avoid signed overflow
in size_t subtraction
- alloc.c: add SIZE_MAX overflow check in ga_grow_inner() before
itemsize multiplication
- list.c: add overflow check before count * sizeof(listitem_T)
- popupwin.c: add overflow check before width * height allocation
- insexpand.c: add overflow check before compl_num_bests multiplication
- regexp_bt.c: replace sprintf() with vim_snprintf() in regprop()
- spellfile.c: use SIZE_MAX instead of LONG_MAX for allocation overflow
check
closes: vim/vim#199048d23fcb603
Co-authored-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
(cherry picked from commit a4ad469fb1)
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)
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>
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)
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)
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>
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>
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>
Problem: :restart leads to ERR/WRN logging on Windows with --listen.
Solution: Add a log_level flag to vim._with() and use it to suppress
logging from serverstart()/serverstop() during restart.
(cherry picked from commit 208951cbc0)
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)
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>
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)
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)
Problem: Integer overflow with "ze" and large 'sidescrolloff'.
Solution: Check for overflow to avoid negative w_leftcol (zeertzjq).
closes: vim/vim#2002633f3965087
(cherry picked from commit 1569a71c8a)
Problem:
Build fails if user cloned the repo to a path with "%" chars:
src/gen/gen_char_blob.lua:51: bad argument #1 to 'format' (number expected, got string)
Solution:
- Escape "%" chars.
- Also use "%q" in case the path has spaces...
(cherry picked from commit 4af0c5d8df)
Problem: ins_compl_stop() sets compl_best_matches = 0, but that's a
pointer, should reset compl_num_bests instead,
find_common_prefix() reads cpt_sources_array[cur_source] without
checking cur_source != -1 which causes an OOB for -1,
find_next_completion_match(): second `if` in the pending loop
should be `else if`. Forward paging only moves one step per call.
Solution: Reset compl_num_bests instead, add a check for cur_source not
equal -1, change if to else if (glepnir)
closes: vim/vim#20000b328686d6a
Co-authored-by: glepnir <glephunter@gmail.com>
(cherry picked from commit 3f9500e75d)
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)
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>
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)
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)