Commit Graph

833 Commits

Author SHA1 Message Date
Sean Dewar
1db945b584 fix(api): parse_expression crash with unopened ] and node
Problem: nvim_parse_expression null pointer dereference with unmatched ]
followed by a node.

Solution: if ast_stack was empty, set new_top_node_p to top of the stack after
pushing the list literal node; similar to what's done for curlies.

This bug was originally found by a Matrix user, but I couldn't remember how to
trigger it... Ran into the other crash while finding a repro. :P

(cherry picked from commit a5e5ec8910)
2026-01-17 13:48:49 +00:00
Sean Dewar
92849eacff fix(api): parse_expression crash with ident and curly
Problem: nvim_parse_expression null pointer dereference when parsing an
identifier followed by { with "highlight" parameter set to false.

Solution: only set opening_hl_idx if pstate->colors is not NULL.

Not added to parser_tests.lua as that uses highlight = true.

(cherry picked from commit 5226801be2)
2026-01-17 13:48:49 +00:00
Sean Dewar
10a1df2789 fix(api): nvim_get_option_value dummy buffer crashes
Problem: nvim_get_option_value with "filetype" set can crash if autocommands
open the dummy buffer in more windows, or if &bufhidden == "wipe".

Solution: Attempt to close all dummy buffer windows before wiping. Promote the
dummy buffer to a normal buffer if that fails.

(cherry picked from commit 7e2e116343)
2026-01-15 23:19:44 +00:00
Sean Dewar
6ce7b9b851 fix(api): autocmds mess up nvim_get_option_value's dummy buffer
Problem: When the "filetype" key is set for nvim_get_option_value, autocommands
can crash Nvim by prematurely wiping the dummy buffer, or cause options intended
for it to instead be set for unrelated buffers if switched during OptionSet.

Solution: Don't crash. Also quash side-effects from setting the buffer options.
(cherry picked from commit 3cb462a960)
2026-01-15 23:19:44 +00:00
zeertzjq
f21c169a02 fix(lua): vim._with() doesn't save boolean options properly (#37354)
Problem:  vim._with() doesn't save boolean options with false values
          properly.
Solution: Use vim.F.if_nil().
(cherry picked from commit 94144d4678)
2026-01-11 12:30:12 +00:00
zeertzjq
2a3cd8dc80 fix(rpc): don't overwrite already received results on error (#37339)
This fixes a regression from cf6f60ce4d
(possibly), as before that commit a frame is popped from the call stack
immediately after its response is received.

Also fix leaking the allocated error messages.

(cherry picked from commit 39d8aa0a1a)
2026-01-11 10:49:03 +00:00
zeertzjq
1b13864d97 test(server_notifications_spec): improve chanclose test (#37337)
Check that a pending event is actually cancelled, in place of the
nvim_subscribe that was removed in #28487.

(cherry picked from commit cb77bd1b86)
2026-01-10 04:37:36 +00: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
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
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
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
18f189a3f3 test(api/server_requests_spec): fix flaky test (again) (#37100)
(cherry picked from commit b7adf8081c)
2025-12-26 02:25:00 +00:00
zeertzjq
a6bc5780ac test(api/server_requests_spec): fix flaky test (again) (#36570)
Use a fast API, as a deferred API request may be aborted by EOF.

(cherry picked from commit c924d68021)
2025-11-16 10:38:51 +00:00
zeertzjq
b74f74ba20 test(api/server_requests_spec): fix flaky test (#36410)
Wait for the notification to be processed.

(cherry picked from commit 2b83237b0f)
2025-10-31 14:45:36 +00:00
zeertzjq
66b8018b06 fix(channel): closing socket with pending writes leaks memory (#36400)
Problem:  Closing socket with pending writes leaks memory.
Analysis: When calling rstream_may_close() on an RStream with pending
          writes, it waits for write_cb() to call stream_close_handle(),
          which closes it as if it's a WStream and doesn't free the
          RStream's buffer.
Solution: Ensure that an RStream's buffer is freed when it's closed.
2025-10-31 01:49:21 +00:00
Sean Dewar
f2fb46ef9e fix(api): nvim_open_win default to half-size for splits (#36088)
Problem: after #35601, nvim_open_win incorrectly attempts to set the size of a
split window to 0 if it wasn't specified.

Solution: only attempt to set the size again if it was actually specified. This has the effect of defaulting to half the size of the parent window (or it may be equalized with other windows to make room), like before.

Fix #36080

(cherry picked from commit d7472c0617)
2025-10-08 16:56:29 +00:00
glepnir
479bb9cbab fix(api): nvim_open_win respects requested split window size (#35601)
Problem: requested window size passed to nvim_open_win for splits may be ignored
by win_split_ins if it decides to forcefully equalize window sizes instead (e.g:
in an attempt to make room for the new window).

Solution: try to set the size again if it differs from what was requested.

Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
2025-10-04 10:18:48 +01:00
zeertzjq
2af99811f7 test: remove a few more redundant clear() calls 2025-10-03 16:14:14 +08:00
Sean Dewar
5aa6257e8c fix(api): win_set_config error message for splitting from a float #35650
Problem: after #34287 nvim_win_set_config no longer errors when attempting to
split from a floating window only if "win" is 0.

Solution: fix the regression, reduce the scope of "parent" and similar checks to
only where it's currently used and add test coverage for the errors.

(cherry picked from commit da39966a3a)
2025-09-08 17:18:48 +00:00
zeertzjq
27282696fe fix(api): fix not capturing output in cmdline mode (#35322)
(cherry picked from commit 7b9512e613)
2025-08-13 12:40:07 +00:00
glepnir
09b0003d38 fix(api): nvim_create_user_command addr option should allow ranges #35077
Problem: Using `addr` without `range` in nvim_create_user_command gives
"No range allowed" error, inconsistent with `:command -addr` behavior.

Solution: Set EX_RANGE flag when `addr` option is specified to match
`:command` behavior.

(cherry picked from commit 22df649210)
2025-08-03 03:40:46 +00:00
zeertzjq
a05b70baa6 fix(clipboard): correct blockwise register width computation (#35038)
(cherry picked from commit 95dfb063da)
2025-07-23 03:18:38 +00:00
luukvbaal
89959ab9dc fix(messages): recognize cmdline one_key/number prompt State (#34206)
Problem:  Since 48e2a736, prompt messages are handled by an actual
          active cmdline, resulting in `State` no longer being equal
          to `MODE_CONFIRM` which is used in some places. E.g. to
          specify the current `mode()` or to re-emit a confirm message.
Solution: Replace `MODE_CONFIRM` with a new `MODE_CMDLINE` sub-mode when
          `ccline.one_key/mouse_used` is set. Use it to avoid clearing
          mouse_used prompt messages, and to re-emit one_key messages
          (when ext_messages is inactive, for which this is unnecessary).
(cherry picked from commit e876a739ee)
2025-07-12 14:45:29 +00:00
zeertzjq
2ddb5d21bb test(api): nvim_get_keymap returns correct lhsraw and lhsrawalt
(cherry picked from commit 0c973bf442)
2025-07-08 00:29:05 +00:00
luukvbaal
742ea00742 fix(window): don't enter unfocusable or hidden prevwin (#34486)
Problem:  When closing a floating window, the next window to be entered
          may be unfocusable or hidden.
Solution: Don't enter prevwin when it is unfocusable or hidden. Enter
          firstwin instead (like for when prevwin is no longer valid).
(cherry picked from commit 0d658660c2)
2025-06-14 22:19:32 +00:00
luukvbaal
8d3b7b57c8 fix(api): update topline when flushing with nvim__redraw() (#34346)
Problem:  nvim__redraw may update the screen with an invalid topline.
Solution: Update the topline before calling `update_screen()` (as
          :redraw does).
(cherry picked from commit af82f36108)
2025-06-07 11:35:59 +00:00
glepnir
f2c4305114 fix(api): add missing nargs field to user command Lua callbacks #34210
Problem: nvim_create_user_command() Lua callbacks were missing the documented nargs field in the options table passed to the callback function.

Solution: Add nargs field derivation from command argument type flags in nlua_do_ucmd(), using the same logic as nvim_parse_cmd().
(cherry picked from commit 5cfbc35aa8)
2025-06-01 23:18:32 +00:00
Sean Dewar
9965cfb84c vim-patch:9.1.1361: [security]: possible use-after-free when closing a buffer (#33820)
Problem:  [security]: Possible to open more windows into a closing
          buffer without splitting, bypassing existing "b_locked_split"
          checks and triggering use-after-free
Solution: Disallow switching to a closing buffer. Editing a closing
          buffer (via ":edit", etc.) was fixed in v9.1.0764, but add an
          error message and check just "b_locked_split", as "b_locked"
          is necessary only when the buffer shouldn't be wiped, and may
          be set for buffers that are in-use but not actually closing.
          (Sean Dewar)

closes: vim/vim#17246

6cb1c82840
(cherry picked from commit 627c648252)
2025-05-10 17:07:31 +00:00
luukvbaal
fb71d631a5 fix(api): wrong return value with reverse range + overlap #32956
Problem:  When iterating in reverse with {start} > {end} in
          `nvim_buf_get_extmarks()`, marks that overlap {start} and are
          greater than {end} are included in the return value twice.
          Marks that overlap {end} and do not overlap {start} are not
          not included in the return value at all. Marks are not
          actually returned in a meaningful "traversal order".

Solution: Rather than actually iterating in reverse, (also possible but
          requires convoluted conditions and would require fetching
          overlapping marks for both the {start} and {end} position,
          while still ending up with non-traversal ordered marks),
          iterate normally and reverse the return value.
(cherry picked from commit 65170e8dad)
2025-04-21 23:49:27 +00:00
zeertzjq
e4007551c4 fix(completion): avoid freeing uninitialized value (#33459)
(cherry picked from commit 51caf0a3af)
2025-04-14 05:31:00 +00:00
tstsrt
5fc6bd6454 fix(api): nvim_set_keymap() throws error even in pcall() #33228
Problem: When `nvim_set_keymap` tries to overwrite a `<unique>` mapping,
it throws an error even when called in `pcall`.

Solution: src/nvim/mapping.c:buf_do_map no longer calls `semsg`. Its
callers now decide whether to ignore the error, or use
`semsg` (not caught)/`api_set_error` (caught by `pcall`).

(cherry picked from commit ec18ebcb41)
2025-04-01 15:50:54 +00:00
zeertzjq
2b2a90051e fix(api): use E226 instead of E227 for duplicate abbreviation (#33159)
(cherry picked from commit 99529577cc)
2025-04-01 15:04:03 +00:00
Gregory Anders
056dbf3ea7 fix(api): use original LHS in keymap error message #33135
When setting a keymap with "unique" that already exists the error
message contains the LHS of the keymap with termcodes replaced. In
particular this means that keys like <Tab> show as an actual tab
character, meaning the error message displays as "Mapping already exists
for ", which is hard to debug for users.

Instead, display the original LHS (without any simplification or parsed
termcodes). This rperesents exactly what the user passed to the `lhs`
argument of `nvim_set_keymap`, which makes it easier to find where the
offending keymap is.

(cherry picked from commit 0d73ec5834)
2025-03-29 13:48:06 +00:00
Au.
9516997eb0 fix(paste): wrong '[ mark after pasting a big string (streamed chunks) #33025
Problem
Pasting a big string ("streamed paste" with multiple chunks) sets the '[
mark to the edit from the last chunk, instead of the start of the paste.

Solution:
Set the '[ mark where the paste started, not where the last chunk was
inserted.

Note: `startpos == nil` is not equal to `phase == 1` because there may
be some empty chunks pasted which won't arrive here (returned at code
before).
2025-03-23 16:10:42 -07:00
glepnir
0e59f6f4c7 fix(api): don't use 'winborder' when reconfiguring float (#32984)
Problem: Reconfiguring a float window applies the global 'winborder'.
Solution:
- Ignore 'winborder' when reconfiguring a float window.
- Still apply 'winborder' when converting a split to a float window.
2025-03-19 12:16:20 +00:00
zeertzjq
63bbb7c109 fix(api): fix 'winborder' preventing splits with nvim_open_win (#32981)
While at it, rename the p_winbd variable to p_winborder, as 'winbd' is
not the option's short name.

Co-authored-by: glepnir <glephunter@gmail.com>
2025-03-19 07:28:24 +00:00
Gregory Anders
b31132f1c1 feat(defaults): jump between :terminal shell prompts with ]]/[[ #32736 2025-03-07 05:45:34 -08:00
zeertzjq
6750d00fe9 vim-patch:8.2.4603: sourcing buffer lines is too complicated
Problem:    Sourcing buffer lines is too complicated.
Solution:   Simplify the code. Make it possible to source Vim9 script lines.
            (Yegappan Lakshmanan, closes vim/vim#9974)

85b43c6cb7

This commit changes the behavior of sourcing buffer lines to always have
a script ID, although sourcing the same buffer always produces the same
script ID.

vim-patch:9.1.0372: Calling CLEAR_FIELD() on the same struct twice

Problem:  Calling CLEAR_FIELD() on the same struct twice.
Solution: Remove the second CLEAR_FIELD().  Move the assignment of
          cookie.sourceing_lnum (zeertzjq).

closes: vim/vim#14627

f68517c167

Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
2025-02-28 18:21:08 +08:00
Luuk van Baal
f58e7d5fac feat(marks): add conceal_lines to nvim_buf_set_extmark()
Implement an extmark property that conceals lines vertically.
2025-02-25 13:09:01 +01:00
zeertzjq
51cf84daf9 feat(marks): virtual lines support horizontal scrolling (#32497)
Add a new field `virt_lines_overflow` that enables horizontal scrolling
for virtual lines when set to "scroll".
2025-02-20 21:47:12 +08:00
Cai Rijun (Richard)
ad60b3fb48 fix(api): memory leaks in vim.api.nvim_*get_option #32390
Problem: `get_option_value` returns caller owned `Object`s but the
corresponding C apis do not marked `FUNC_API_RET_ALLOC` properly.

Solution: add `FUNC_API_RET_ALLOC` to the C apis.
2025-02-10 09:37:36 -08:00
zeertzjq
4317d36669 fix(event-loop): process input before events in getchar() (#32322)
Follow-up to #27358.
2025-02-05 06:48:56 +08:00
glepnir
d84a95da7e feat(api): nvim_get_autocmds filter by id#31549
Problem:
nvim_get_autocmds cannot filter by id.

Solution:
Support it.
2025-01-26 15:28:33 -08:00
Luuk van Baal
34d808b73c feat(api): combined highlights in nvim_eval_statusline()
Problem:  Combined highlighting was not applied to nvim_eval_statusline(),
          and 'statuscolumn' sign segment/numhl highlights.
Solution: Add an additional `groups` element to the return value of
          `nvim_eval_statusline()->highlights`. This is an array of stacked
          highlight groups (highest priority last). Also resolve combined
          highlights for the 'statuscolumn' sign segment/numhl highlights.
          Expose/synchronize some drawline.c logic that is now mimicked in
          three different places.
2025-01-23 10:56:25 +01:00
bfredl
71922cd1dc Merge pull request #31597 from bfredl/deletionism
fix(wininfo): when freeing windows, free the lowest priority wininfo
2025-01-20 11:02:58 +01:00
luukvbaal
5cc93ef472 fix(marks): revise metadata for start mark of revalidated pair #32017
Problem:  Metadata may be revised for end mark of a revalidated pair.
Solution: Revise metadata for start mark of a revalidated pair.
2025-01-15 02:38:45 -08:00
bfredl
59da82abd9 fix(wininfo): when freeing windows, free the lowest priority wininfo
On master (and also before #31539) closing a window could cause the
used wininfo for a buffer to change. This is due to always removing the
previous NULL wininfo when deleting a window, even if that wininfo had
higher priority than the the deleted window's own wininfo.

Instead delete the wininfo with lowest priority. This retains the memory
saving efect while not affecting the effective value of window options
and so on.
2025-01-14 14:47:35 +01:00