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: 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: 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: 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>
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:
: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: 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)
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:
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:
When `vim.hl.range(0, …, { timeout = N })` is called, the deferred
`range_hl_clear` captures `buf=0`, which resolves to an arbitrary
"current buffer" at timeout. This may cause a stale highlight that never
gets cleared.
Solution:
Resolve `buf=0` explicitly, before `range_hl_clear` captures it.
(cherry picked from commit ec7dab077b)
Problem:
Currently, only some filesystems (Btrfs, ext2, ext3, ext4) have full
support of accessing the `dirent` entry-type. On other filesystems,
`uv.fs_scandir_next` may return `nil` for an existing but unsupported
entry-type.
This means consumers (such as `fs.dir()`), cannot know if `nil` means
"non-existent" or "unsupported".
Solution:
Fall back to `uv.fs_lstat` when `etype` is `nil`; return "unknown" if it
fails.
(cherry picked from commit 4b5f026ac9)
feat(ui): vim.ui.input(opts.scope) #39570
Problem: There is no way for a `vim.ui.input` caller to indicate for
which scope the input is. As in "This input is for something at cursor
scope". This information can be useful for `vim.ui.input`
implementation to tweak its behavior and presentation:
- Show different floating window depending on the scope. For example:
- Near cursor for "cursor" scope.
- At line start for "line" scope.
- In window corner for "buffer" and "window" scopes.
- In whole editor corner for "tabpage", "editor", "project" scopes.
- Navigate through history only for inputs with the same scope.
Solution: Document new `opts.scope` for `vim.ui.input`. Use it in the
codebase.
Problem: filetype: some html files are wrongly recognized as htmlangular
Solution: Use the \< atom to anchor ng-template and ng-content to start
of word (truffle)
Prevent false-positive htmlangular detection on words containing
'ng-template' or 'ng-content' as a substring (e.g. 'song-template',
'sing-content'). Anchor both branches with \< to require a word start,
matching the \<DTD\s\+XHTML\s idiom used five lines below.
related: neovim/neovim#39778.
closes: vim/vim#20246354ab1a69e
Co-authored-by: truffle <truffleagent@gmail.com>
(cherry picked from commit f3bb21e71d)
Problem:
During startup, we manually trigger a useless and misleading `OptionSet`
event, which doesn't set `v:option_*` values (this is a limitation of
`nvim_exec_autocmds`).
ad4bc2d90c/runtime/lua/vim/_core/defaults.lua (L939).
Solution:
The `nvim_exec_autocmds('OptionSet',…)` call does not serve any purpose
since 5cbb9d613b, so just drop it.
Problem: Crash with invalid shellredir/shellpipe value
(bfredl)
Solution: Validate the option and allow only a single "%s".
fixes: vim/vim#20157closes: vim/vim#2015984ae09dd79
Co-authored-by: Christian Brabandt <cb@256bit.org>
(cherry picked from commit ffe87d91f7)
Problem:
- Empty ranges have different `<`, `<=`, `has` and `intersect` semantics compared to regular ranges.
- `to_inclusive_pos` assumes that the end position of a range is exclusive, which is not true for empty ranges
Solution:
Special case empty ranges in these operations.
(cherry picked from commit 416f3482e7)
feat(tui): restore 'ttyfast' to control tty requests
Problem:
When running nvim on a remote machine over SSH, if there is high ping,
then bg detection may not complete in time. This results in a warning
every time nvim is started. #38648
Solution:
Restore 'ttyfast' option and allow it to control whether or not bg
detection is performed. Because this is during startup and before any
user config or commands, we use the environment variable
`NVIM_NOTTYFAST` to allow disabling `ttyfast` during initialization.
Co-authored-by: Kyle <50718101+kylesower@users.noreply.github.com>
Problem:
`builtin_types.lua` seems to be about vimfn (aka "eval", aka
"vimscript", …) specifically, whereas `builtin.lua` is about the Lua
stdlib.
Solution:
Rename it to `vimfn_types.lua`, to align with `vimfn.gen.lua`.
(cherry picked from commit aea9aeee78)
Problem:
Linter missed backtick and double-quote keynames in the quasi-keyset of
the `nvim_create_user_command` docstring.
Solution:
Update the linter to check backtick-surrounded and quote-surrounded key
names.
Problem:
For a given position, it is not easy to compare which of several other positions is closest to it.
Solution:
Add support for converting `vim.Pos` to a buffer byte offset.
This allows for sorting, e.g:
```lua
table.sort(positions, function(pos1, pos2)
return pos1:to_offset() < pos2:to_offset()
end
```
Or a binary search, e.g:
```lua
vim.list.bisect(positions, pos, { key = function(pos) return pos:to_offset() end })
```
Co-authored-by: Yi Ming <ofseed@foxmail.com>
Problem:
`diagnostic.status` only follows the `config.status.format` setting to determine how to display diagnostic signs. However, `signs` can actually also be configured via `config.signs.text`.
Solution:
If the user has set symbols via `config.status.format`, let that determine the content of `signs`; otherwise, use `config.signs.text` for display.
TODO: drop support `type(config.status.format) == 'table'`; users should just configure `config.signs.text` directly.
Co-authored-by: Yi Ming <ofseed@foxmail.com>
Problem: Entering the pager fails if <ESC> is remapped to :fclose by user.
Solution: Avoid executing mappings with nvim_feedkeys() that closes expanded cmdline.
(cherry picked from commit 2b7a00746d)
Problem: `vim:`, etc. in cmdline are interpreted as modeline, causing error E518.
Solution: Set 'nomodeline' when creating the buffers.
(cherry picked from commit 0ea720f281)
Problem:
`get_node_text()` returned inconsistent results between buffer and
string sources when a node's range ends at `end_col == 0` (i.e. the node
ends with a newline). The buffer path dropped the trailing newline; the
string path included it correctly.
Solution:
Append `'\n'` in `buf_range_get_text()` when `end_col == 0` and
`start_row ~= end_row`. The `start_row ~= end_row` guard excludes
zero-width nodes at column 0, which should return `""`.
Remove the workaround in the `#trim!` directive that manually
compensated for the missing newline.
Strip whitespace in `resolve_lang()` so injection language nodes ending
at `end_col == 0` (e.g. `">lua\n"`) still resolve correctly.
(cherry picked from commit 7ed5609439)
Problem:
LSP clients previously did not handle dynamic registration for off-spec methods
Solution:
Update the client logic to assume support for dynamic registration when
the method is unknown. Adjust the registration provider fallback and
enhance tests to verify correct behaviour for unknown methods and their
registration options. This improves compatibility with servers using
custom dynamic registrations.
AI-assisted: OpenCode
(cherry picked from commit 344d984ed2)
Problem:
The argument to `:help` is normalized to fit the general tag format.
I.e. i^U-default, iCTRL-U-default and i_CTRL_U-default should all point
to the i_CTRL_U-default tag. Our normalization adds an underscore around
the CTRL keycode, e.g. iCTRL-GCTRL-J becomes i_CTRL-G_CTRL-J. That's not
necessary if the following part starts with a dash, like the case of
iCTRL-U-default.
Solution:
Do not insert an underscore if the following character is a dash/minus
(-).
(cherry picked from commit 84ae70c172)
docs: update instructions for debugging LSP
Previously, it was suggested to set:
vim.lsp.log.set_format_func(vim.inspect)
This made sense before f72c13341a, when
`format_func` was called once per argument being logged, but since that
commit it's called with the log level followed by the other args, so the
suggested setting would call `vim.inspect(log_level, ....)` which would
just print the human readable name of the current log level and no other
details, for example with this set I saw in my logs:
"DEBUG""DEBUG""DEBUG""DEBUG"
Instead just rely on the default formatter, which will:
> ... log the level, date, source and line number of the
caller, followed by the arguments.
(cherry picked from commit 578727c25e)
fix(lsp): send didClose, didOpen when languageId changes
Problem:
If a buffer's filetype changes after the LSP client has already
attached (e.g. from json to jsonc via a modeline), but the client
supports both filetypes, it stays attached. It does not notify the
server of the new languageId, causing the server to incorrectly process
the file using the old languageId.
Solution:
Save the languageId used during textDocument/didOpen, and send
textDocument/didClose + textDocument/didOpen when buffer's languageId
changed.
Lsp spec:
0003fb53f1/_specifications/lsp/3.18/textDocument/didOpen.md (L5)
> If the language id of a document changes, the client
> needs to send a textDocument/didClose to the server followed by a
> textDocument/didOpen with the new language id if the server handles
> the new language id as well.
AI-assisted: Gemini 3.1 Pro
Co-authored-by: phanium <91544758+phanen@users.noreply.github.com>