Commit Graph

9890 Commits

Author SHA1 Message Date
glepnir
88dc44260f fix(api): preserve WinConfig style when converting float to split #37264
Problem: When a float window with style='minimal' is converted to a
split window and then changes buffer, the minimal style options get
overridden. This happens because merge_win_config() clears the style
field, so get_winopts() doesn't know to re-apply minimal style after
restoring options from the buffer's wininfo.

Solution: Save and restore the style field when clearing the config
during float-to-split conversion.
2026-02-12 20:23:30 -05:00
zeertzjq
cc7022c544 fix(terminal): scrollback may still be wrong on height increase (#37835)
Problem:  Terminal scrollback may be wrong when increasing height after
          outputting lines with full scrollback.
Solution: Ensure enough number of scrollback lines have been deleted.
2026-02-13 01:06:23 +00:00
zeertzjq
39d8a9c353 vim-patch:9.1.2146: filetype: cel files are not recognized (#37834)
Problem:  filetype: cel files are not recognized
Solution: Detect *.cel files as cel filetype (Stefan VanBuren).

Reference:
https://cel.dev/
e36c49febc/testing/src/test/resources/expressions/coverage_test_case/simple_expression.cel
d0d2dbabae/example.cel

closes: vim/vim#19381

fb5777fa20

Co-authored-by: Stefan VanBuren <svanburen@buf.build>
2026-02-13 08:34:00 +08:00
Kevin Goodsell
fa24df3264 fix(bufwrite.c): handle invalid byte sequences #37363
Problem:

bw_rest was used as an extra buffer to save incomplete byte sequences
between calls to buf_write_bytes. Besides being unnecessarily
complicated, this introduced a number of issues:

1) The bytes stored in bw_rest could still be there at the end of
writing the file, never having been written, thus losing some of the
file content on write.

2) bw_rest was not cleared out after the "checking_conversion" phase,
leaving them to affect the written file content during the writing
phase, corrupting the file.

3) bw_rest could contain extra bytes that need to be written to the
output buffer during a buf_write_convert call, potentially before any
bytes are consumed. But some conversions are in-place, without a
separate output buffer. Writing bytes from bw_rest to the "output"
buffer actually overwrote bytes from the input buffer before they were
read, corrupting the data to be written.

4) The extra bytes in bw_rest that need to be written to the conversion
output buffer were not originally accounted for in the size calculation
for the output buffer, causing a buffer overflow (previously fixed in
Vim patch 9.1.2028).

Solution:

Rather than maintaining a separate buffer, the unconverted bytes at the
end of the buffer can just be shifted to the beginning of the buffer,
and the buffer size updated. This requires a bit of refactoring, and
buf_write_convert and buf_write_convert_with_iconv need to report the
number of bytes they consumed so that buf_write_bytes can handle the
remaining bytes.

Following conversion, bw_buf can be checked for any remaining bytes.
Leftover bytes in this case result in a conversion error, which is
better than silently dropping them.

A short section of dead code was removed from buf_write_convert, for
converting a non-UTF-8 buffer to UTF-8. Neovim buffers are always UTF-8.

A few additional tests for iconv conversions have been added. Vim's
iconv tests are disabled in Neovim because they use unsupported values
for 'encoding'.
2026-02-12 17:38:11 -05:00
Elijah Koulaxis
8a0cbf04d6 feat(iter): peek(), skip(predicate) for non-list iterators #37604
Problem:
Iter:peek() only works if the iterator is a |list-iterator| (internally, an `ArrayIter`).
However, it is possible to implement :peek() support for any iterator.

Solution:
- add `_peeked` buffer for lookahead without actually consuming values
- `peek()` now works for function, pairs(), and array iterators
- `skip(predicate)` stops at the first non matching element without consuming it
- keep existing optimized behavior for `ArrayIter` to maintain backward compatibility
- use `pack`/`unpack` to support iterators that return multiple values
2026-02-12 11:55:16 -05:00
phanium
179e7fccd7 fix(ui2): incomplete :echon message in g< pager #37819
Problem:
`:echo 1 | echon 2<cr>g<` shows "2", but should be "12".

