Commit Graph

32758 Commits

Author SHA1 Message Date
zeertzjq
77809f0d9c Merge pull request #37249 from zeertzjq/backport
fix(terminal): avoid multiple terminals writing to same buffer (#37219)
2026-01-05 14:13:55 +08:00
zeertzjq
074d342f63 fix(terminal): avoid multiple terminals writing to same buffer (#37219)
Problem:  Calling termopen() or nvim_open_term() on a buffer with an
          existing terminal leads to two terminals writing to the same
          buffer if the terminal job is still running, or memory leak
          if the terminal job has exited.
Solution: Close the terminal if the terminal job has exited, otherwise
          report an error.
2026-01-05 13:54:08 +08:00
zeertzjq
e4a2bbf5f5 Merge pull request #37244 from zeertzjq/backport
Backport to release-0.11
2026-01-05 11:53:10 +08:00
zeertzjq
f7e2554bfb fix(window): crash closing split if autocmds close other splits (#37233)
Problem:  Crash when closing a split window if autocmds close other
          split windows but there are still floating windows.
Solution: Bail out and give the window back its buffer.
2026-01-05 11:34:49 +08:00
Sean Dewar
a9ffdca528 fix(api): open_win leak from naughty autocommands
Problem: error set by win_set_buf may leak if autocommands immediately close the
new window.

Solution: free the error set by win_set_buf. (prefer nvim_open_win's error as
it's more important and will cause 0 to be returned)
2026-01-05 11:34:26 +08:00
Sean Dewar
91ebbc6c4e fix(api): ignore split_disallowed when opening a float
Problem: split_disallowed seemingly exists to prevent issues from changing
frames to accomodate a split window, which doesn't apply to floats.

Solution: remove the restriction for nvim_open_win, but only for floats.
(continue to check b_locked_split though)

NOTE: like before, the buffer we check b_locked_split for may not actually be
the target buffer "buf", as the later call to win_set_buf can fail to switch to
"buf" due to autocommands. (among other things)

Maybe we could attempt to close the new window in that case (or switch to a
different buffer if that also fails), but this is safer. (and simpler)

Fixes #36857 (and possibly some spurious E242s I've observed from extui)
2026-01-05 11:34:15 +08:00
glepnir
7f51431c12 fix(api): crash when moving curwin to other tabpage #35679
Problem: nvim_win_set_config may crash when attempting to move curwin to a
different tabpage if there is no other non-float available to switch to.

Solution: fix the crash. Fix ONE_WINDOW checks in winframe_find_altwin and
win_altframe to consider floating windows by instead using one_window. Allow
one_window to consider non-current tabpages. We can use one_window in
win_close_othertab now to also better reflect its use in win_close.

Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
2026-01-05 11:33:54 +08:00
Sean Dewar
7a9bced071 fix(window): disallow closing autocmd window in other tabpage
Problem: unlike win_close, win_close_othertab could be used to close the
autocommand window from a different tabpage. This causes aucmd_restbuf to close
the wrong window, potentially causing a crash.

Solution: disallow closing it. Also replace a deprecated use of exc_exec in the
test file.

Fixes #21409.
2026-01-05 11:33:37 +08:00
Sean Dewar
7896fe2dea fix(api): do not allow opening float to closing buffer
Problem: no check for nvim_open_win opening a new floating window into a closing
buffer, which can lead to crashes.

Solution: call check_split_disallowed; opening a new float semantically splits
from a window, so the same problems as regular splits apply. Also restore the
error if switch_win_noblock in win_set_buf fails (may not be possible to hit
this, but win_set_buf can silently succeed there since #31595).

As the lock check applies to curbuf (not the target buffer) this may feel a bit
restrictive, though this isn't different to how things like ":split" or
nvim_open_win with "split = true" works when targeting a different buffer. Only
checking the target buffer's lock will cause issues if win_set_buf doesn't end
up in the target buffer for whatever reason.

Maybe we could consider checking the lock of the buffer after win_set_buf and
close the window if it's locked (maybe a bit fiddly, especially as closing a
window can fail...), or make the open + switch operation more atomic, like how
Vim does for its popup windows..?

It also used to be the case that win_set_buf would set an error if autocommands
sent us to a different buffer than what was requested, but #31595 appears to
have also changed that... I haven't touched that here.
2026-01-05 11:33:33 +08:00
Sean Dewar
d38ba7e2b8 fix(window): restore b_nwindows if win_close_othertab keeps window
Problem: can't accurately know if close_buffer directly (e.g: not via autocmds)
decremented b_nwindows. This can cause crashes if win_close_othertab decides to
keep the window after calling close_buffer (if it did not free the buffer), as
b_nwindows may remain out-of-sync.

Solution: change the return value of close_buffer to accurately depict whether
it decremented b_nwindows. Check it in win_close_othertab to avoid a crash.

Similar issues may exist in other places that call close_buffer, but I've not
addressed those here (not to mention only one other place even checks its return
value...)
2026-01-05 11:33:26 +08:00
Sean Dewar
a3dabcfa11 test(tabclose): remove deprecated calls, use testnvim helpers 2026-01-05 11:33:18 +08:00
Sean Dewar
46011a4e87 fix(autocmd): fire TabClosed after freeing tab page
Problem: TabClosed is fired after close_buffer is called (after b_nwindows is
decremented) and after the tab page is removed from the list, but before it's
freed. This causes inconsistencies such as the removed tabpage having a valid
handle and functions like nvim_tabpage_get_number returning nonsense.

Solution: fire it after free_tabpage. Try to maintain the Nvim-specific
behaviour of setting `<amatch>` to the old tab page number, and the
(undocumented) behaviour of setting `<abuf>` to the buffer it was showing
(close_buffer sets w_buffer to NULL if it was freed, so it should be OK pass it
to apply_autocmds_group, similar to before).
2026-01-05 11:33:13 +08:00
Sean Dewar
88619e1aaf fix(window): handle closing the only non-float in other tabpage
Problem: No check for closing the only non-floating window in a non-current
tabpage that contains floats. This can lead to a tabpage that contains only
floats, causing crashes.

Solution: Copy the relevant check from win_close to win_close_othertab. Fix some
uncovered issues.

Closes #34943
Fixes #31236

Co-authored-by: glepnir <glephunter@gmail.com>
2026-01-05 11:28:31 +08:00
zeertzjq
4e90ea5dca refactor(terminal): remove unnecessary buf_valid() (#37224)
In close_buffer(), free_buffer() is called to remove the buffer from
buffer_handles immediately after removing it from the buffer list, so as
long as a buffer is in buffer_handles it is always valid.

(cherry picked from commit 033302d97d)
2026-01-05 01:12:52 +00:00
zeertzjq
ceed171485 fix(terminal): crash with race between buffer close and OSC 2 (#37225)
Problem:  Crash when a terminal receives OSC 2 just after closing its
          buffer but before terminal job exits.
Solution: Remove FUNC_ATTR_NONNULL_ALL from buf_set_term_title() and
          check for NULL.
(cherry picked from commit b67ac8cc6b)
2026-01-05 00:31:02 +00:00
zeertzjq
f1641e6fc2 Merge pull request #37234 from zeertzjq/backport
fix(terminal): handle closing terminal with pending TermRequest (#37227)
2026-01-04 23:10:32 +08:00
Sean Dewar
d9631c7678 fix(window): crash closing only non-float if autocmds :tabonly (#37218)
Problem: null pointer member access when closing the only non-float in the
current tab page if autocommands after closing all floats also close all other
tab pages. (making it the last window)

Solution: check last_window again after closing the floats.

Also reduce the scope of "wp"; it would be bugprone to use it before it's later
reassigned to the rv of win_free_mem if freed by Buf/WinLeave.

(cherry picked from commit c14de47f1a)
2026-01-04 14:46:02 +00:00
zeertzjq
acc46e1dd7 fix(terminal): handle closing terminal with pending TermRequest (#37227)
Problem:  Destroying a terminal with pending TermRequest leads to
          heap-use-after-free when processing TermRequest afterwards.
Solution: Store the buffer handle instead of the Terminal pointer in the
          pending TermRequest event, and don't emit TermRequest if the
          terminal is already closed.
2026-01-04 22:37:20 +08:00
zeertzjq
bb31e7b345 fix(terminal): inconsistent mode change when switching buffer (#37215)
Problem:  When switching to another terminal buffer in Terminal mode,
          usually Nvim stays in Terminal mode, but leaves Terminal mode
          if the old terminal buffer was deleted.
Solution: Don't always leave Terminal mode when active terminal buffer
          is deleted. Instead let terminal_check_focus() decide that.
(cherry picked from commit 3621af9b97)
2026-01-04 03:54:26 +00:00
Francisco Giordano
c124594b22 fix(api): buffer overflow in nvim_buf_get_extmarks overlap #37184
With `overlap=true`, more extmarks than the requested limit may be
collected in `extmark_get`. This then leads to an out of bounds write of
`rv` in `nvim_buf_get_extmarks`.

(cherry picked from commit 612cd99a00)
2026-01-02 07:37:32 +00:00
zeertzjq
44eae48b75 vim-patch:9.1.0893: No test that undofile format does not regress (#37193)
Problem:  No test that undofile format does not regress
Solution: include a sample undofile to make sure we are always able to
          read it

This is so, that we don't unintentionally change the undofile format and
make sure we can load an undo file that has been created by an older
Vim.

closes: vim/vim#16127

14382c8bc9

Convert the undo file in samples/ using method from #13973.

Co-authored-by: Christian Brabandt <cb@256bit.org>
(cherry picked from commit 94f7302e66)
2026-01-01 23:40:43 +00:00
Peter Cardenas
46f569a890 fix(treesitter): use metadata in :EditQuery captures #37116
Problem:
When the `#offset!` directive is used with `:EditQuery`, the query does not take the offset into consideration when creating the extmark to preview the capture.

Solution:
Use the capture metadata to modify the node range before creating the extmark.
2025-12-31 12:21:41 +01:00
zeertzjq
fda8d2c717 vim-patch:9.1.2028: [security]: Buffer-overflow with incomplete multi-byte chars (#37133)
Problem:  Buffer overflow in buf_write() when converting incomplete
          multi-byte characters (Kevin Goodsell)
Solution: Make the buffer slightly larger

closes: vim/vim#19007

f99de42a9f

Co-authored-by: Christian Brabandt <cb@256bit.org>
(cherry picked from commit 444e1ffe3e)
2025-12-28 01:05:55 +00:00
zeertzjq
18f189a3f3 test(api/server_requests_spec): fix flaky test (again) (#37100)
(cherry picked from commit b7adf8081c)
2025-12-26 02:25:00 +00:00
Sean Dewar
648cf4e586 fix(autocmd): skip empty comma-separated patterns properly
Problem: empty comma-separated patterns in an aupat aren't skipped correctly.
Solution: skip consecutive commas in an aupat.

Also simplify the logic.

(cherry picked from commit 1cde71233f)
2025-12-26 02:21:20 +00:00
Sean Dewar
bea500dbeb fix(autocmd): parsing of comma-separated buflocal patterns
Problem: patterns after a buffer-local pattern in a comma-separated aupat are
         ignored.
Solution: ensure pat refers to the original buffer after each pattern, not the
          buflocal_pat buffer, and when printing make sure it's normalized for
          each pattern, not just the first.

Also simplify the logic when printing all autocommands for an event, and ensure
headings aren't repeated for each event when printing autocommands.

(cherry picked from commit 6d2330f50d)
2025-12-26 02:21:20 +00:00
phanium
bd2317f17f fix(lua): separate vim.{g,b,w,t} types #37081
Problem:
When `vim.g.foo = 1`, `vim.b.foo` also appears as
a completion candidate (when use emmylua_ls).

Solution:
Define separate types.

(cherry picked from commit 1aa26f5d55)
2025-12-23 16:08:39 +00:00
zeertzjq
fcdc984188 test(ui/inccommand_spec): don't check for transient message (#37078)
The check for v:errmsg is enough.

(cherry picked from commit c374d78095)
2025-12-23 01:01:42 +00:00
Sean Dewar
6338d2d54b fix(window): win_move_after UAF from naughty autocmds (#37065)
Problem: use-after-free in win_move_after if win_enter autocommands free win1/2.
Solution: set w_pos_changed before calling win_enter.

(cherry picked from commit d1189ea508, also adding
an import of "exec" in the test)
2025-12-22 09:38:38 +00:00
Jaehwang Jung
124c18261c fix(marks): wrong line('w$', win) with conceal_lines (#37047)
Background:
Suppose a window has concealed lines, and sets conceallevel>2,
concealcursor="". The concealed lines are displayed if the window is
curwin and the cursor is on the those lines.

Problem:
line('w$', win) switches curwin to win, and then does validate_botline
for curwin. It computes botline assuming the concealed lines displayed,
resulting in a smaller value than the actual botline that the user sees.

Solution:
Evaluate line('w$', win) without switching curwin.
Apply similar changes to other functions that switches curwin.

Co-authored-by: zeertzjq <zeertzjq@outlook.com>
(cherry picked from commit 033f1123cd)
2025-12-22 09:29:41 +00:00
zeertzjq
d1cd79a4b6 vim-patch:64799a5: runtime(doc): clarify the behavior of CTRL-Z
fixes: vim/vim#18975

64799a5080

Co-authored-by: Christian Brabandt <cb@256bit.org>
(cherry picked from commit 9b55f037d2)
2025-12-21 00:36:37 +00:00
zeertzjq
a93b5a7104 vim-patch:fe8c8b1: runtime(doc): fix outdated :function help
Since patch 7.4.264 a leading "g:" is skipped.

closes: vim/vim#18976

fe8c8b1e85
(cherry picked from commit 03aef8fd2a)
2025-12-21 00:36:37 +00:00
zeertzjq
275c769f01 fix(lua): don't remove first char of non-file stacktrace source (#37008) 2025-12-18 08:57:33 +08:00
Alejandro Exojo
df9452ea9e fix(man.lua): show_toc condition may cause infinite loop #36979
`lnum` gets set with `vim.fn.nextnonblank`, which returns 0 on failure,
and which is truthy on Lua.

(cherry picked from commit 46220afef8)
2025-12-15 23:05:19 +00:00
zeertzjq
6f84ea7c66 fix(buffer): switching buffer should respect jumpoptions+=view (#36969)
Also add missing change to buflist_findfmark() from #19224.

(cherry picked from commit 2700f6642a)
2025-12-15 07:40:48 +00:00
Shmerl
45cda1bcf4 fix(vim.loader): randomized AppImage path pollutes luac cache #36944
different approach to 78bbe53f76

(cherry picked from commit 1363ef7d50)
2025-12-14 23:02:44 +00:00
zeertzjq
69321879fe Merge pull request #36922 from zeertzjq/backport
Backport to release-0.11
2025-12-12 09:38:06 +08:00
zeertzjq
a66fce6fab vim-patch:98a0cbf: patch 9.1.1971: crash with invalid positional argument 0 in printf() (#36919)
Problem:  crash with invalid positional argument 0 in printf()
Solution: Reject positional arguments <= 0.

closes: vim/vim#18898

98a0cbf05b

Co-authored-by: Christian Brabandt <cb@256bit.org>
2025-12-12 08:49:19 +08:00
Justin M. Keyes
cfb586a77b docs(vimfn): fix vimdoc parser errors 2025-12-12 08:49:05 +08:00
zeertzjq
d1604e0f38 vim-patch:9.1.1969: Wrong cursor position after formatting with long 'formatprg' (#36918)
Problem:  Wrong cursor position after formatting with long 'formatprg'.
Solution: Don't show hit-enter prompt when there are stuffed characters.

Previously a stuffed character at the hit-enter prompt will dismiss the
prompt immediately and be put in the typeahead buffer, which leads to
incorrect behavior as the typeahead buffer is processed after the stuff
buffers. Using vungetc() when KeyStuffed is TRUE can fix this problem,
but since the hit-enter prompt isn't visible anyway (and is likely not
desired here), just skip the prompt instead, which also avoids a wait
when using "wait" instead of "hit-enter" in 'messagesopt'.

fixes:  vim/vim#18905
closes: vim/vim#18906

50325c3d59
(cherry picked from commit 18642a63be)
2025-12-12 00:45:44 +00:00
Olivia Kinnear
808d973fb0 feat(lsp): warn about unknown filetype #36910
(cherry picked from commit 054eaf8493)
2025-12-11 19:17:39 +00:00
Shmerl
91fd4d127e fix(vim.loader): randomized AppImage path pollutes luac cache #35636
Problem:
When using the Nvim appimage, `~/.cache/nvim/luac` directory can grow to
250,000+ files.

Example of 2 identical files in `./luac/`:

    %2ftmp%2f.mount_nvim.a65Rja0%2fusr%2fshare%2fnvim%2fruntime%2flua%2fvim%2ftreesitter.luac
    %2ftmp%2f.mount_nvim.aNpxXgo%2fusr%2fshare%2fnvim%2fruntime%2flua%2fvim%2ftreesitter.luac

Analysis:
The `nvim.appimage` mounts nvim at a different temporary path each time
it is invoked. The naming scheme of these cache files is random, which
defats the purpose of the cache creates N new files on every launch of
nvim.

Steps to reproduce:
1. install `nvim.appimage`
2. `mv ~/.cache/nvim/luac ~/.cache/nvim/luac.backup`
3. `nvim`
4. Observe contents of `~/.cache/nvim/luac/`
5. Close nvim and run `nvim` again
6. Observe contents of `~/.cache/nvim/luac/` and see that new identical
   files have been added with a different mount prefix

Solution:
When running from an appimage, trim the random part of the filepaths.

(cherry picked from commit 78bbe53f76)
2025-12-10 19:01:47 +00:00
skewb1k
83c589d95f fix(lua): relax vim.wait() timeout validation (#36907)
fix(lua): relax `vim.wait()` timeout validation #36900

Problem:
After bc0635a9fc `vim.wait()` rejects floats
and NaN values.

Solution:
Restore the prior behavior, while still supporting `math.huge`. Update
tests to cover float case.

(cherry picked from commit b87bdef2a8)
2025-12-10 11:09:24 -05:00
ymich9963
ec9e337479 docs(options): shell-powershell #36881
Problem:
Current options for powershell and pwsh had mistakes and rationale
behind them was not clear.

Solution:
Update the suggested options by splitting up powershell and pwsh, as
well as ensuring that all options work and rationale is documented and
discussed.

(cherry picked from commit d2e445e1bd)
2025-12-10 07:01:39 +00:00
zeertzjq
bcc6e13851 Merge pull request #36893 from zeertzjq/backport
ci: stop using macos-13 runner (#35996)
2025-12-10 09:59:18 +08:00
zeertzjq
7e99466a89 fix(eval): 0 should mean current tabpage in gettabvar() (#36891)
This matches the gettabvar() behavior change in Vim 8.1.1218.

(cherry picked from commit df9e4a037a)
2025-12-10 01:42:58 +00:00
skewb1k
9acbf5102f fix(lua): vim.wait(math.huge) fails #36885
Problem:
`nlua_wait()` uses `luaL_checkinteger()` which doesn't support
`math.huge` since it's double type. On PUC Lua this fails with
'number has no integer representation' error and on LuaJIT this
overflows int.

Solution:
Use `luaL_checknumber()` and handle `math.huge`.

(cherry picked from commit bc0635a9fc)
2025-12-09 23:20:22 +00:00
zeertzjq
c1c0078138 ci(cirrus): update to FreeBSD 14.3 (#36813)
(cherry picked from commit 6456a7cd1e)
2025-12-06 14:35:42 +00:00
zeertzjq
0706c55ab1 vim-patch:partial:9.1.1955: sort() does not handle large numbers correctly (#36840)
Problem:  sort() does not handle large numbers correctly
          (Igbanam Ogbuluijah)
Solution: Don't truncate the return value of tv_get_number_chk()
          (Yegappan Lakshmanan)

closes: vim/vim#18868

04794efe12

Use a Lua test for now, as the Vimscript test uses tuples.

Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
(cherry picked from commit 5370b7a2e0)
2025-12-06 14:30:09 +00:00
Anatolii Sakhnik
5ca2eb5e48 fix(remote): remote-ui connect timeout on slow networks #36800
Problem:
Connecting to a remote Neovim fails on slow network:

```
$ nvim --remote-ui --server 10.0.3.100:11111
Remote ui failed to start: connection refused
```

Strace reveals that the connection wasn't actually refused, but was still in progress:
```
15:52:50.678223 socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_IP) = 11
15:52:50.678278 setsockopt(11, SOL_TCP, TCP_NODELAY, [1], 4) = 0
15:52:50.678320 connect(11, {sa_family=AF_INET, sin_port=htons(11111), sin_addr=inet_addr("10.0.3.100")}, 16) = -1 EINPROGRESS (Дія зараз виконується)
15:52:50.678443 clock_gettime(CLOCK_MONOTONIC, {tv_sec=21736, tv_nsec=57625406}) = 0
15:52:50.678489 io_uring_enter(4, 3, 3, IORING_ENTER_GETEVENTS, NULL, 0) = 3
15:52:50.678544 epoll_pwait(3, [], 1024, 50, NULL, 8) = 0
15:52:50.728911 clock_gettime(CLOCK_MONOTONIC, {tv_sec=21736, tv_nsec=108159596}) = 0
15:52:50.729203 epoll_ctl(3, EPOLL_CTL_DEL, 11, 0x7ffd6ec9a3bc) = 0
15:52:50.729527 close(11)               = 0
```

Solution:
Increase hardcoded timeout from 50ms to 500ms.

(cherry picked from commit a141fd2c4d)
2025-12-02 16:59:27 +00:00