Commit Graph

37999 Commits

Author SHA1 Message Date
Volodymyr Chernetskyi
050fa30632 fix(options): 'scrolloffpad' reads the wrong window #41684
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
2026-09-05 13:36:14 -04:00
Justin M. Keyes
455b6a810c fix(multicursor): cursors may be "deduped" incorrectly #41721
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.
2026-09-05 13:18:22 -04:00
Justin M. Keyes
c543e9e1de fix(cmdatom): exclude <expr> EVALUATION input from CmdAtom.keys #41718
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`.
2026-09-05 11:52:25 -04:00
Justin M. Keyes
0c642196b9 fix(multicursor): cascade mapping atoms with insert entry #41714
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>' } }
2026-09-05 09:53:41 -04:00
li
739a44753d fix(cwd): :bcd completion shows non-directories #41661
Problem:
Completion for `:bcd` shows files, not just directories.

Solution:
Set the ctx properly.
2026-09-05 07:56:27 -04:00
Volodymyr Chernetskyi
48864161cd fix(api): leaked error message in nvim_win_set_buf() #41688
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
2026-09-04 20:57:55 -04:00
Justin M. Keyes
3a02a39957 fix(multicursor): live-mirror mapped Insert entry #41692
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.
2026-09-04 20:03:19 -04:00
Volodymyr Chernetskyi
06bff27929 feat(ui2): highlight the [+x] spill indicator with MoreMsg #41679
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
2026-09-04 14:28:22 -04:00
Samiul Islam
b7a0c71a54 fix(multicursor): prevent clipboard crash after cursor jump #41698
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>
2026-09-04 13:06:50 -04:00
Lewis Russell
630e0592b7 test(lua): avoid async task completion flake #41702
Allow enough time for the timer and scheduled continuation to run on
Windows.

fixes #41699

AI-assisted
2026-09-04 12:51:23 -04:00
Volodymyr Chernetskyi
f1833490a0 fix(msgpack): out-of-bounds read on a truncated string #41683
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
2026-09-04 12:48:55 -04:00
Justin M. Keyes
0a173b09f4 Merge #41565 from janlazo/na-patch-v900
build(vim-patch): n/a patches for docs, test_override()
2026-09-04 12:40:21 -04:00
Volodymyr Chernetskyi
ba11f36695 fix(api): leaked window set in nvim__ns_set() #41689
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
2026-09-04 12:39:08 -04:00
Volodymyr Chernetskyi
6386e29636 fix(api): leaked error message in nvim_eval_statusline() #41690
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
2026-09-04 12:37:25 -04:00
Volodymyr Chernetskyi
b21f2094ba feat(ui2): scroll the dialog window with the mouse wheel #41682
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
2026-09-04 11:33:53 -04:00
Volodymyr Chernetskyi
cbba00c15a fix(menu): menu_get() files terminal mode menus under the tooltip key #41687
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
2026-09-04 11:32:34 -04:00
Volodymyr Chernetskyi
f22b017759 fix(menu): menu_get() cannot tell :noremenu from :menu <script> #41686
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
2026-09-04 11:18:22 -04:00
Volodymyr Chernetskyi
6112d4a674 fix(fuzzy): fuzmatch_str_free() frees the wrong element #41691
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
2026-09-04 09:42:09 -04:00
Christian Clason
efd1b66401 ci(release): bump deprecated runner image to macos-15
Problem: The `macos-14` image is deprecated and will be removed in
November 2026 (and have scheduled brownouts during October 2026).

Solution: Bump the image to `macos-15`, which is the oldest supported
version on GHA.
2026-09-04 14:32:01 +02:00
Christian Clason
e6292b2ee0 ci(macos): untap untrusted aws/tap on macOS
Problem: The 3rd-party default homebrew tap `aws/tap` is untrusted,
which now triggers a warning in our macOS workflows.

Solution: "Untap" (disable) the tap (which we don't use).
2026-09-04 14:32:01 +02:00
Christian Clason
1ce0ea50a2 ci(macos): skip brew upgrade
Problem: Support for Intel macOS is increasingly being dropped since
Apple itself retired the architecture (with macOS 27 already being
ARM-only). In particular, homebrew is already dropping support, with
some 3rd-party taps like `hashicorp/tap/vagrant` (that are enabled on GH
runners by default) no longer being available. This makes `brew upgrade`
fail on Intel.

Solution: Skip `brew upgrade` in `install_deps.sh`, as we don't rely on
the bleeding edge version of the installed dependencies. This skips
checking the tap (which we don't use) and hence lets the workflows pass.
(It also shaves of some seconds from the CI time.)

Note: This is strictly speaking a GHA issue and should be handled by
adapting the runner images; but since GHA has already announced that
they will drop all Intel macOS images in 2027, this is unlikely to
happen.

It also means that this is a stopgap solution to allow 0.13 to keep Tier
1 support for Intel macOS, but next year we'll have to drop support as
well.
2026-09-04 14:32:01 +02:00
Justin M. Keyes
2124f968a6 feat(multicursor): "]C"/"[C" leave a cursor at old position #41681
Problem:
`]C` jumps the primary onto another cursor, which dedupes at the next
edit. Every `]C` consumes a cursor.

Solution:
`]C` adds a cursor at the current position before jumping. This
effectively "rotates" the primary cursor.
2026-09-04 06:28:42 -04:00
Christian Clason
8c77b5be94 build(deps): bump luajit to 24c20c94e 2026-09-04 10:07:51 +02:00
Justin M. Keyes
18f5d47543 fix(multicursor): follow cursor-move by API #41675
Problem:
A non-edit mapping that moves the cursor by API (Lua,
`:call nvim_win_set_cursor()`, …) is not cascaded.

Solution:
Fallback to LHS-replay if the cursor moved and follow-mode is enabled.
2026-09-04 07:37:48 +00:00
Volodymyr Chernetskyi
034fca6c53 fix(move): zz does not center the cursor with wrapped lines #41656
Problem:
`scroll_cursor_halfway()` resets its `above` and `below` row counters on
every iteration of the `topline` scan, because they are declared inside
the loop. Each iteration then takes one line from each side regardless
of how many screen rows those lines occupy, so tall wrapped lines below
the cursor leave it near the top of the window instead of centered.

Affects the default `nosmoothscroll` path, reached from "zz" and from
`update_topline()`. Regression from 9b9ccac625 (vim-patch:9.0.1121),
which moved the declarations to their first use while porting; the
upstream patch did not touch them.

Solution:
Declare the counters at function scope, as Vim does, so they accumulate
across iterations.
2026-09-04 03:27:53 -04:00
Justin M. Keyes
5209695703 fix(multicursor): abandoned Visual selection does not move cursors #41670
Problem:
"v{motion}<Esc>" moves the primary cursor to the selection end, but the
other cursors snap back to their anchors unless follow-mode ("q=") is
on. The selection preview showed them at the selection end.

Solution:
Replay the abandoned selection at every cursor, not only in follow-mode.
An abandoned typed selection now always emits a "visual" CmdAtom.
2026-09-03 15:20:30 -04:00
Lewis Russell
ce8a897f98 feat(lua): add vim.async
Problem: Nvim has many Lua APIs that start callback-driven work: timers,
jobs, libuv handles, and other event-loop tasks. Callers that need to
sequence or cancel that work have to build their own coroutine wrappers,
task bookkeeping, and cleanup rules. This makes async control flow hard
to share, test, and document.

Solution: Add `vim.async`, a structured-concurrency module vendored from
async.nvim. It provides task handles, await/pawait helpers,
sleep/timeout helpers, completion-order iteration, and semaphores on top
of Nvim's event loop.

The API follows the same broad model as Trio: async work has an owner,
tasks are awaited explicitly, and cancellation is cooperative. Include
generated vimdoc with an introductory overview and examples, a news
entry, and functional tests for the new module.

AI-assisted
2026-09-03 19:17:25 +01:00
Justin M. Keyes
da4355ab8f fix(multicursor): 'guicursor' uses Normal shape in Visual mode #41669
Problem:
'guicursor' is not respected when extra cursors exist.

Per-cursor selection toggles Visual off, and the sandbox restores it
only after restore_current_state(), whose ui_cursor_shape() caches the
Normal shape.

Solution:
Restore Visual before restore_current_state().
2026-09-03 13:22:50 -04:00
Sébastien Hoffmann
3808c00fc8 fix(statusline): default 'statusline' improvements #41597
Problem: there should be exactly one cell of padding between sections,
and exactly one cell of minimum padding between the left and the right.
- Spaces between sections waste space when a section is empty.
  According to a comment in #33036, this was the reason to avoid `%k`
  and implement the keymap section with a vim expression, but other
  sections still have this problem.
- The diagnostics section wastes space because it is not entirely empty
  when there are diagnostics in another buffer.
- The terminal exit code section can touch the right side, e.g. the
  ruler, even though it belongs to the left side.
Solution:
- Use auto-hiding item groups (`%(` without width fields) to get rid of
  unneeded spaces when a section shows no information.
  This simplifies the 'showcmd' and 'keymap' sections in particular.
- As a slight simplification, `term_exitcode` is moved into the flags
  section since it is formatted with square brackets like a flag.
- Count the diagnostics for the current buffer specifically.
- Ensure at least one cell of padding between the left and the right
  side by adding a space next to the separator `%=`.

Problem: some sections are implemented with `%{%`, even though
reevaluation of the expression result is not needed.
This leads to otherwise needless %-escaping in `progress_status`.
Solution: use `%{` instead.

Problem: `%{` and `%{%` (without items) replace spaces with fillchars.
This looks out-of-place inside the terminal exit code section, and in
contrast to all other sections, the 'busy' section is surrounded by
fillchars, which looks inconsistent, and with some terminal-font
combinations, ◐ overlaps the fillchar, e.g. Alacritty & JetBrains Mono.
Solution: use non-breaking spaces U+202F to avoid fillchar substitution.

Problem: sections that appear/disappear frequently can make otherwise
more stable sections jump around a lot.
Solution: sort the sections on the right roughly by volatility:
'showcmd' in first place, 'keymap' next to the ruler.
2026-09-03 12:44:30 -04:00
Justin M. Keyes
ba0ee081c8 fix(coverity): DEADCODE, FORWARD_NULL, UNINIT #41667
Problem:

    CID 655469:           (DEADCODE)
    /build/src/nvim/auto/lua_api_c_bindings.generated.h: 7696             in nlua_api_nvim__mcursor_cascading()
    7690
    7691     exit_0:
    7692       arena_mem_free(arena_finish(&arena));
    7693       if (ERROR_SET(&err)) {
    7694         luaL_where(lstate, 1);
    7695         if (err_param) {
    >>>     CID 655469:           (DEADCODE)
    >>>     Execution cannot reach this statement: "lua_pushstring(lstate, "Inv...".
    7696           lua_pushstring(lstate, "Invalid '");
    7697           lua_pushstring(lstate, err_param);
    7698           lua_pushstring(lstate, "': ");
    7699         }
    7700         lua_pushstring(lstate, err.msg);
    7701         api_clear_error(&err);
    /build/src/nvim/auto/lua_api_c_bindings.generated.h: 7702             in nlua_api_nvim__mcursor_cascading()
    7696           lua_pushstring(lstate, "Invalid '");
    7697           lua_pushstring(lstate, err_param);
    7698           lua_pushstring(lstate, "': ");
    7699         }
    7700         lua_pushstring(lstate, err.msg);
    7701         api_clear_error(&err);
    >>>     CID 655469:           (DEADCODE)
    >>>     Execution cannot reach the expression "5" inside this statement: "lua_concat(lstate, (err_par...".
    7702         lua_concat(lstate, err_param ? 5 : 2);
    7703         return lua_error(lstate);
    7704       }
    7705
    7706       return 1;
    7707     }

    CID 655468:         Null pointer dereferences  (FORWARD_NULL)
    /src/nvim/mcursor.c: 833             in mc_ins_cascade()
    827           mc_ins_span_push(keys.items, NULL);
    828           mc_ins_preview_rebase();
    829         }
    830       } else if (ins.data != NULL && ins.size < mc_ins_span.done_len) {
    831         // Capture shrank without a restart signal, e.g. completion surgery rewrote the pending keys.
    832         mc_ins_cascade_restart();
    >>>     CID 655468:         Null pointer dereferences  (FORWARD_NULL)
    >>>     Passing null pointer "ins.data + mc_ins_span.done_len" to "mc_ins_keys_nonliteral", which dereferences it.
    833       } else if (ins.size > mc_ins_span.done_len
    834                  && mc_ins_keys_nonliteral(ins.data + mc_ins_span.done_len,
    835                                            ins.size - mc_ins_span.done_len)) {
    836         // Non-literal keys pending (BS, CTRL-U, ...): re-execute instead of previewing.
    837         mc_ins_span_flush(&ins, false);
    838       } else {

    CID 655467:         Uninitialized variables  (UNINIT)
    /src/nvim/mcursor.c: 1041             in mc_vsel_refresh()
    1035       for (size_t i = 0; i < kv_size(mc_cursors); i++) {
    1036         Context *ctx = &kv_A(mc_cursors, i);
    1037         pos_T pos;
    1038         if (!mc_ctx_resolve(ctx, &pos)) {
    1039           continue;
    1040         }
    >>>     CID 655467:         Uninitialized variables  (UNINIT)
    >>>     Using uninitialized value "pos". Field "pos.coladd" is uninitialized.
    1041         curwin->w_cursor = pos;
    1042         check_cursor(curwin);
    1044         Visual.select = false;
    1045         nvim_feedkeys(span, cstr_as_string("nix"), false);
    1046         if (!Visual.active) {

Solution:

- CID 655467 UNINIT: real (minor). `mc_vsel_refresh()` copied
  uninitialized local into `curwin->w_cursor`, and garbage coladd
  survived into the Visual replay (`equalpos()` compares it).
  - Fix: `pos_T pos = { 0 }`
- CID 655468 FORWARD_NULL: false positive
- CID 655469 DEADCODE: generated code. `nvim__mcursor_cascading`
  is flagged bc it is new,
- TODO: teach `gen_api_dispatch.lua` to omit the branch for
  parameterless functions.
2026-09-03 12:41:40 -04:00
Justin M. Keyes
e1a28e52b2 fix(editor): shada "force" load clears v:oldfiles #41662
Problem:
`shada_read()` rebuilds `v:oldfiles` for any "forced" read, which first
*clears* the list. For an in-memory caller such as multicursor, the list
is never repopulated. So `v:oldfiles` is empty after `Q` + edit.

Solution:
Rebuild `v:oldfiles` only when `kShaDaGetOldfiles` is requested.
`shada_read_everything()` (`:rshada[!]`, startup) always requests it.

old bug from 411a06c8b6
2026-09-03 11:32:20 -04:00
Justin M. Keyes
3beb15da57 fix(multicursor): live-mirror 'autocomplete' <BS> #41660
Problem:
During 'autocomplete', a completion-ending `<BS>` restarts completion
immediately. Multicursor insert-cascade skips replay (`edit()` refuses
to nest if compl/pum is active), so the mcursors do not update until
ESC.

Solution:
Flush pending keys in `TRIGGER_AUTOCOMPLETE`, just before autocomplete
restarts again.
2026-09-03 10:28:17 -04:00
Justin M. Keyes
e1cde28ba2 fix(multicursor): live-mirror Visual-mode operator mapping #41655
Problem:
Insert entered by a Visual-mode operator mapping (`xnoremap c c`) does
not live-mirror at cursors.

Solution:
Decide `typed` from the Visual session's own provenance (`vatom`, which
spans the selection and knows whether it was user input) instead of only
negating it.
2026-09-03 08:44:22 -04:00
Volodymyr Chernetskyi
73923b0dd8 fix(ssh): compare table length in the SSH config #41637
Problem:
`parse_ssh_config()` compares tables against a freshly allocated empty
table.
- In `parse_multiple_values()`, the guard which avoids flushing an empty
  accumulator never applies. Runs of separators and trailing whitespace
  push empty strings into the results, and `is_valid()` does not filter
  them. `Host  alpha   beta ` parses as `{ 'alpha', '', 'beta' }`.
- In `parse_value()`, the condition reduces to `chr == '"' and quoted`.
  `quoted` starts false and only that branch sets it, so it can never
  become true: quotes are never recognised and are inserted literally,
  and the unterminated-quote check is unreachable.

Solution:
Compare `#val` instead. Add a test for repeated and trailing separators.

AI-assisted
2026-09-03 06:40:58 -04:00
zeertzjq
51eacf284c fix(statuscolumn): heap buffer overflow with sign/number column (#41640)
Problem:  Drawing 'statuscolumn' leads to a heap-buffer-overflow if a
          sign/number column comes after many items.
Solution: Avoid curitem >= stl_items_len when writing to stl_items.
2026-09-03 16:56:41 +08:00
Volodymyr Chernetskyi
9222ed3a4a fix(filetype): report documented parameter name #41649
Problem:
Invalid `args` parameter for `vim.filetype.match()` reports wrong
parameter name `"arg"`.

Solution:
Report correct parameter name `"args"` instead.
2026-09-03 04:10:05 -04:00
Volodymyr Chernetskyi
9a8966879a fix(iter): keep take() predicate within bounds #41635
Problem:
`IterArray:take()` iterates up to `self._tail`, but `_tail` is
exclusive. When no element fails the predicate, the loop reads one index
past the last element and calls the predicate with `nil`.

Solution:
Stop at `self._tail - inc`, which is the last in-range index for both
iteration directions. Add tests using a predicate which dereferences its
argument and matches every element, forward and reversed.

AI-assisted
2026-09-03 03:23:45 -04:00
zeertzjq
b51a0b2dcc vim-patch:9.2.1036: syntax highlighting is slower than necessary (#41644)
Problem:  While advancing the syntax highlighting, store_current_state()
          calls syn_stack_find_entry() about once per parsed line, and
          that function rescans the state-cache list from its head every
          time. With the list capped at 1000 entries this linear rescan
          dominates the cost of highlighting a large file.
Solution: Keep a cached position to the entry last located in the list
          and resume the scan from it when it is at or before the wanted
          line, advancing the finger as new states are stored
          (Julien Voisin).

The list is sorted by line number, so when the remembered entry is at or
before the wanted line the answer can only follow it, never precede it;
resuming from there returns the same entry as a scan from the head.  The
"at or before" guard keeps this correct for any lookup order: a backward
or random-access lookup whose remembered entry is past the wanted line
falls back to a full scan.  The pointer is cleared whenever an entry is
freed, the array is reallocated or the block is freed, so it cannot
dangle.

Parsing the syntax of a 20000-line C file is about a third faster, a
5000-line file about a quarter faster, benchmarked via something like
this:

```
call synID(1, 1, 1)              " warm-up
let s = reltime()
for l in range(1, line('$')) | call synID(l, 1, 1) | endfor
call writefile([reltimefloat(reltime(s))], $T)
```

closes: vim/vim#21166

f1b4549129

Co-authored-by: Julien Voisin <julien.voisin@dustri.org>
2026-09-03 11:07:44 +08:00
zeertzjq
7645d7e232 vim-patch:9.2.1035: filetype: Github citation files are not recognized (#41643)
Problem:  filetype: Github citation files are not recognized
Solution: Detect *.cff files as yaml filetype (Wu Zhenyu).

Reference:
https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-citation-files

closes: vim/vim#21163

05de894401

Co-authored-by: Wu, Zhenyu <wuzhenyu@ustc.edu>
2026-09-03 11:07:12 +08:00
zeertzjq
aff123a5d4 vim-patch:9.2.1034: NFA regexp matching is slow for ASCII text (#41642)
Problem:  NFA regexp matching is slower than necessary for ASCII text
          because two indirect function calls are made for every
          character.
Solution: Add an inline fast path for an ASCII byte that is not followed
          by a composing character (Julien Voisin).

The main loop of nfa_regmatch() fetched the current character and its
byte length with two calls through the mb_ptr2char and mb_ptr2len
function pointers on every character.  These pointers cannot be inlined,
yet for ASCII text, which is the common case, both merely return the byte
and a length of one.

Handle that case inline.  NUL is checked first so that reading the next
byte cannot go past the end of the line, and the "next byte is ASCII"
condition matches the check in utfc_ptr2len(), so a base character
followed by a composing character still falls through to the original
calls.

A "perf stat -e instructions" on a full scroll of a 60000 line C file with
syntax highlighting enabled shows an instructions count reduction of 4%.

closes: vim/vim#21179

58390ca285

Co-authored-by: Julien Voisin <julien.voisin@dustri.org>
2026-09-03 11:06:35 +08:00
zeertzjq
89837bdd72 vim-patch:9.2.1032: scrolling moves cursor up with 'scrolloffpad' (#41641)
Problem:  Cursor correction can move the cursor up at the end of the
          buffer when 'scrolloffpad' is enabled (gx089).
Solution: Allow missing context below EOF in cursor_correct().  Add
          regression tests for CTRL-D and CTRL-E (Seunghee Kim).

fixes:   vim/vim#21096
closes:  vim/vim#21188

6a3db67a52

Co-authored-by: SeungheeKim <ksh368@naver.com>
2026-09-03 11:05:33 +08:00
dependabot[bot]
4b3ab0d6bd ci: bump the github-actions group across 1 directory with 3 updates
Bumps the github-actions group with 3 updates in the / directory: [github/codeql-action](https://github.com/github/codeql-action), [vmactions/freebsd-vm](https://github.com/vmactions/freebsd-vm) and [vmactions/openbsd-vm](https://github.com/vmactions/openbsd-vm).


Updates `github/codeql-action` from 4.37.8 to 4.37.9
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v4.37.8...v4.37.9)

Updates `vmactions/freebsd-vm` from 1.5.4 to 1.5.5
- [Release notes](https://github.com/vmactions/freebsd-vm/releases)
- [Commits](d0518f9125...f0552d3b69)

Updates `vmactions/openbsd-vm` from 1.4.6 to 1.4.7
- [Release notes](https://github.com/vmactions/openbsd-vm/releases)
- [Commits](e6c68b637a...86cdc08415)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.37.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: vmactions/freebsd-vm
  dependency-version: 1.5.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: vmactions/openbsd-vm
  dependency-version: 1.4.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-02 23:58:45 +02:00
Jan Edmund Lazo
e034dbadec build(vim-patch): n/a 5400a5d4269874fe4f1c35dfdd3c039ea17dfd62
comment,editorconfig plugins in Vim's runtime/pack/, are N/A.
Editorconfig is unrelated but Vim did not fix the bundled version
from editorconfig-vim and did not port the upstream fix.

0d54ea8630
2026-09-02 17:44:53 -04:00
Jan Edmund Lazo
9d51351218 build(vim-patch): 2ca7d5f4831ce3d86cdc3f0c844fc50ea0deb7e5 is n/a
v9.1.1029 removes runtime/doc/uganda.rux.
2026-09-02 17:44:52 -04:00
Jan Edmund Lazo
bb3adbe52e build(vim-patch): v9.0.1994 is n/a 2026-09-02 17:44:52 -04:00
Jan Edmund Lazo
84f66fa687 build(vim-patch): v9.0.1557 is n/a
Global variables with "_for_testing" suffix are modified
in "f_test_override()", N/A to Nvim.
If a test needs them, then port the relevant code outside
"f_test_override()" via LuaJIT C FFI.
2026-09-02 17:44:52 -04:00
Volodymyr Chernetskyi
0ecca23ee2 fix(treesitter): accept a string title in inspect_tree() #41639
Problem:
`inspect_tree()` documents `title` as
`string|fun(bufnr:integer):string|nil`, but the implementation handles
only `nil` and function values. A string title leaves `title` unset and
fails the assertion below.

Solution:
Use the string as the title.
2026-09-02 17:01:54 -04:00
Volodymyr Chernetskyi
a58cee4512 fix(lsp): respect range in linewise visual mode #41636
Problem:
An explicitly passed `range` to `vim.lsp.buf.format()` in linewise
visual mode is silently replaced by the selection.

Solution:
Parenthesise the mode check.
2026-09-02 17:01:32 -04:00
Volodymyr Chernetskyi
10fa98bb6e fix(pack): read document links from the request buffer #41638
Problem:
The `textDocument/documentLink` handler resolves the confirmation buffer
from the request URI and checks it for `nil`, then reads lines from
buffer `0`. When the confirmation buffer is not current, links are
computed from unrelated text and returned against the confirmation
buffer's line numbers, producing missing or misplaced links.

Solution:
Read lines from the resolved `bufnr`.

AI-assisted
2026-09-02 16:58:26 -04:00
Volodymyr Chernetskyi
45b645718c fix(keymap): report the documented parameter name #41633
Problem:
Invalid `modes` parameter for `vim.keymap.del()` reports wrong parameter
name `"mode"`.

Solution:
Report correct parameter name `"mode"` instead.
2026-09-02 16:27:20 -04:00