Solution:
Don't clear temp msg (g<) if we are appending.
2026-02-12 11:10:37 -05:00
Justin M. Keyes
858576777e docs: lsp, options, promptbuf
Close #37630
Close #37682
Close #37762
Close #37785

Co-authored-by: Daniel Schmitt <d.schmitt@lansoftware.de>
Co-authored-by: Duane Hilton <duane9@gmail.com>
Co-authored-by: NeOzay <colpaert.benoit@gmail.com>
Co-authored-by: Yi Ming <ofseed@foxmail.com>
Co-authored-by: "Justin M. Keyes" <justinkz@gmail.com>
2026-02-12 13:46:45 +01:00
zeertzjq
16da47f474 fix(terminal): changing height may lead to wrong scrollback (#37824)
Problem:  Changing terminal height immediately after outputting lines
          may lead to wrong scrollback.
Solution: Insert pending scrollback lines before the old window height.
2026-02-12 20:10:02 +08:00
zeertzjq
60730482fe test(testterm): remove useless TermCursor highlight definition (#37827)
TermCursor already has cterm=reverse. Additionally, now that terminal
buffers have a real cursor, the cterm=reverse in TermCursor no longer
shows up in the screen state.
2026-02-12 17:31:12 +08:00
skewb1k
6b4ec2264e feat(stdlib): vim.json.decode() can allow comments #37795
Problem:
`vim.json.decode()` could not parse JSONC (JSON with Comments)
extension, which is commonly used in configuration files.

Solution:
Introduce an `skip_comments` option, which is disabled by default. When
enabled, allows JavaScript-style comments within JSON data.
2026-02-11 06:54:57 -05:00
zeertzjq
886efcb853 fix(channel): possible hang after connecting with TCP times out (#37813)
Problem:  Possible hang after connecting with TCP times out.
Solution: Wait for the close callback to arrive.
2026-02-11 02:48:03 +00:00
zeertzjq
64ce5382bd fix(channel): crash on failed sockconnect() (#37811)
Problem:  Crash on failed sockconnect() if a new connection is accepted
          while polling for uv events.
Solution: Don't use channel_destroy_early().

Also test "tcp" mode failure properly.
2026-02-11 01:34:38 +00:00
Olivia Kinnear
0c46ea7d38 feat(lua): add Iter:unique() (#37592) 2026-02-10 11:43:47 -06:00
Evgeni Chasnovski
14c708634e fix(vim.fs): make rm() work with symlink to a directory 2026-02-10 16:40:12 +00:00
Yochem van Rosmalen
a6252c6683 refactor(help): move escaping logic to Lua #37757
Problem:
Escaping logic for {subject} in ex cmd `:help {subject}` is done in a
messy 200+ lines C function which is hard to maintain and improve.

Solution:
Rewrite in Lua. Use `string.gsub()` instead of looping over characters
to improve clarity and add many more tests to be able to confidently
improve current code later on.
2026-02-10 07:43:17 -05:00
glepnir
31c45f1aa4 test: move deprecated highlight API tests #37801
Problem: Tests for deprecated highlight API were mixed with current API tests.

Solution: Move them to deprecated_spec.lua and update highlight_spec.lua to use nvim_get_hl.
2026-02-10 05:38:13 -05:00
zeertzjq
54468c1c3c fix(terminal): wrong scrollback with nvim_open_term() on buffer (#37791)
Problem:  Wrong scrollback when passing a buffer with many lines to
          nvim_open_term().
Solution: Delete all buffer lines before opening the terminal.

I tried to use buf_clear(), but it crashes inside deleted_lines_mark(),
so I'll just use deleted_lines_buf() for now. The behavior of marks can
be decided later.
2026-02-10 06:30:02 +08:00
phanium
9f77124b78 fix(lsp): error on omnifunc completion (#37790)
Problem:
After eaacdc9, complete with emmylua_ls error with:
runtime/lua/vim/lsp/completion.lua:586: attempt to get length of field
'items' (a nil value)

Solution:
Result can be CompletionItem[] according the spec:
> If a `CompletionItem[]` is provided, it is interpreted to be complete,
> so it is the same as `{ isIncomplete: false, items }`
2026-02-09 09:45:21 -08:00
Sean Dewar
1b627f6c59 fix(terminal): set b_locked when setting &buftype (#37787)
Problem: heap use-after-free if OptionSet autocommands from setting a terminal's
&buftype wipe the buffer.

Solution: set b_locked during OptionSet for &buftype.
2026-02-09 12:51:04 +00:00
Nanashi.
7ee41a4b33 test: add failing case for screenrow/screencol #37761 2026-02-09 07:19:50 -05:00
zeertzjq
e254688016 fix(terminal): handle ED 3 (clear scrollback) properly (#21412)
Problem:  Terminal doesn't handle ED 3 (clear scrollback) properly.
Solution: Add vterm callback for sb_clear().

Also fix another problem that scrollback lines may be duplicated when
pushing to scrollback immediately after reducing window height, as can
be seen in the changes to test/functional/terminal/window_spec.lua.
2026-02-09 11:28:00 +00:00
Sean Dewar
19379d1255 fix(autocmd): deferred TermResponse lacks "data", may not fire (#37778)
Problem: TermResponse deferred due to blocked autocommands lacks "data" payload.
Also, it may not fire if a new v:termresponse reuses the same string address.

Solution: add it. Use the value of v:termresponse for "data.sequence". Replace
pointer comparisons with a flag.

The removal of "old_termresponse" comparisons is required to pass the test on
the CI, or locally for me when compiled in RelWithDebInfo.
2026-02-08 21:43:50 +00:00
Tomasz N
eaacdc9bdf fix(lsp): ignore empty response on trigger completion #37663
Problem:
Empty response affects server start boundary computed before.

Solution:
Ignore empty responses. This is mostly micro-optimization that avoids
extending existing results with empty responses.
2026-02-08 16:25:47 -05:00
GenchoXD
9c8d06e086 test(lsp/diagnostic): clearing diagnostics #37759
Problem:
Diagnostic lifecycle invariants (clearing on empty publish and buffer
deletion) were previously implicit and not directly covered by functional
tests, allowing regressions to go unnoticed.

Solution:
Add functional regression tests asserting that diagnostics are cleared
when an LSP server publishes an empty diagnostic set and when the
associated buffer is deleted. Assertions are scoped to the client
diagnostic namespace and use public diagnostic APIs only.
2026-02-08 16:22:13 -05:00
Mike J McGuirk
15ff454443 feat(lsp): display codelens as virtual lines, not virtual text #36469
Problem: Code lenses currently display as virtual text on the same line
and after the relevant item. While the spec does not say how lenses
should be rendered, above the line is most typical. For longer lines,
lenses rendered as virtual text can run off the side of the screen.

Solution: Display lenses as virtual lines above the text.

Closes https://github.com/neovim/neovim/issues/33923

Co-authored-by: Yi Ming <ofseed@foxmail.com>
2026-02-08 16:10:41 -05:00
Sean Dewar
1519a34e43 fix(terminal): autocmds leave terminal open to wiped buffer
Problem: if buf_free_all autocommands open a terminal, it will remain open after
the buffer is freed.

Solution: close terminals again later, this time while blocking autocommands.

Did consider terminal_open checking stuff like b_locked_split instead, but
that's set during BufHidden, etc., which doesn't mean the buffer's being wiped.
2026-02-08 16:12:00 +00:00
Sean Dewar
da8de99d0b fix(window): use real last buffer of closed window
Problem: close_buffer autocmds may switch buffers at the last moment when
closing a window, causing terminal_check_size to prefer the size of a closed
window, or TabClosed to set an old <abuf>.

Solution: use the actual last buffer, similar to what TabClosed did before.

NOTE: If buffer was unloaded/deleted (not wiped), then TabClosed's <abuf> may
not use it. (w_buffer = NULL) Maybe odd, but it's how it worked before anyhow.

Relies on close_buffer reliably setting w_buffer to NULL if freed, otherwise
buf_valid is better. Only concern I see is if the window wasn't in the window
list after closing the buffer (close_buffer won't set it to NULL then), but then
win_close{_othertab} should've returned earlier.
2026-02-08 16:12:00 +00:00
Sean Dewar
d945a93d69 fix(autocmd): potential TabClosed UAF, always set abuf
Problem: win_free_mem can free w_buffer (via qf_free_all), which may cause a
heap use-after-free if used as TabClosed's <abuf>. I think TabClosed is also the
only event to conditionally set <abuf> not based on event type.

Solution: use the buffer saved by the bufref. Fall back to curbuf if invalid,
like WinResized/WinScrolled.

NOTE: Not always equivalent if close_buffer autocmds switch buffers at the last
moment; previously <abuf> would be set to that buffer. Fixed in next commit.

https://github.com/neovim/neovim/actions/runs/21765657455/job/62800643599?pr=37758#step:9:159
for an example of qf_free_all being a nuisance.
2026-02-08 16:12:00 +00:00
Sean Dewar
5c156fdc64 fix(terminal): update size after closing window
Problem: terminal's size may not update after one of its windows close.

Solution: call terminal_check_size after closing a window.

Disable test for Windows, as for some reason it only shows a few lines...
2026-02-08 16:12:00 +00:00
luukvbaal
4260f73e13 fix(messages): unwanted newlines with ext_messages #37733
Problem:  Newlines intended to write messages below the cmdline or to
          mark the start of a new message on message grid are emitted
          through ext_messages. This results in unnecessary newlines for
          a UI that has decoupled its message area from the cmdline.
          msg_col is set directly in some places which is not transmitted
          to msg_show events.
          Various missing message kind for list commands.
          Trailing newlines on various list commands.

Solution: Only emit such newlines without ext_messages enabled.
          Use msg_advance() instead of setting msg_col directly.
          Assign them the "list_cmd" kind.
          Ensure no trailing newline is printed.
2026-02-08 09:47:02 -05:00
Evgeni Chasnovski
0f73873d4f fix(pack): close confirmation buffer, not tabpage #37756 2026-02-08 09:15:16 -05:00
Sean Dewar
c90593ed5f test(terminal): skip flaky test on Windows (#37774)
Ref: https://github.com/neovim/neovim/pull/37758#discussion_r2778065203
2026-02-08 02:27:30 +00:00
zeertzjq
a9454f8511 test(api/server_requests_spec): fix flaky test (#37771)
Sometimes the scheduled :qall can arrive too late, so that EOF isn't
received in the same uv_run() call as the response.
2026-02-08 00:49:13 +00:00
zeertzjq
ed8fbd2e29 vim-patch:9.1.2138: win_execute() and 'autochdir' can corrupt buffer name (#37767)
Problem:  With 'autochdir' win_execute() can corrupt the buffer name,
          causing :write to use wrong path.
Solution: Save and restore b_fname when 'autochdir' is active
          (Ingo Karkat).

This is caused by a bad interaction of the 'autochdir' behavior,
overriding of the current directory via :lchdir, and the temporary
window switching done by win_execute(), manifesting when e.g. a custom
completion inspects other buffers:
1. In the initial state after the :lcd .. we have curbuf->b_fname =
   "Xsubdir/file".
2. do_autochdir() is invoked, temporarily undoing the :lcd .., changing
   back into the Xsubdir/ subdirectory.
3. win_execute() switches windows, triggering win_enter_ext() →
   win_fix_current_dir() → shorten_fnames(TRUE)
4. shorten_fnames() processes *all* buffers
5. shorten_buf_fname() makes the filename relative to the current
   (wrong) directory; b_fname becomes "file" instead of "Xsubdir/file"
6. Directory restoration correctly restores working directory via
   mch_chdir() (skipping a second do_autochdir() invocation because
   apply_acd is FALSE), but b_fname remains corrupted, with the
   "Xsubdir/" part missing.
7. expand("%:p") (and commands like :write) continue to use the
   corrupted filename, resolving to a wrong path that's missing the
   "Xsubdir/" part.

To fix the problem the short filename is saved if its in effect (i.e.
pointed to by curbuf->b_fname) and 'autochdir' happened. It's then
restored in case of a local cwd override. The conditions limit this
workaround to when 'autochdir' is active *and* overridden by a :lchdir.

closes: vim/vim#19343

abb4d74033

Co-authored-by: Ingo Karkat <swdev@ingo-karkat.de>
2026-02-08 07:04:36 +08:00
zeertzjq
72eb9fe87c vim-patch:partial:9.1.2137: test: Update tests for OpenBSD (#37766)
Problem:  Some tests are not valid on OpenBSD.
Solution: Add CheckNotOpenBSD, use it to skip certain tests
          (Kevin Goodsell).

Test_readdirex_sort performs locale-dependent sorting. OpenBSD has
minimal locale support.

Test_stdin_no_newline hangs on OpenBSD and FreeBSD. I don't know exactly
why, but it may be due to bash not exiting at the end of the test. This
is skipped in the FreeBSD CI runs because bash is not installed.

Test_detect_fifo uses /dev/fd/ files (via process substitution) as
FIFOs. On OpenBSD the files in /dev/fd are not FIFOs.

closes: vim/vim#19351

a24cb278bd

Co-authored-by: Kevin Goodsell <kevin-opensource@omegacrash.net>
2026-02-08 07:03:41 +08:00
zeertzjq
e704529909 vim-patch:9.1.2136: :tab sbuffer may close old tabpage (#37765)
Problem:  :tab sbuffer may close old tabpage if BufLeave autocommand
          splits window (after 9.1.0143).
Solution: Only close other windows if the buffer will be unloaded
          (zeertzjq).

related: neovim/neovim#37749
closes: vim/vim#19352

6da9f757c4
2026-02-07 23:03:21 +08:00
Justin M. Keyes
7720e52a0b Merge #37424 $XDG_CONFIG_DIRS with init.lua, $NVIM_APPNAME 2026-02-06 13:28:43 -05:00
horrifyingHorse
ba6440c106 fix(terminal): reset w_leftcol after resizing terminal
Problem: windows may scroll horizontally upon resize using the old terminal
size, which may be unnecessary and cause the content to be partially out-of-view.

Solution: reset the horizontal scroll after resizing.
2026-02-06 15:50:05 +00:00
Jesse van der Pluijm
5c51b45a82 fix(startup): respect $NVIM_APPNAME in $XDG_CONFIG_DIRS paths
Problem:

$NVIM_APPNAME was not respected when searching $XDG_CONFIG_DIRS for
config files. Nvim hardcoded "nvim" when constructing paths like
`$XDG_CONFIG_DIRS/nvim/init.lua`, ignoring the $NVIM_APPNAME environment
variable.

This meant that config files like `$XDG_CONFIG_DIRS/myapp/init.lua` were
not loaded, even though $NVIM_APPNAME was set to "myapp".

Solution:

Use `get_appname()` instead of hardcoded "nvim" for $XDG_CONFIG_DIRS
paths in `do_system_initialization()` and `do_user_initialization()`.
This makes $XDG_CONFIG_DIRS behave consistently with $XDG_CONFIG_HOME,
which already respected $NVIM_APPNAME.

As documented in `runtime/doc/starting.txt` (L1440-L1441):
"In the help wherever `$XDG_CONFIG_…/nvim` is mentioned it is understood
as `$XDG_CONFIG_…/$NVIM_APPNAME`."

See:
43339dee40/runtime/doc/starting.txt (L1440-L1441)

Relates to #37405
2026-02-06 16:12:01 +01:00
Jesse van der Pluijm
c785d5cdf0 fix(startup): source init.lua from XDG_CONFIG_DIRS
Problem:

`init.lua` files in `$XDG_CONFIG_DIRS` directories were not being sourced during startup, even though the documentation states they should be searched alongside `init.vim`.

See:

e51f5e17e1/runtime/doc/starting.txt (L495-L496)

Solution:

Modify `do_user_initialization()` to search for `init.lua` in each `$XDG_CONFIG_DIRS` directory before falling back to `init.vim`, matching the behavior for `$XDG_CONFIG_HOME`. Also show `E5422` error if both `init.lua` and `init.vim` exist in the same directory.

Fixes #37405
2026-02-06 16:11:22 +01:00
luukvbaal
a33e5fb1bb fix(ui): cmdline_block events for exmode #37751
Problem:  Exmode is missing cmdline_block events.
Solution: Emit cmdline_block_show/append when executing a cmdline during
          exmode. Emit cmdline_block_hide when leaving exmode.
2026-02-06 08:10:33 -05:00
zeertzjq
6dd0a7d60a vim-patch:9.1.2135: tests: tar plugin does not consider 'nowrapscan' (#37752)
Problem:  search() is used to check for the message from tar that
          indicates leading slashes found in the tar archive, or to
          check for the leading slashes themselves. However, if
          'nowrapscan' is in effect these searches are limited to the
          last line and don't find any results. This causes the warning
          message from tar to be seen in the buffer, the "Path Traversal
          Attack Detected" message to be omitted, and editing actions
          can fail. This can be seen, for example, when editing
          src/testdir/samples/evil.tar.
Solution: Use the 'w' flag for search() (Kevin Goodsell)

closes: vim/vim#19333

18d844e365

Co-authored-by: Kevin Goodsell <kevin-opensource@omegacrash.net>
2026-02-06 20:25:14 +08:00
zeertzjq
15061d322d vim-patch:9.1.2133: Another case of buffer overflow with 'helpfile' (#37746)
Problem:  Another case of buffer overflow with 'helpfile'.
Solution: Leave room for "tags" in the buffer (zeertzjq).

closes: vim/vim#19340

21d591fb12
2026-02-06 18:29:24 +08:00
zeertzjq
db133879b2 vim-patch:9.1.2132: [security]: buffer-overflow in 'helpfile' option handling (#37735)
Problem:  [security]: buffer-overflow in 'helpfile' option handling by
          using strcpy without bound checks (Rahul Hoysala)
Solution: Limit strncpy to the length of the buffer (MAXPATHL)

Github Advisory:
https://github.com/vim/vim/security/advisories/GHSA-5w93-4g67-mm43

0714b15940

Co-authored-by: Christian Brabandt <cb@256bit.org>
2026-02-06 07:40:51 +08:00
zeertzjq
e40c5cb06d fix(vterm): handle split UTF-8 after ASCII properly (#37721)
Problem:  libvterm doesn't handle split UTF-8 sequence after ASCII.
Solution: Only use one UTF-8 encoding state per vterm state.
2026-02-06 07:28:26 +08:00
luukvbaal
e198037148 fix(ui2): always route to dialog when cmdline is open #37730
Problem:  Messages emitted while cmdline is open are not shown with
          cmdline message target.
Solution: Route to dialog window when cmdline is open.
2026-02-05 14:54:22 -05:00
luukvbaal
7a490d65c5 fix(messages): increment message ID without ext_messages #37714
Problem:  Message ID is not incremented without ext_messages.
Solution: Increment where callstack reaches without ext_messages.
          There is no clear place marking the end of internal
          messages without ext_messages so IDs are only incremented
          with `nvim_echo` calls. Message IDs are currently not exposed
          anywhere but the msg_show event for this to matter.
2026-02-05 09:55:11 -05:00
luukvbaal
f1dcde6cba fix(messages): single msg_show event for :global command #37728
Problem:  "first" parameter added in 912388f5 for grouping printed lines
          in a single event is ineffective for the :global command.
Solution: Only set the message kind for the first printed line during a
          :global command.
2026-02-05 08:37:20 -05:00
luukvbaal
bf68ba40a0 refactor: rename _extui => _core.ui2 #37692
Problem:
_extui module name is confusing and should eventually end up in _core/.

Solution:
Move it there and name it ui2.
2026-02-05 07:45:45 -05:00
zeertzjq
b95e0a8d20 test(terminal/cursor_spec): fix flaky test (#37715)
Problem:  Cursor visibility test may fail if the :sleep lasts too long.
Solution: Wait for the TermLeave autocommand to finish.
2026-02-05 14:27:15 +08:00