"vim.pot" file and tasks are N/A.
"clean" task is N/A after migrating to CMake.
N/A patches:
- 59bd74ed4c9ab366182c93bdc430b186729abbad
- 5d552d652b0197063565ab937d30f92a9ed28545
- 3c8d32e4fc17b4b38b17d7c039ee6203d1b01078
Problem:
The eol_offset used to decode multiline semantic tokens is computed as
vim.bo.fileformat[bufnr] == 'dos' and 2 or 1
which indexes the option value rather than the buffer, so it is never
"dos" and the offset is always 1. A token that crosses a line boundary
in a 'fileformat' of "dos" is then decoded one code unit short per line
ending, and the highlight extends past the end of the token.
Solution:
Read the option with the buffer-scoped form, vim.bo[bufnr].fileformat.
The existing multiline test covers both formats now. Its token length of
82 counts the line endings it spans, so the same token reaches four
characters less far once the buffer is "dos".
AI-assisted
Problem:
vim.lsp.util.show_document() can fail to load the target buffer, most
visibly with E325 when another process owns the file's swapfile and the
user declines to open it. The Vim error escapes show_document() and
surfaces inside whichever LSP handler called it, instead of being
reported as a failure to show the document.
Solution:
Load the buffer up front with vim.fn.bufload(), before any of that
state is touched, and report the error instead of raising.
AI-assisted
Problem: LuaLS struggles with the generics used in Nvim's runtime,
requiring broad diagnostic suppressions. Indexing is also slow.
Solution: Use EmmyLua for type checks in the build and CI. It offers
more sophisticated type checking, substantially better support for
generics, and much better flow analysis.
Correct the affected annotations. Use `@internal`, supported directly by
EmmyLua, instead of `@nodoc` for shared internal declarations, and
support it in the help parser.
AI-assisted
Problem: K on generic and nullable type annotations can jump to the
wrong help tag. Generated See references repeat the type names.
Solution: Strip generic arguments and nullable suffixes when resolving
help tags. Remove the redundant generated See references.
AI-assisted
Problem:
dynamicRegistration is declared false, and completionProvider is read
from server_capabilities only.
Solution:
Declare it, and prefer registerOptions per field.
Problem:
The LSP client excludes paths such as Git objects and installed
dependencies from file watching. However, watchdirs() still traverses
these subtrees before filtering which directories receive watchers,
paying the filesystem and Lua traversal cost for excluded content.
Solution:
Prune excluded subdirectories during the initial walk, and document
that excluding a directory also excludes its descendants.
Using the LSP client's existing **/node_modules/*/** exclusion on a
synthetic macOS tree with 100 installed packages and 4,000 files:
Before After
Directory scans 503 103
Entries inspected 4502 202
Directory watchers 103 103
The measurements use real filesystem calls and watcher handles, with
identical watcher paths for this exclusion.
Ref: #23291
AI-assisted
Problem:
msgpack#strptime() finds a timestamp by bisecting strftime() output, and
brackets the search with the extreme UTC offsets. The lower bound
subtracts 12 hours, but -12:00 is the westernmost offset, which produces
the *largest* timestamp for a given local time. The easternmost offset
is +14:00, so in any zone east of UTC+12 the search can start above the
target and the function throws:
internal-start-string:Internal error: start > string
With TZ=GMT-14, four of the five timestamps in msgpack_spec.lua fail,
as do three tests in shada_spec.lua, which reaches the same function
through shada#strings_to_sd().
Solution:
Subtract 14 hours instead. The upper bound is already generous enough at
+14, and widening a bisection bracket downwards cannot change the result
in zones that worked before.
The test disables the python3 provider, because msgpack#strptime() only
uses the Vimscript implementation changed here when no provider answers,
and otherwise hands the work to datetime.strptime().
AI-assisted
Problem: vim.pack uses a private async implementation even though
vim.async is now available.
Solution: Remove the private implementation and run plugin operations in
structured task scopes. Bound parallel work with semaphores and use
protected awaits so cancellation still propagates.
AI-assisted
Problem: Spup syntax fails for an out-of-range comment mode.
Solution: Add the missing let to the fallback assignment (Qiming zhao).
Setting oneline_comments above 3 raises E492 while loading the syntax
script. Use a valid legacy Vim script assignment to restore the default
value of 2.
Validated with oneline_comments set to 1, 2, 3, 4 and 99, and with the
variable unset. The original script fails with E492 for a value of 4.
The corrected script loads and applies the expected comment mode.
closes: vim/vim#21227
Supported by AI.
22b72dca7e
Co-authored-by: Qiming zhao <chemzqm@gmail.com>
Problem:
A Visual-mode mapping that leaves Visual mode ("xmap I Q0i") does not
replay its motions/edits at the extra cursors, though an insert session
it starts does.
atom_map_start() skips while Visual is active, so the mapping has no
`composite`, and atom_capturable() then rejects its commands.
Solution:
Open the `composite` for Visual-mode mappings too.
Bonus: the mapping atom is now reported as:
before: type=visual, keys="viwcFOO<Esc>"
after: type=mapping, keys="viwc<Esc>iFOO<Esc>", lhs=",c"
Problem:
TSHighlighter._on_conceal_line() parses with the range { row, row }. A
Range2 has an exclusive end, so that is the empty range, and no injected
region ever intercepts it.
The root tree is parsed regardless, because its region is empty, so only
injections are affected: conceal_lines metadata coming from an injected
language's highlights query is dropped. on_range_impl() then records the
row in _conceal_checked, so the miss persists until the buffer changes.
For a markdown code block nested in a markdown code block, the inner
fence delimiters stay visible and nvim_win_text_height() reports 5 rows
where 3 are displayed.
Solution:
Pass the one-row range, as the on_range_impl() call below already does.
AI-assisted
Problem:
A Visual selection opened programmatically (`:normal! viw`) is not
previewed at the other cursors, and a user-typed operator completing it
does not cascade.
":normal" keys run as child frames, which are never user input, so the
session they build was classified "fed" once and never revisited.
Solution:
Recalculate the session kind (`vatom.state`) on every frame. Record
`vatom.frame` (the last frame to add to the session) so an enclosing
frame does not reset or recapture it.
Problem:
cmd_on_key() tests the key it was handed against the literal string
'<MouseMove>', but at that point "typed" still holds raw key bytes. Thus
the comparison never holds and the branch its own comment describes
is dead. Moving the mouse over an expanded cmdline collapses it.
Solution:
Translate the key once, up front, so every comparison in the function
sees the same form.
AI-assisted
Problem:
The #has-parent? predicate indexes the result of node:parent() without
checking it, so a capture that matches a tree's root node raises
query.lua:600: attempt to index a nil value
instead of simply not matching. In a highlights query that breaks
highlighting for the whole buffer. The sibling #has-ancestor? predicate
handles the same situation.
Solution:
Treat a missing parent as "does not match".
AI-assisted
Problem:
`getdigits_int(pp, strict, def)` returns `def` only when the number
fails to parse or overflows, never when the text parses to a literal
`0`, so `%.0` leaves `maxwid` at 0. Both render paths then break down:
`l > maxwid` is always true and `while (l >= maxwid)` consumes the whole
string, so `%.0f` comes out as `<` and `%.0l` as `0>3`.
Vim guards for this right after the same call. Nvim had the guard too
until 3344cffe7b ("getdigits: introduce `strict`, `def` parameters"),
which folded it into the new `def` argument and so changed what a
literal zero means. The neighbouring `minwid` call was translated
correctly.
Solution:
Fall back to 50 when the parsed width is not positive, as Vim does.
AI-assisted
Problem:
Cursors placed same-line before the primary, or producing multiline
edits on lines above the primary, shift the text in a way that breaks
the insert-mode live-mirroring.
Solution:
Skip live-mirroring under those conditions.
TODO (future): we could support live-mirroring if ins-completion's
internal bookkeeping tracked its regions more precisely.
vim-patch:9.0.1557: test failures for unreachable code
vim-patch:9.0.1994: inconsistent feature description
vim-patch:2ca7d5f48 translation(ru): Add translation for README.txt and uganda.txt (#14312)
vim-patch:5400a5d42 runtime(comment): include a simple comment toggling plugin
vim-patch:9.1.0578: no tests for :Tohtml
vim-patch:85c724ea0 translation(ru): Updated uganda.rux
vim-patch:b256221e8 runtime(2html): Make links use color scheme colors in TOhtml
vim-patch:9.1.0834: tests: 2html test fails
vim-patch:9.1.0859: several problems with the GLVS plugin
vim-patch:9.1.1029: the installer can be improved
vim-patch:9.1.1227: no tests for the comment package
vim-patch:9.1.1533: helptoc: does not handle code sections in markdown well
vim-patch:9.2.0300: The vimball plugin needs some love
vim-patch:9.2.1027: runtime(helptoc): FuzzySearch() highlights matched characters at the wrong column
vim-patch:d33afe12c6639d70fca82230df6b9fdee7365423
vim-patch:9.1.0681: tests: Analyzing failed screendumps is hard
vim-patch:9.1.0736: Unicode tables are outdated
vim-patch:9.1.0750: there are some Win9x legacy references
vim-patch:9.1.1372: style: braces issues in various files
Problem:
`get_scrolloffpad_value()` takes a window, but its else branch reads
`curwin->w_p_sop` instead of `wp->w_p_sop`.
Reachable from Vimscript, since `line('w0', winid)` runs
`update_topline()` on another window without making it current.
Solution:
Read the option from the window that was passed in.
AI-assisted
Problem:
Freeing an unrelated buffer deletes the cursor under the primary.
Scratch-buffer cleanup triggers this unexpectedly.
Solution:
Separate dead-cursor cleanup from dedupe/merge. Merge overlapping
cursors only at cascade boundaries, not during buffer/namespace cleanup
or cursor removal.
Problem:
Input (`getchar()`, `input()`, …) consumed by an expr mapping EVALUATION
can leak into `CmdAtom.keys`, depending on count placement ("2dse" vs
"d2se").
Solution:
Skip payload capture while `expr_map_lock` is active.
- Input read during expr EVALUATION is recorded in `CmdAtom.lhs`.
- Only input read by mapping EXECUTION is appended to `CmdAtom.keys`.
Problem:
Pending mapping atoms prevent live insert-cascading (`nnoremap i ^i`).
Flushing them at insert-session start (3a02a39957) adds a separate
cascade boundary, which muddles the architecture.
Solution:
Let the first insert-span cascade pending mapping atoms on insert-entry.
This is an alternative fix for #41692.
Composite children (`.atoms`) BEFORE:
{ { 'motion', '^' }, { 'insert', '1iX<Esc>' } }
Composite children (`.atoms`) AFTER:
{ { 'motion', '^' }, { 'insert', '1i<Esc>' }, { 'insert', 'iX<Esc>' } }
Problem:
Both handle lookups write into the same `Error` before either one is
checked, and `api_set_error()` unconditionally `xmalloc`s `err->msg`
without freeing what is already there. When both handles are invalid,
the message allocated for the window is silently overwritten by the one
for the buffer and leaked.
Solution:
Check the window before looking up the buffer. As a side effect the
reported error no longer names the buffer when the window was wrong too.
AI-assisted
Problem:
A Normal-mode mapping that moves before entering Insert, does not
live-mirror. Its pending motion defers insert-cascade until Insert ends.
Solution:
Cascade pending atoms before the Insert entry replay, then start the
live insert span.
Problem:
The "spill" indicator that ui2 appends when messages overflow the
available height is drawn with whatever highlight the message tail
happens to have, so it is indistinguishable from the message text.
Solution:
Give the [+x] chunks an explicit `MoreMsg` highlight, and only fall back
to the message tail highlight for chunks that don't carry one of their
own.
AI-assisted
Problem:
Changing from an empty-line cursor after a multicursor jump can crash
while flushing a deferred clipboard update. Exact context restore can
leave an omitted register with a null array and stale non-zero size.
Solution:
Make free_register() fully reset the register after freeing its contents,
so it always leaves a valid empty register. Add a regression test.
Signed-off-by: sami <samiulsami7786@gmail.com>
Problem:
`unpack_string()` validates the declared length against `*size`, the
size *before* `mpack_rtoken()` consumed the token header, rather than
`size2`, the remainder after it. The header is one to five bytes, so any
declared length in the window `(size2, *size]` slips through. The
returned `String` then covers up to five bytes past the end of the
buffer, and `size2 - tok.length` underflows, leaving `*size` near
`SIZE_MAX` so every later unpack call on that entry believes it has an
unbounded buffer.
Reachable from ShaDa, where a history entry ending in a five-byte string
header followed by four bytes is enough, so a corrupted or hostile
`main.shada` triggers it at startup.
Solution:
Check the remainder left after the header.
AI-assisted
Problem:
The early return for an invalid window handle bypasses the
`set_destroy()` at the end of the block, so the set's backing allocation
leaks whenever an earlier iteration already called `set_put()`.
Triggered by `{ wins = { valid_win, 9999 } }`.
Solution:
Destroy the set before returning.
The new test passes either way, since the leak is only visible to a
sanitizer; it is there so the ASAN job covers the path.
AI-assisted
Problem:
`find_window_by_handle()` returns NULL only after `VALIDATE_INT` has
already set `err`, so the `api_set_error()` that followed allocated a
second message over the first pointer and leaked it.
Solution:
Drop the redundant call and keep the helper's message, which is already
set and better worded.
AI-assisted
Problem:
The ui2 dialog implements paging for the arrow keys, Home/End and the
page keys, but not for the mouse wheel. When `mouse` contains `"c"`,
turning the wheel does nothing at all.
Solution:
Handle <ScrollWheelUp>/<ScrollWheelDown>, scrolling by the `mousescroll`
`"ver"` amount.
AI-assisted
Problem:
`menu_mode_chars` includes the two-character `"tl"` value. The hardcoded
`1` is the `key_len` argument of `tv_dict_add_dict()`, which truncated
it to `"t"`, the designator for a tooltip. Scripts keying on the
documented mode designators therefore miss terminal mode entries and
misread them as tooltips.
Solution:
Pass the real length of the designator.
AI-assisted
Problem:
`REMAP_NONE` is -1 and `REMAP_SCRIPT` is -2. These are enumerated
values, not bit flags, so `&` is the wrong operator: `x & -1` is `x`,
and `-1 & -2` is -2, which is truthy. Both kinds of non-remapping menu
therefore reported `noremap` and `sid` as 1 and became
indistinguishable.
The sibling `menu_get_info()` already compares with `==`.
Solution:
Compare rather than mask.
The expectations in menu_spec.lua had the
conflated values baked in, so 22 entries from plain `*noremenu` commands
now report `sid = 0`, and the two from `nnoremenu <script> Export.Script`
now report `noremap = 0`.
AI-assisted
Problem:
The loop frees `fuzmatch[count].str` on every iteration instead of
`fuzmatch[i].str`.
The function has no callers in Nvim, so there is no impact today. The
indexing is a slip from the port; Vim's implementation is correct.
Solution:
Index with the loop variable, as Vim does.
AI-assisted