Problem: On some systems `stderr` can be disabled. This results in not
usable `vim.pack` since it asserted `stderr` to be non-nil.
Solution: Stop asserting non-nil `stderr`. The downside is that
potential errors are not shown, but this is intentional since `stderr`
is disabled on system level.
Still assert non-nil `stdout` as its output is important for
`vim.pack` to actually do its job. Disabled `stdout` is not something
that can work with `vim.pack`.
(cherry picked from commit 25d33dd12b)
Problem:
When buffers are by default `nomodifiable`, such as when Nvim starts with
`-M`, the health buffer cannot be updated.
Solution:
Always set `modifiable` before modifying the buffer.
(cherry picked from commit 0f86ea5ed8)
fix(lsp): use LspNotify for document_color #40571
Problem: The document_color lsp module was already using the capability
framework but was still using raw buffer events to handle requests and
reloading. This means that every keystroke was sending a document_color
request to the server since there was no debounce in the raw handlers.
Solution: Switch to using LspNotify autocmd events. LspNotify fires just
after new document versions are synced with the server and provides a
built in debounce mechanism for changes. It also provides the signal for
when the current state should be cleared (didClose). The detach part is
already handled by the capability framework.
Fixes#39785
(cherry picked from commit 29db6ce84c)
Problem: Session with multiple tabpages sets 'winminheight' to 0.
Solution: Only save 'winminheight' and 'winminwidth' once (zeertzjq).
related: vim/vim#8119
related: neovim/neovim#40493closes: vim/vim#20673294dec827d
(cherry picked from commit c040f53dc1)
Problem: A previous refactor removed the BufWinEnter autocmd that
initiated a token request. When an LSP server sends a refresh
notification, then buffers that aren't shown in any window lost their
only trigger to request new tokens.
Solution: Add the BufWinEnter autocmd back which simply requests tokens
for all clients attached to the buffer.
Problem: changed_lines got a hardcoded 0, so the changelist entry
and '. mark always recorded column 0 instead of where the edit
actually happened.
Solution: pass start_col instead. changelist now tracks the real
column.
(cherry picked from commit 7312df77bb)
Problem:
On Windows, channel jobs inherit Nvim's stdio, so a background job
writing to CON (e.g. gutentags) draws onto the TUI and stays until
redraw.
Solution:
Give Windows job stdin/stderr libuv-created pipes (UV_CREATE_PIPE)
instead of inherited fds, so libuv spawns the child with
CREATE_NO_WINDOW and CON writes no longer leak onto the TUI.
(cherry picked from commit 39e9c1754a)
Problem: [security]: With C omni-completion, a crafted tags file can execute
arbitrary Ex commands when completing a struct/union member
(cipher-creator)
Solution: Escape the type field before inserting it into the :vimgrep
pattern so it cannot close the pattern and start a new command
(Hirohito Higashi).
Github Security Advisory:
https://github.com/vim/vim/security/advisories/GHSA-mf92-v4xw-j45x6b611b0d15
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
(cherry picked from commit d844a276bb)
ArrayOf metadata existed before the LuaCATS type documentation refactor and is
useful to typed clients consuming api_info().
Keep Tuple metadata normalized to Array, since tuple element types can be mixed,
but preserve ArrayOf(...) for exported API metadata.
Fixes#38734
AI-assisted: Codex
(cherry picked from commit ea0af59854)
Problem: The table `history` in treesitter/_select.lua stores references
to previously selected TSNodes, but a TSNode needs to keep its
whole TSTree alive in memory, which may be kept alive even
after closing the buffer to which this history corresponds.
Solution: Store just the bits of information from the TSNode we need to
go back in selection history (the range and ID), without
referencing the TSNode itself.
(cherry picked from commit bcfc2037ef)
Problem: The function visual_select() in treesitter/_select.lua is
executing `:normal! v<Esc>` to ensure that `gv` later goes
back to character Visual mode, but doing so when mode() is
already `v` first switches back to the Normal mode, then
executes <Esc>, which causes a beep.
Solution: Check if the mode() is already `v` and avoid any switching in
that case.
(cherry picked from commit 9afa8477b3)
Some servers register `workspace/didChangeWatchedFiles` watchers for URI
schemes that cannot be watched locally. Skipping the unsupported glob
and keep the rest of the registration batch active.
(cherry picked from commit 4d9e5acfb5)
Problem: :syn sync without an argument also lists every defined cluster
Solution: Fix control flow in syn_cmd_list() so that only the syncing
items are printed when this function gets called by :syn sync.
(dmitmel)
closes: vim/vim#20614f2954c821e
(cherry picked from commit 764e257ae5)
Problem: LspNotify autocmds were not being triggered for didChange
requests when being used during undo/redo (and possibly other) actions.
autocmds are blocked when calling on_lines() callbacks while doing the
undo/redo action.
Solution: Defer firing the autocmd until after the action is complete.
This is closer to what existed before, but now there's a check in the
deferred function to only fire the autocmd if the client is still
active and the buffer is still attached, if applicable.
(cherry picked from commit 3c924d13fe)
Problem: LspNotify never passed a buffer when executing the autocmds, so
buffer-local LspNotify autocmd subscriptions didn't have the correct buf
in the event metadata. It was also wrapped in a schedule() so the actual
autocmd was delayed until after the event loop.
This could result in the wrong buffer receiving the notification if
multiple LspNotify autocmds with buffer filters were added. Only the
"latest" one would actually receive non-buffer-filtered autocmds, not
the matching one. It also caused listeners to receive the notification
"out of sync" with when the notification is actually sent. If a buffer
is being deleted (which fires a textDocument/didClose notification), the
notification is scheduled and fired after the buffer is already gone.
Solution: For LSP notifications that pertain to a particular buffer, set
it when executing the LspNotify autocmds so the callback functions that
are filtered on that buffer will get the correct notifications and the
metadata buf field will be correct. Additionally, there is no need to
wrap the LspNotify callback in vim.schedule when it can be called inline
when the notification to the rpc server is fired.
This is tested by removing now-unnecessary autocmds from semantic tokens
(InsertEnter and BufWinEnter should no longer be necessary now that
requests are fired by LspNotify). Without this fix, simply modifying a
buffer doesn't actually trigger LspNotify correctly, and the test for
that fails.
(cherry picked from commit 54188fa242)
Co-authored-by: jdrouhard <john@drouhard.dev>
Problem: When multiline semantic token support was introduced, the loop
that finds the end line for a particular token didn't sanitize the token
length sent back by the LSP server. If the server returned an overflowed
length (near uint32 max), neovim would burn cpu and loop for an
extremely long time while trying to find the "end line" represented by
the massively large token, causing neovim to seemingly hang.
Solution: Stop looping once the calculated end_line reaches the actual
last line of the buffer.
Fixes#36257
(cherry picked from commit 6bc6461eac)
Co-authored-by: jdrouhard <john@drouhard.dev>
This was initially added so that the __NVIM_DETACH environment variable
can be added to the jobs started in this test. That environment variable
is no longer needed, and there is also vim.tbl_extend() that can be used
to add an environment variable to a job anyway.
Also, make a shallow copy of opts.env in setup_child_nvim(), as mutating
the opts.env passed in may mask problems in other tests.
(cherry picked from commit f876fd906e)
Today there is a constraint that these arguments to the enable filter be
mutually exclusive, but I do not know why such a constraint exists (it
is perfectly reasonable to want to enable a capabilility for just one
buffer and just one client).
(cherry picked from commit ed267268b8)
Problem: A wrapped command line and screen width may be redrawn
repeatedly after calls to `redrawstatus` from lua.
Solution: redrawcmd() redraws the command line, but msg_clr_eos() may
invalidate cmdline_was_last_drawn during the redraw process.
Restore cmdline_was_last_drawn when redrawcmd() completes.
Co-authored-by: Sam Reynoso <sam@codeoutpost.com>
Co-authored-by: Luuk van Baal <luukvbaal@gmail.com>
(cherry picked from commit 6be9459d35)
Problem:
:Man does not syntax highlight codeblocks (injected language).
Analysis:
init_pager() swapped pcall(parse_ref, ref) return values order, so
vim.b.man_sect was set to the manpage name instead of the section
number, so C syntax highlighting did not load.
Solution:
Swap the calls.
(cherry picked from commit 67b3cceaa7)
Problem: No message kind and multiple events for :recover and
(non-prompt) swapfile attention messages.
Solution: Assign these the "list_cmd" and "wmsg" kind.
Problem: The "Scanning:" completion, bufwrite, and indent (there may be
more) messages which indicate progress can use the "progress" kind
for their msg_show event. Indent message does not have a kind.
Solution: Emit these messages with the "progress" kind. Set the message id
to the replaced kind so that a UI knows to replace it (and to provide
a migration path in case a UI was distinguishing these messages for
whatever reason).
Problem: The refactor to use Capability left around some cruft and
semi-broken configuration for debounce.
Solution: Clean up now-unnecessary helper methods and simplify
deprecated ones to pass through to the non-deprecated ones. `debounce`
now defaults to 200 for all buffers but is overridable via the
deprecated start() method, which continues to take the max value
specified for any client attached to the buffer.
If we wish to expose changing the debounce in a non-deprecated way, we
will need to consider a "configuration" function, or even a bespoke
method to set the debounce time on the main metaclass (or provide
options to override for a particular buffer). General configuration of
specific LSP features is an as-of-yet unsolved problem.
(cherry picked from commit 859790e244)
Problem:
A colored (guisp) underline showing through a 'winblend' float
lost its special color and followed the foreground instead.
Solution:
In the blend-through case, blend the underline's special color
only when the cell below sets sp explicitly; otherwise clear it.
(cherry picked from commit 823517ad1d)
Problem:
Terminfo sucks.
Solution:
Patch Ss/Se (set/reset cursor style) sequences when we know what they
should be.
close#38987
(cherry picked from commit ebc69b387c)
Problem:
All (tested by me) terminals (xterm, st, ghostty, vte, foot, wezterm, konsole) do support `\x1b[0 q` as "reset cursor to default", but at least konsole and wezterm only understands `\x1b[0 q` as "reset to default", but have different behaviour on `\x1b[ q` (konsole sets "steady block", and wezterm does nothing (do not change cursor shape).
Solution:
Use `\x1b[0 q` would be more widely compatible "reset" sequence than `\x1b[ q`
P.S. actually, `xterm`, `ghostty` and `st` (with default config.h) sets "steady block" for both sequence, but still here `[0` behaves the same as `[`
(cherry picked from commit 224ad8a538)
(AI-assisted)
Problem:
Zig build failing since 966e7a98f5:
FAILED ...r/work/neovim/neovim/test/functional/editor/xxd_spec.lua @ 22: xxd handles long lines in revert mode
Expected values to be equal.
Expected:
0
Actual:
134
stack traceback:
...r/work/neovim/neovim/test/functional/editor/xxd_spec.lua:26: in function <...r/work/neovim/neovim/test/functional/editor/xxd_spec.lua:22>
`huntype` parses the address column by repeatedly left-shifting
`want_off` (a signed `long`) by 4 bits per hex digit. After 16 hex
digits the value occupies all 64 bits; the next shift moves a non-zero
bit into the sign bit -- signed overflow, i.e. undefined behavior.
This happens on the Zig build because it enables UBSAN. The bug was
pre-existing, but 966e7a98f5 added a test that exercises it.
Solution
Shift through `unsigned long` and cast back to `long`, making the
overflow well-defined wrap-around.
(cherry picked from commit f350e39b77)
Problem:
Backport commits may have subjects like "backport: fix(ui): ...".
(e.g. ecda67662f). git-cliff treats them as OTHER.
Solution:
Preprocess the subject to strip a leading "backport:" or "backport ".
(cherry picked from commit 4c3b0ecb46)
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
feat(lsp): use LspNotify for semantic tokens
Problem: The semantic token module is using its own debounce timer for
the buffer on_lines event. If its internal debounce is shorter than the
changetracking module's debounce, it's possible for semantic token
requests to fire for changed buffers before the textDocument/didChange
notification is sent to the server.
Solution: Trigger semantic token requests from the LspNotify autocmd
when the method is the didChange or didOpen notifications, which
enforces a strict happens-before relationship for the sync change
notification followed by a semantic token request.
Note: There is still an internal debounce mechanism in the semantic
token module to handle other debouncing needs specific to its
functionality, such as debouncing server refresh notifications and
handling WinScrolled events when using range requests.
Co-authored-by: jdrouhard <john@drouhard.dev>
Problem:
A text edit positioned entirely past the last buffer line, with
newText ending in a newline, leaves a stray blank line: the
past-the-end path appends the trailing empty fragment produced by
vim.split() and does not set has_eol_text_edit, so the end-of-buffer
cleanup is skipped. Formatting servers emit such edits whenever
formatting moves text to the end of a document.
Regression from ec94014cd1 (#20137), which split the past-the-end
fast path off the clamp path that sets the flag.
Solution:
Set has_eol_text_edit in the past-the-end path, like the adjacent
path that clamps end_row.
(cherry picked from commit d42f7ee9dc)
Co-authored-by: Aaron Tinio <aptinio@gmail.com>
Problem:
When a server sends workspace/codeLens/refresh while an automatic codelens
request is already scheduled, Nvim ignores the server refresh. This can leave
rendered codelens text stale until another buffer edit triggers a new request.
Solution:
Cancel the pending automatic request and send the server-requested refresh
immediately. This preserves request coalescing while giving explicit server
refreshes priority.
Co-authored-by: Tristan Knight <admin@snappeh.com>
Problem:
Various out-of-bounds writes inherited from vim (examples assume MAXPATHL==4096):
- truncated item groups where minwid>maxwid:
nvim --clean +"set stl=%<%{%repeat('x',4096-11)%}%50.5(12🙂345%)"
leads to fillchars spilling over the end of the group/buffer while trying to
compensate for truncating at a multicell character because minwid<=maxwid is assumed
- left-aligned item groups with multi-byte fillchar:
nvim --clean +"set fillchars+=stl:∙ stl=%<%{%repeat('x',4096-3)%}%-2(X%)"
wrongly leads to padding at the end of the statusline and `out_p-out==4097`
because the bounds check assumes a 1-byte fillchar
- right-aligned item groups with 1-byte fillchar:
nvim --clean +"set stl=%<%{%repeat('x',4096-4)%}%4(XY%)"
leads to "YX" instead of "XY" at the end of the statusline
because `memmove` is done before adjusting the offset
- right-aligned item groups with multi-byte fillchar:
nvim --clean +"set fillchars+=stl:∙ stl=%5(X%)"
leads to "∙∙∙∙<e2>", i.e. the fillchar is being written over the group contents
and eventually being overwritten itself at the second byte with the final NUL,
because the padding counter assumes a 1-byte fillchar; to crash Neovim,
nvim --clean +"set fillchars+=stl:∙ stl=%<%{%repeat('x',4096-149)%}%50(X%)"
Solution:
Clearer variable names and no recycling of variables for different purposes.
(cherry picked from commit e36659c82f)
Problem:
Flickering may occur when paging up/down in big files, as ranges for semantic
tokens are requested. This happens with LSP servers like gopls which return
"/full" semantic tokens if the file is too big, where we fall back to
viewport-range token retrievals.
Solution:
Broaden the requested ranges to one viewport of "overscan" on each side plus
some padding if possible:
(viewport_topline - viewport_height)..(viewport_botline + viewport_height)
(cherry picked from commit 3ed78daf83)
Problem:
`foldcolumn` is empty for virtual lines above the start of a nested
fold.
Solution:
For virtual lines, compute the outer fold level and display it by
reusing the logic from `fill_foldcolumn`.
(cherry picked from commit fe154f4d45)
Problem:
`nvim -u NONE -d <(xxd one) <(xxd two)` has weird behavior.
Process substitution `<(...)` is a pipe and not a seekable file.
Test case:
cat /dev/random | head -c 10240 > one
cp one two
cat /dev/random | head -c 10240 >> two
nvim -u NONE -d <(xxd one) <(xxd two)
Solution:
Workaround the issue by skipping `nvim.difftool` if the 2 args are not
directories; fall-through to the builtin diff handling.
Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
(cherry picked from commit 2fd2361a9d)
Following is a list of commits (fixes/features only) in this release.
See `:help news` in Nvim for release notes.
BREAKING
--------------------------------------------------------------------------------
- f54f566bf8 diagnostic: deprecate `format` as a table
FEATURES
--------------------------------------------------------------------------------
- fd1b193d51 :restart: v:starttime, v:exitreason #39319
- c407e3e67b eval: treat Lua string as "blob" in writefile() #39098
- a0dcdcd8a0 treesitter: provide select()
- 49efe692f3 vim.pos: accept buf=0 for current buf #39414
- ad27075c8d vim.pos: pos:to_offset(), pos.offset() (#39639)
- b05675bccc `opts.scope` in `vim.ui.input` (#39906)
PERFORMANCE
--------------------------------------------------------------------------------
- 96d5dd4107 vim.pos: use numeric index internally #39447
FIXES
--------------------------------------------------------------------------------
- e230ff0439 vim._with may silence all cmdline-errors #34301
- 781c43ea05 api: adjust Visual position after nvim_buf_set_text #30690
- 5b8268356a api: don't update 'title' when renaming non-curbuf #39743
- 4df16ecdb9 api: `LuaRef` leak in `nvim_set_keymap` on LHS too long (>=66 bytes) (#39376)
- e5d6d2e769 api: leak `preview` callback `LuaRef` in `nvim_create_user_command` (#39377)
- f0baa18043 channel: stack-buffer-overflow with exit during connection (#39387)
- d9baaf7da1 ci: generate more data to stress output throttling test #39577
- f62ce1a42f difftool: handle filenames containing spaces #39740
- fb56d50032 eval: writestring() handling of null #39328
- 822778f7e5 excmd: use realtime for v:starttime, :uptime #39425
- 8fccb26cd3 fold: virtual lines duplicate foldopen (#39891)
- 10695f44af health: set 'tags' for help filetype #39742
- e069022215 help: fix CTRL character issue for :help {subject} #39537
- 445fe8a6b7 lsp: calc correct screen_width when opts.relative == 'editor' (#39977)
- 93dc301781 lsp: callHierarchy/outgoingCalls ranges are relative to caller, not callee #39336
- 5e6c8d4edf lsp: check window is still valid after async request #39396
- 8919b02eba lsp: dynamic registration for off-spec method #39544
- c4d3a3d363 lsp: filter code_action diagnostics to the cursor #38988
- 27d01f2dbb lsp: handle null id in JSON-RPC responses
- aedbae4ab6 lsp: handle self-mapped methods in supports_method #39383
- 0bd6e62509 lsp: malformed edit if apply_text_edits() is called twice (#39347)
- 378f5f49b3 lsp: show meaningful error on invalid completion response (#39476)
- c9ca59ad28 lsp: util.lua attempt to concatenate userdata #39510
- e67f9c5853 lua: avoid `__index` when deciding if a table is a list #39556
- 731f9743e2 lua: don't strip debuginfo in precompile module #39191
- b0bfce290f lua: fields of `nvim.spellfile.Opts` are optional #39902
- 34bf0472ab marks: don't use spell decorations from other lines (#39441)
- d1cf3ab4c3 marks: read from the correct variable in conceal_lines mark collection (#39991)
- 33b6b0bfe5 messages: avoid recursive rtp build due to msg_show #39888
- d725ead5ec messages: reset redirection message column after :echon #39472
- b490fba786 mouse: mouse=n should not adjust visual selection
- 17ddfde131 net: `:edit <uri>` should set buftype=nofile #39915
- dd95e434e3 pack: only use tags that strictly comply with semver spec #39342
- 585c93204f path: `nvim_get_runtime_file` fails on DOS 8.3 filename #40144
- 42f6c1c443 prompt: handle multi-element lists in prompt_appendbuf #39550
- 915880d252 shada: bdelete'd buffers not stored in oldfiles #39070
- e4a9bd55b2 shada: set correct buffer number for local marks on read #39712
- 2389cf2e39 shell: preserve CR when `:!` outputs to binary-mode buffer #39558
- 98098d8466 startup: emitting useless OptionSet
- ae9f7accdd statusline: no cmdline ruler for autocommand window
- 39e8c584d5 terminal: memory leak in pending TermRequest StringBuilder #39333
- fa69cac7e3 terminal: memory leak when pasting '=' register (#39738)
- 3a3405d964 test: only test for unibilium if a valid compilation string exists
- dcf9e8a98e treesitter: crash in ts_parser_delete after gc #39497
- 4f22640b86 treesitter: get_node_text() inconsistent trailing newline #39409
- 654c964d1a trust: hash unchanged empty buffers as empty files #39027
- 70f22713a1 ui2: entering the pager fails if `<ESC>` is remapped to `:fclose` (#39462)
- 13041a067e ui2: error E518 when typing "vim:" in cmdline #39599
- a0ee5811b1 unittest: preprocess failure when __typeof declarations present #40145
- b9d39f5bb2 vim.fs: fs.dir() may return nil "type" on some filesystems #39749
- be4e7cfd6a vim.hl: range(0,…) highlight not cleared after buffer-switch #40130
- 79fd0b6655 vim.range: empty ranges semantics vs regular ranges #39474
- 2ec758f403 vim.range: validate arguments on all cases #39415
- f83e0dcaf8 vim.secure: read() command injection vulnerability #39918
BUILD
--------------------------------------------------------------------------------
- a612ada984 version bump
- b1b489b316 docs: sort/lint class fields and keysets
- 4f6c711fc0 test: declaration specifier expected near '_Static_assert' #39788
VIM PATCHES
--------------------------------------------------------------------------------
- 964e797fdf 9.2.0395: tests: Test_backupskip() may read from $HOME (#39417)
- b013940391 9.2.0435: [security]: backticks in 'path' may cause shell execution on completion
- f9f2596288 9.2.0436: Buffer overflow when parsing overlong errorformat lines (#39578)
- 0aa77cb78c 9.2.0443: GUI: cancelling save dialog overwrites or discards unnamed buffer (#39617)
- 15a58bb02a 9.2.0444: Cannot set 'path' option via modeline
- 03af1ec931 9.2.0450: [security]: heap buffer overflow in spellfile.c read_compound() (#39660)
- 2902ec0541 9.2.0458: Crash with invalid shellredir/shellpipe value (#39691)
- 647b6be489 9.2.0461: Corrupted undofile causes use-after-free (#39707)
- c8e0af85e0 9.2.0500: filetype: some html files wrongly recognized as htmlangular (#39880)
- d9b8bac435 9.2.0508: completion: cannot complete user cmd :K with 'ignorecase' (#39944)
- 15a3318e13 9.2.0513: [security]: memory safety issues in spellfile.c (#39960)
- cc1982bd06 9.2.0517: quickfix: can set quickfixtextfunc in restricted/sandbox mode (#39970)
- dfd6cd477f bfebd12: runtime(javacc): Check for existence of javaFuncDef syn group before clearing it (#39731)
- a76bcbe3b8 partial:9.2.0315: missing bound-checks (#39334)
Problem:
stdpath() may return a DOS 8.3 "shortened" filename, because Windows
truncates some long usernames into `6ch~N` names. Then features such
as `nvim_get_runtime_file` fail to find the file.
Analysis:
When expanding an 8.3 filename path like `C:/Users/ADMINI~1/AppData/*`,
we treat `~` as a special character and first check whether a directory
named `ADMINI~1` exists under `Users`. Since no such directory actually
exists, the expansion fails.
Solution:
Treat `~` as a literal character in `do_path_expand`. Since the `~/`
case is already handled in `gen_expand_wildcards`, any remaining `~` is
just a literal character and will later be escaped to `\~` by
`file_pat_to_reg_pat` if needed.
(cherry picked from commit 7bf2ab4b87)