Problem:
Can't expand treesitter-incremental-selection to the next and previous
sibling nodes.
Solution:
Pressing `]N` in visual mode will expand the selection to the next
sibling node, and `[N` will do the same with the previous node.
Problem:
- The `ZR` feature makes it more obvious that we need some sort of flag so that
an `ExitPre` / `QuitPre` / `VimLeave` handler can handle restarts differently
than a normal exit. For example, it's common that users want `:mksession` on
restart, but perhaps not on a normal exit.
- Nvim has no way to report its "uptime".
Solution:
- Introduce `v:starttime`
- Introduce `v:exitreason`
benchmark: https://gist.github.com/ofseed/6224529d77c016c36f7ab2f977059848
local rounds = tonumber(arg[1]) or 1000
local count = tonumber(arg[2]) or 1000
-- Load the table.clear function.
local clear = require("table.clear")
local function fill(t, n)
for i = 1, n do
t[i] = i
end
end
local function bench_reassign(n_rounds, n_items)
local t = {}
local start = os.clock()
for _ = 1, n_rounds do
t = {}
collectgarbage("collect")
fill(t, n_items)
end
return os.clock() - start
end
local function bench_reassign_no_gc(n_rounds, n_items)
local t = {}
local start = os.clock()
for _ = 1, n_rounds do
t = {}
fill(t, n_items)
end
return os.clock() - start
end
local function bench_clear(n_rounds, n_items)
local t = {}
local start = os.clock()
for _ = 1, n_rounds do
clear(t)
fill(t, n_items)
end
return os.clock() - start
end
-- Warm up LuaJIT before the real benchmark.
do
local t = {}
for _ = 1, 2000 do
clear(t)
fill(t, count)
end
end
collectgarbage("collect")
local reassign_time = bench_reassign(rounds, count)
collectgarbage("collect")
local reassign_no_gc_time = bench_reassign_no_gc(rounds, count)
collectgarbage("collect")
local clear_time = bench_clear(rounds, count)
print(string.format("rounds=%d count=%d", rounds, count))
print(string.format("t = {} + GC : %.6f s", reassign_time))
print(string.format("t = {} : %.6f s", reassign_no_gc_time))
print(string.format("table.clear : %.6f s", clear_time))
print(string.format("vs + GC : %.2fx", reassign_time / clear_time))
print(string.format("vs no GC : %.2fx", reassign_no_gc_time / clear_time))
benchmark result:
rounds=1000 count=1000
t = {} + GC : 0.022469 s
t = {} : 0.002570 s
table.clear : 0.000387 s
vs + GC : 58.06x
vs no GC : 6.64x
`count` is how many items the table has, and `round` is how many rounds we fill
the table, clear, and then refill it. `table = {}` is clear the table by
resigning a new empty one, because this script does not run persistently like
nvim so GC is not triggered, so I added another extreme control group that
manually triggers GC.
Problem:
With GIT_DIR/GIT_WORK_TREE set, the LSP on the vim.pack.update()
confirmation buffer does not show the correct git log on hover.
Solution:
Temporarily remove the git vars from the environment.
Problem: Cannot apply 'scrolloff' context lines at end of file
Solution: Add the 'scrolloffpad' option to keep 'scrolloff' context even
when at the end of the file (McAuley Penney).
closes: vim/vim#19040a414630393
Co-authored-by: McAuley Penney <jacobmpenney@gmail.com>
Problem: :restart leads to ERR/WRN logging on Windows with --listen.
Solution: Add a log_level flag to vim._with() and use it to suppress
logging from serverstart()/serverstop() during restart.
Problem:
On Windows, :restart cannot immediately reuse the canonical --listen
address because named pipe release is asynchronous.
Solution:
Start the new Nvim server on a temporary address; in the new Nvim,
retry serverstart() with the original ("canonical") address until it
succeeds.
Problem: filetype: ghostty config files are not recognized
Solution: Detect ghostty configuration files as ghostty filetype,
include a simple ghostty filetype plugin (Bez Hermoso)
closes: vim/vim#20002b30803b231
Co-authored-by: Bez Hermoso <bezalelhermoso@gmail.com>
Co-authored-by: Christian Brabandt <cb@256bit.org>
Problem: Invalid check for non-typed key to dismiss expanded cmdline.
Unable to delay the timer that removes a message from the msg
window.
Solution: Check for empty string instead of nil to determine whether a
key is typed.
Restart the timer if it expires while the user is in the msg
window. Allow entering the msg window with a mouse click.
Problem: After closing a tabpage while the msg window is showing a
message, it is hidden while the msg window still contains a
message.
Solution: Unhide the msg window after entering a tabpage and it still
contains a message.
Co-authored-by: Linykq <yukunlin590@gmail.com>
Problem: fg_indexed/bg_indexed were dropped from nvim_get_hl output due
to a wrong short_keys guard. HL_FG_INDEXED also wasn't cleared in
hl_blend_attrs, and HLATTRS_DICT_SIZE was too small.
Solution: Remove the short_keys guard, clear HL_FG_INDEXED in
hl_blend_attrs, bump HLATTRS_DICT_SIZE to 24, and clarify docs that
these flags mean rgb is an approximation of the cterm palette index.
Problem:
- Unable to "pin" a window to prevent closing without specifically
being targeted.
- :fclose closes hidden windows (even before visible windows).
Solution:
- Add 'winpinned' window-local option. When set, window is skipped by
:fclose and :only. Pin the ui2 cmdline window (which should always be
visible), so that it is not closed by :only/fclose.
- Skip over hidden (and pinned) windows with :fclose.
Co-authored-by: glepnir <glephunter@gmail.com>
Problem:
Codelens virtual lines remain on stale rows after an external file
change and buffer reload.
Solution:
Clear codelens extmarks and cached row/version state in `on_reload`
before requesting fresh code lenses.
Problem: completionItem/resolve response's `detail` field is silently
dropped. Only `documentation` is shown in the popup.
Solution: Prepend `detail` as a fenced code block before `documentation`
in the info popup, skipping if documentation already contains it.
Problem:
After on_refresh() sends a textDocument/codeLens request, the buffer may
be deleted before the response arrives. The response callback then tries
to redraw that deleted buffer and raises Invalid buffer id error.
Solution:
Check buffer validity before redrawing.
AI-assisted: Codex
Co-authored-by: Yi Ming <ofseed@foxmail.com>
Problem:
No LuaLS types for event-data fields (ev.data). Types are only
documented ad hoc in scattered locations.
Solution:
Add runtime/lua/vim/_meta/events.lua defining vim.event.<name>.data
classes for events that provide ev.data. Reference the types from
each event's help in autocmd.txt, lsp.txt, and pack.txt.
Problem: Using `buf=0`/`win=0` context in `vim._with` should be
equivalent to using explicit buffer/window identifier respectively.
Solution: Explicitly adjust context in case of `buf=0` or `win=0`.
Problem:
Too much boilerplate needed to use Lua to impl an excmd or f_xx
function.
Solution:
- Add `nlua_call_vimfn` which takes the args typval, executes
Lua, and returns a typval.
- refactor(excmd): lua impl for :log, :lsp
Problem: Calling `vim.filetype.match({ filename = '...', buf = ... })`
during startup results in an error due to not yet defined
`g:ft_ignore_pat`.
Solution: Add a guard to check `g:ft_ignore_pat` related properties only
if the variable is defined. This also allows to simplify other tests
which did not depend on `g:ft_ignore_pat` but required it explicitly
set to work.
* fix(api): allow silencing "Too many highlight groups" error
Problem: Using Lua's `vim.api.nvim_set_hl(0, 'New', {...})` can fail if
there are too many existing highlight groups. However, this error can
not be silenced with `pcall`.
Solution: Make it possible to silence in `nvim_set_hl` and
`nvim_get_hl_id_by_name`.
* fix(lsp): limit number of groups created by `document_color()`
Problem: A file can contain many string colors that would be highlighted
by an LSP server. If this number crosses 19999 (maximum number of
allowed highlight groups), there are general issues with creating
other highlight groups, which can break functionality outside of
`vim.lsp.document_color`.
Solution: Limit number of highlight groups that are created by
`vim.lsp.document_color` to 10000 (half of allowed maximum).
This is not a 100% solution (since there can exist more than 10000
other highlight groups), but explicitly checking number of groups is
slow and 10000 should (hopefully) be enough for most use cases.
Problem:
- Builtin "Vimscript" functions (f_xx) are mostly implemented in C.
Partly that's because there is some boilerplate required to call out
to Lua.
- Calls to `vim.fn.foo()` always marshall over the Lua <=> Vimscript
("typval") bridge, even if `fn.foo()` is implemented entirely in Lua:
```
Lua => typval => Object => Lua => Object => typval => Lua.
```
Solution:
Functions declared in eval.lua with `func_lua` are implemented in
entirely in Lua (`_core/vimfn.lua`).
- `gen_eval.lua` wires `func_lua` entries to `lua_wrapper`, which handles
the typval conversion for Vimscript callers (slow path).
- `nlua_call()` detects `func_lua` functions and calls the Lua
implementation directly. This eliminates all conversion overhead for
Lua callers (fast path).
- Validate at build-time that `func`, `func_float`, and `func_lua` are
mutually exclusive.
- Migrate `hostname()` as a toy example, to show the idea.
Problem: Documentation based on patches is outdated.
Solution: Add changes to documentation in a patch.
853886722c
Trailing space was removed in later patches.
Also fix a few more misplaced error numbers from #8155.
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Problem: - Paging keys in the dialog window consume input when the user
may not expect it. The dismissable title hint intended to
mitigate that results in having to press Escape twice to
abandon the prompt.
- Mimicked "msgsep" float border is taking up unnecessary
space when window takes up the entire screen.
Solution: - Use (conventional, albeit less convenient) keys intended
for scrolling to page the dialog window:
<(Mousewheel/Page)Up/Down>, <Home/End>.
- Only set the float top border when separation is actually
necessary, i.e. window does not reach the first row.
Problem:
Difficult for us to provide default handlers for functions like
`vim.lsp.buf.definition`. When users wanted to fine-tune the default behavior,
they don't know how.
Solution:
- Document an example providing `on_list` boilerplate to make it easier for
users to modify and override.
- Also, considering that the parameters of the previous
`on_list`(`vim.lsp.ListOpts.OnList`) are compatible with the parameters of
`setqflist`, remove that custom type in favor of passing
`vim.fn.setqflist.what`.
Problem:
`TSNode:id()` returns the underlying c pointer as a string, which may include
NUL bytes. In PUC Lua, `('%s'):format('\0a\0')` returns `''` and not `'\0a\0'`
(i.e. treats the string as a c-string (which terminates at the NUL byte)).
This resulted in two different nodes being able to have the same id.
Solution:
Use concatenation `..` instead of `string.format()`.
Problem: Sometimes automatic lockfile synchronization after `:restart`
might fail, like due to bad/absent Internet connection. This would
remove failed to install entries from the lockfile (since they are not
on disk and lockfile is meant to lock the latest plugin version on
disk).
Solution: Document that this should be treated as an unwanted update and
use steps similar to "Revert plugin after an update" use case.
Problem:
Naming conventions are not automatically checked.
Solution:
Add a check to the doc generator. Eventually we should extract this
somehow, but that will require refactoring the doc generator...
Note: this also checks non-public functions, basically anything that
passes through `gen_eval_files.lua` and `gen_vimdoc.lua`. And that's
a good thing.
Problem
Some variables use the wrong type (ClientToServer instead of ServerToClient)
and some use vaguer types that could be more strict.
Solution
Use the correct types.
Problem: filetype: not all Bitbake include files are recognized
Solution: Enhance the file detection logic and consider varflags
(Martin Schwan)
closes: vim/vim#199830e02be1919
Co-authored-by: Martin Schwan <m.schwan@phytec.de>
Problem:
The window opened by `vim.lsp.util.open_floating_preview()`
allows its buffer to be switched. Presumably that only happens
by accident and is disorienting.
Solution:
Set 'winfixbuf' in the open_floating_preview() window.
continues d0af4cd909.
This commit renames positional parameters. This is only "cosmetic", but
is intended to make it extra clear which name is preferred, since people
often copy existing code despite the guidelines in `:help dev-naming`.
Problem:
To support `collapsedText`, which allows the LSP server to determine the
content of the foldtext, we provided `vim.lsp.foldtext()`. However, such
content does not have highlighting.
Solution
Treat the filetype of `collapsedText` as the filetype of the corresponding
buffer and use tree-sitter to highlight it.
In 3a4a66017b, 4d3a67cd62, df8d98173c we renamed "buffer" to "buf"
in dict parameters and return-values.
This commit renames positional parameters. This is only "cosmetic", but
is intended to make it extra clear which name is preferred, since people
often copy existing code despite the guidelines in `:help dev-naming`.
Extract the diagnostic implementation from
runtime/lua/vim/diagnostic.lua into focused internal modules covering
config, display, float rendering, jump/list helpers, namespace and
storage management, severity/shared utilities, and statusline support.
Move the builtin handlers into runtime/lua/vim/diagnostic/handlers/ and
keep runtime/lua/vim/diagnostic.lua as the public facade that lazily
dispatches to the split modules. This preserves the external
vim.diagnostic API while making the implementation easier to navigate
and reason about.
AI-assisted: Codex