Commit Graph

20326 Commits

Author SHA1 Message Date
zeertzjq
34288b3eec vim-patch:9.2.0339: regexp: nfa_regmatch() allocates and frees too often (#38996)
Problem:  nfa_regmatch() allocates and frees two list buffers on every
          call, causing unnecessary memory allocation overhead for
          frequently used patterns.
Solution: Cache the list buffers in the regprog struct and reuse them
          on subsequent top-level calls. Recursive calls still allocate
          their own buffers. Free cached buffers in nfa_regfree()
          (Yasuhiro Matsumoto).

Benchmark: 10K lines, `:%s` x50 iterations

| Pattern | Before | After | Improvement |
|---|---|---|---|
| `\<\(\w\+\%(ing\|tion\|ed\|ly\)\|\w\{3,}\)\>` (many matches) | 4.384s | 4.299s | -2% |
| `\(foo\|bar\|baz\)\{3,}\(qux\|quux\|corge\)\{2,}...` (no match, high nstate) | 16.927s | 3.015s | -82% |

closes: vim/vim#19956

105d65e29b

Co-authored-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
2026-04-13 07:30:32 +08:00
glepnir
fcdb148437 fix(pum): info float width grows on reselect with 'linebreak' #38680
Problem: win_linetabsize() includes wrap overhead from 'linebreak'
based on current window width, but the result sizes the window,
causing a feedback loop.

Solution: Temporarily set w_view_width to Columns before measuring.
2026-04-12 11:42:27 -04:00
glepnir
1033739b60 feat(api): nvim_set_hl can set "font" #37668
Problem: Cannot set highlight group fonts via API, only via :highlight
command.

Solution: Add font parameter in nvim_set_hl().
2026-04-12 11:19:40 -04:00
Barrett Ruth
b7cbad7489 fix(tui): use erase_chars for short clears #38973
Problem:
Due to optimizations c936ae0f36, nvim prints literal spaces instead of using
`erase_chars` in widths <= 5 even if the terminal advertises `erase_chars`
support (perhaps a small-output size heuristic). However, this is not
semantically neutral: in some terminals, erased cells and printed spaces are
copied differently.

I ended up with two useful groups of results.

First, I tested raw terminal behavior without nvim involved:

    | Terminal | Raw plain text | Raw `erase_chars` | Raw literal spaces |
    | --- | --- | --- | --- |
    | xterm | clean | trailing spaces copied | trailing spaces copied |
    | xfce4-terminal | clean | clean | trailing spaces copied |

Second, I tested nvim itself:

    | Terminal | no patch | with this patch |
    | --- | --- | --- |
    | xfce4-terminal | trailing spaces reproduced | clean |
    | xterm | trailing spaces reproduced | trailing spaces reproduced |
    | Alacritty | clean | clean |
    | Ghostty | clean | clean |
    | WezTerm | clean | clean |

Nvim often prints spaces instead of sending `erase_chars`, which this patch
changes for short clears when the terminal advertises it. This fixes
xfce4-terminal because raw `erase_chars` are already cleaned up by the terminal,
while spaces aren't. ***Notably, xterm is different***: even when `erase_chars`
is sent directly (NO NVIM INVOLVED) xterm *still* copies those cleared blank
trailing cells (and this is documented). So for xterm, which is the only
remaining problematic fix, I'm quite sure there's nothing we ought to do on the
Nvim side.

Solution:
Drop the `width >= 5` condition.
2026-04-12 10:30:06 -04:00
Justin M. Keyes
52d466c500 Merge #38882 docs 2026-04-12 08:45:46 -04:00
Barrett Ruth
6e95d1ad13 fix(normal): pass count to 'keywordprg' as arg1 #38965
Problem:
If `'keywordprg'` begins with `:`, `3K` turns the count into an Ex
range. Commands that don't support that then fail. Vim passes the count
as the first arg (see #19436, vim/vim#10745).

Solution:
Pass `[count]` as the first arg for `'keywordprg'`.
2026-04-12 08:44:56 -04:00
glepnir
49086862fc fix(api): nvim_get_hl drops groups defined with link_global #38492
Problem: hlgroup2dict passes &ns_id to ns_get_hl twice. The first call
(link=true) sets *ns_hl = 0 when link_global is set, so the second call
and the sg_cleared guard both see ns_id == 0 and bail out. The group is
silently dropped from the result.

Solution: use a temporary copy of ns_id for each ns_get_hl call so the
original value is preserved.
2026-04-12 08:38:35 -04:00
Justin M. Keyes
a321c9adad docs: misc
Close #38748
Close #38866

Co-authored-by: Mario Loriedo <mario.loriedo@gmail.com>
Co-authored-by: Anakin Childerhose <anakin@childerhose.ca>
2026-04-12 14:17:50 +02:00
mnikic
2f6c560002 build: support GNU Hurd by skipping BSD sysctl checks #38975
Problem:
Neovim currently fails to build on GNU Hurd. Because Hurd relies on
glibc, `<sys/param.h>` defines the `BSD` macro for 4.4BSD compatibility.
The preprocessor incorrectly routes Hurd into the BSD code paths, which
fatally fail during compilation because Hurd lacks `<sys/sysctl.h>` and
the `sysctl()` function.

Solution:
Update the preprocessor guards in  `os/proc.c` to explicitly exclude
`__gnu_hurd__` from the BSD-specific `sysctl` blocks. Instead, group GNU
Hurd with the `__linux__` paths, as both systems rely on standard POSIX
interfaces and `/proc` parsing (which Hurd fully supports via its
`procfs` translator).

Testing:
The test suite does not fully pass yet natively on GNU Hurd
(specifically tests involving PTY closures and SIGHUP/SIGTERM trapping,
like `autocmd TermClose kills PTY job`). This is due to underlying
differences in Hurd's Mach RPC architecture and the `term` translator.
This patch does not attempt to fix those test executions, but simply
unblocks the core compiler as a necessary first step.
2026-04-12 08:07:15 -04:00
jdrouhard
73cfc3ca03 perf(ui): check rectangle intersection when looking for covering grids #38500
Problem:
The ui compositor does not use grid_scroll events when a grid other than
the built in msg_grid exists above the scrolled grid, regardless of
whether it actually intersects the scrolled grid anywhere in the
scrolled region.

When another layer exists at a higher zindex, the ui compositor falls
back to composing every line of the scrolled grid. This is especially
evident when using ui2 which creates a floating window that replaces the
built-in msg_grid. Scrolling around with ui2 enabled has poor
performance because the entire grid is recomposed on every scroll
instead of using grid_scroll.

Solution:
Instead of just checking whether another grid exists at a higher zindex
than curgrid, ensure there's a grid above the curgrid that is positioned
over the particular rectangle of interest, which could be a subrectangle
of the whole grid.

Grids above the curgrid that don't intersect there no longer count as
covering the curgrid, and the compositor can continue to use grid_scroll
scroll events. The floating window created for the command line/messages
with ui2 never intersects with the scrolled region of the main window
grid, which allows performant scrolling with it enabled.
2026-04-12 07:44:35 -04:00
Justin M. Keyes
6f015cdcdf feat(connect): filepath completion #38959
This is a stop-gap; the next step is for :connect to show a menu of
known peers (and perhaps also any files in CWD that look like sockets).
2026-04-11 11:05:13 -04:00
glepnir
01567ad4f6 fix(highlight): preserve inherited colors when update=true breaks links #38750
Problem: Breaking a link with update=true loses colors inherited from
the linked group.

Solution: Copy color indices from the linked group so inherited colors
remain visible in :hi output.
2026-04-11 10:14:27 -04:00
github-actions[bot]
0cb6dde5ee docs: update version.c #38816
vim-patch:9.2.0313: Callback channel not registered in GUI
vim-patch:9.2.0319: popup: rendering issues with partially transparent popups
vim-patch:9.2.0322: tests: test_popupwin fails
vim-patch:3e194b106 runtime(vimball): detect more path traversal attacks
vim-patch:9.2.0335: json_encode() uses recursive algorithm

vim-patch:9.2.0309: Missing out-of-memory check to may_get_cmd_block()
vim-patch:9.2.0310: unnecessary work in vim_strchr() and find_term_bykeys()

vim-patch:8.2.2824: MS-Windows: build failure with MSVC
vim-patch:9.1.1692: global_functions are not constant
2026-04-11 09:12:58 -04:00
zeertzjq
4f7b6083e5 vim-patch:9.2.0331: spellfile: stack buffer overflows in spell file generation (#38948)
Problem:  spell_read_aff() uses sprintf() into a fixed-size stack buffer
          without bounds checking. store_aff_word() uses STRCAT() to
          append attacker-controlled strings into newword[MAXWLEN] without
          checking remaining space. Both are reachable via :mkspell with
          crafted .aff/.dic files (xinyi234)
Solution: Replace sprintf() with vim_snprintf() in spell_read_aff().
          Replace STRCAT() with STRNCAT() with explicit remaining-space
          calculation in store_aff_word().

closes: vim/vim#19944

07faa961a0

Co-authored-by: Christian Brabandt <cb@256bit.org>
2026-04-10 23:39:54 +00:00
Olivia Kinnear
8715877417 feat(ex): add :log command 2026-04-10 11:08:26 -05:00
Olivia Kinnear
6bea0cdbdc feat(logs)!: move logs to stdpath("state")/logs 2026-04-09 21:54:33 -05:00
zeertzjq
9c5fba5df0 fix(messages): truncate warning messages only in display (#38901)
For now, add a private "_truncate" flag to nvim_echo, using a truncation
method similar to showmode().
2026-04-09 04:11:32 +00:00
Jordan
3a4a66017b feat(api): rename buffer to buf #35330
Problem:
`:help dev-name-common` states that "buf" should be used instead of
"buffer" but there are cases where buffer is mentioned in the lua API.

Solution:
- Rename occurrences of "buffer" to "buf" for consistency with the
  documentation.
- Support (but deprecate) "buffer" for backwards compatibility.

Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2026-04-08 20:34:47 -04:00
Sean Dewar
1ff1973269 fix(api)!: nvim_clear_autocmds() "event" handling
Problem: nvim_clear_autocmds() does not type check "event" correctly, and also
treats an empty array "event" like nil.

Solution: fix type checking. Treat empty array "event" as a no-op, like
nvim_exec_autocmds(). Add some extra tests.

Likewise the nil handling change may be considered breaking if anyone
(unintentionally) relied on that. It was also true that integer, function, etc.
"event"s would also be treated like nil!

Note that an empty string "event" is still an error, as that's must be an exact
match on an event name.
2026-04-08 21:48:38 +01:00
Sean Dewar
eaea0c0f9d docs(api): nvim_exec_autocmds() default "pattern"
Problem: nvim_exec_autocmds() documentation incorrectly describes the default
for "pattern" as *, when it's actually the current file name (like :doautocmd).

Solution: correct it. Add a test.
2026-04-08 21:48:38 +01:00
Sean Dewar
446e794a9c fix(api)!: empty non-nil autocmd "pattern" handling
Problem: in autocmd APIs, a non-nil "pattern" containing only empty
'sub'-patterns is silently treated as nil, causing the fallback value to be
unexpectedly used instead.

Solution: for nvim_create_autocmd(), raise a validation error (as no autocmds
would be created). For nvim_{exec,clear}_autocmds(), make it a no-op (as
matching no autocmds is not an error).
2026-04-08 21:48:38 +01:00
luukvbaal
b35a2e58e9 fix(statusline): no window-local highlights for last line 'ruler' #38879
Problem:  When the 'ruler' is in the last line of the screen, it takes
          local highlight definitions of the current window, tripping an
          assert (since c1648cf8).
Solution: Don't use window-local highlight definitions when the ruler is
          not part of a statusline.

Co-authored-by: glepnir <glephunter@gmail.com>
2026-04-08 12:02:34 -04:00
glepnir
8603fc9180 fix(pum): crash with 'pumborder' and wide item (#38852)
Problem: pum_col goes negative when item width + border exceeds screen.

Solution: account for border_width in pum_compute_horizontal_placement()
instead of adjusting pum_col after the fact
2026-04-08 09:16:41 +08:00
zeertzjq
5d66ef188f fix(rpc): trigger UILeave earlier on channel close (#38846)
Problem:
On exit, rpc_free() is called when processing main_loop.events after
libuv calls close callbacks of the channel's stream. However, when there
are no child processes, these libuv callbacks are called in loop_close()
instead of proc_teardown(), and main_loop.events isn't processed after
loop_close(). As a result, calling remote_ui_disconnect() in rpc_free()
causes UILeave to depend on the presence of child processes.

Solution:
Always call remote_ui_disconnect() in rpc_close_event(), and remove the
call in rpc_free().
2026-04-08 05:29:08 +08:00
luukvbaal
7fff91359e fix(message): flush messages before "empty" msg_show #38854
Problem:  When emitting a msg_show event with the "empty" kind,
          there may still be messages waiting to be emitted, which
          are then dropped as a result of recursion protection.
Solution: Flush messages before emitting "empty" message show.
2026-04-07 13:08:55 -04:00
zeertzjq
2df2e72e0a fix(undo): undefined behavior with empty entry in 'undodir' (#38849)
Problem:  Undefined behavior when 'undodir' contains empty entry.
Solution: Don't try to remove trailing slashes from empty path. Also
          don't remove a colon on Windows while at it.
2026-04-07 14:49:05 +08:00
zeertzjq
6b0367481c fix: don't make path empty when truncating trailing slashes (#38844)
Fixes the following Coverity warning:

*** CID 549779:         Integer handling issues  (INTEGER_OVERFLOW)
/src/nvim/undo.c: 717             in u_get_undo_file_name()
711           dir_name[dir_len] = NUL;
712
713           // Remove trailing pathseps from directory name
714           char *p = &dir_name[dir_len - 1];
715           while (vim_ispathsep(*p)) {
716             *p-- = NUL;
>>>     CID 549779:         Integer handling issues  (INTEGER_OVERFLOW)
>>>     Expression "dir_len--", where "dir_len" is known to be equal to 0, underflows the type of "dir_len--", which is type "size_t".
717             dir_len--;
718           }
719
720           bool has_directory = os_isdir(dir_name);
721           if (!has_directory && *dirp == NUL && !reading) {
722             // Last directory in the list does not exist, create it.
2026-04-07 10:07:32 +08:00
zeertzjq
e94e469324 Merge pull request #38669 from SanzharKuandyk/fix-38667
fix(channel): fix Windows console regressions from #37977
2026-04-07 08:48:07 +08:00
zeertzjq
b36eafd5da vim-patch:794c304: runtime(doc): clarify incsearch feature and typed chars (#38830)
fixes: vim/vim#19886

794c304479

Co-authored-by: Christian Brabandt <cb@256bit.org>
2026-04-07 06:22:45 +08:00
zeertzjq
9d6453b771 vim-patch:9.2.0312: C-type names are marked as translatable (#38829)
Problem:  C-type names are marked as translatable
Solution: Use them as-is, do not translate them
          (Eisuke Kawashima)

closes: vim/vim#19861

a5b6c2d6e9

Co-authored-by: Eisuke Kawashima <e-kwsm@users.noreply.github.com>
2026-04-07 06:22:32 +08:00
luukvbaal
1354787029 fix(cmdline): 'inccommand' preview after setcmdline() #38795
Problem:  'inccommand' preview is not executed after setcmdline(),
          and as a result cmdline_show event is emitted when redrawing
          is not allowed (5b6477be).
Solution: Call command_line_changed() when ccline.cmdbuff_replaced is
          set (by setcmdline()).
2026-04-06 13:15:46 -04:00
Josh Triplett
889572a358 fix(tui): check background color on resume #38726
Problem:
We normally get the background color via continuous reporting. However,
if we were backgrounded while the light/dark mode changed, we won't have
received the report, and we'll have the wrong background color.

Without this change, if you background nvim, toggle the light/dark mode,
resume, and check `:set bg`, it will not match the current state.

Solution:
Query it on resume as well. (This requires separating the query from the
flush, to just do the query along with all the others, while waiting to
flush until we've set up uv.)

With this change, if you background nvim, toggle the light/dark mode,
resume, and check `:set bg`, it will have updated.
2026-04-06 12:44:03 -04:00
Luuk van Baal
fa302037f9 fix(events): avoid recursive loop_uv_run() from vim.ui_attach() shell message
Problem:  vim.ui_attach() msg_show callback runs the risk of a recursive
          loop_uv_run() when trying to display a message from a shell
          command stream.
Solution: Schedule the message callback on the fast_events queue.
2026-04-06 10:07:23 +02:00
Sanzhar Kuandyk
8bb7533639 fix(channel): fix Ctrl-C handling regression in terminal
Problem: Normal Windows builtin-TUI startup spawns the embedded server as DETACHED_PROCESS, which breaks Ctrl-C delivery to :terminal jobs.
Solution: Restores the default behavior once the embedded server has a
console so terminal jobs inherit it.
2026-04-06 11:17:48 +05:00
nameearly
eb9be11da8 refactor(typval.c): fix wrong argument to macro (#38813) 2026-04-06 04:11:57 +00:00
zeertzjq
870e50f0ff vim-patch:9.2.0293: :packadd may lead to heap-buffer-overflow
Problem:  :packadd may lead to heap-buffer-overflow when all entries in
          'runtimepath' have the same length (after 9.2.0291).
Solution: Check for comma after current entry properly (zeertzjq).

related: vim/vim#19854
closes:  vim/vim#19911

bc182ae56e
2026-04-06 11:47:44 +08:00
zeertzjq
4d7dfa081b vim-patch:9.2.0291: too many strlen() calls
Problem:  too many strlen() calls
Solution: refactor concat_fname() and remove calls to strlen()
          (John Marriott)

Function `concat_fnames()` can make up to 5 calls to `STRLEN()` (either
directly or indirectly via `STRCAT()`). In many cases the lengths of
arguments `fname1` and/or `fname2` are either known or can simply be
calculated.

This Commit refactors this function to accept the lengths of arguments
`fname1` and `fname2` as arguments. It also adds new argument `ret` to
return the resulting string as a `string_T`.

Additionally:
- function `add_pack_dir_to_rtp()` in `scriptfile.c`:
   Use a `string_T` to store local variables `new_rtp` and `afterdir`.
   Replace calls to `STRCAT()` with calls to `STRCPY()`.
   Change type of variable `keep` to `size_t` for consistency with
   other lengths.

- function `qf_get_fnum()` in `quickfix.c`:
  Use a `string_T` to store local variables `ptr` and `bufname`
- function `qf_push_dir()` in `quickfix.c`:
  Use a `string_T` to store local variable `dirname`.
  Replace call to `vim_strsave()` with `vim_strnsave()`.

- function `qf_guess_filepath()` in `quickfix.c`:
  Use a `string_T` to store local variable `fullname`.

- function `make_percent_swname()` in `memline.c`:
  Rename some variables to better reflect their use.
  Use a `string_T` to store local variables `d` and `fixed_name`.
  Slightly refactor to remove need to create an extra string.
- function `get_file_in_dir()` in `memline.c`:
  Use a `string_T` to store local variables `tail` and `retval`.
  Move some variables closer to where they are used.

- function `cs_resolve_file()` in `if_cscope.c`:
  Use a `string_T` to store local variable `csdir`.
  Remove one call to `STRLEN()`.

- function `add_pathsep()` in `filepath.c`:
  Refactor and remove 1 call to `STRLEN()`

- function `set_init_xdg_rtp()` in `option.c`:
  Use a `string_T` to store local variable `vimrc_xdg`.

closes: vim/vim#19854

cb51add7ae

Co-authored-by: John Marriott <basilisk@internode.on.net>
Co-authored-by: Christian Brabandt <cb@256bit.org>
2026-04-06 11:47:44 +08:00
Justin M. Keyes
42f6c55139 Merge #38796 from justinmk/doc2 2026-04-05 20:36:45 -04:00
Justin M. Keyes
6b796696c3 docs: statusline
fix https://github.com/neovim/neovim/issues/38670
2026-04-06 02:29:29 +02:00
Elijah Koulaxis
bba48ee1b0 fix(windows): force console codepage to UTF-8 for shell/system() #38742
Problem:
On Windows, `:!echo тест` shows `????` because the console code page defaults to a legacy ANSI encoding (e.g. CP1252) instead of `UTF-8`

Solution:
Call `SetConsoleOutputCP(CP_UTF8)` and `SetConsoleCP(CP_UTF8)` in `do_os_system()` before spawning child processes, and restore the original values after. It covers both `:!` and `system()` since they both go through `do_os_system()`
2026-04-05 19:16:48 -04:00
Jibril
cfbac23235 fix(coverity): coverity/530031, coverity/530027 resource leaks #37916
Fixed resource leak caused by overwriting lp->sl_midword by freeing
lp->sl_midword first.
2026-04-05 15:08:30 -04:00
zeertzjq
9705a1c13b fix(help): show error when using :help! with nothing at cursor #38775
It's possible to still show the old Easter egg, but then the user won't
know about the new feature, so showing E349 is better.
2026-04-05 10:59:22 -04:00
github-actions[bot]
38c32aa029 docs: update version.c #38752
vim-patch:9.2.0286: still some unnecessary (int) casts in alloc()
vim-patch:9.2.0288: libvterm: signed integer overflow parsing long CSI args
vim-patch:bd8b6c6b0 CI: Bump codecov/codecov-action
vim-patch:9.2.0294: if_lua: lua interface does not work with lua 5.5
vim-patch:9.2.0297: libvterm: can improve CSI overflow code

vim-patch:8.2.0356: MS-Windows: feedkeys() with VIMDLL cannot handle CSI
vim-patch:8.2.0647: MS-Windows: repeat count for events was not used
2026-04-05 10:51:18 -04:00
zeertzjq
9927d9259d fix(:restart): inherit stderr fd on Unix (#38755)
This in turn gives TTY access to channel_from_stdio() in the new server,
if the old server has access to a TTY.
2026-04-04 21:57:27 +08:00
zeertzjq
e20c4ea966 fix(channel): crash on exit after closing v:stderr channel (#38754)
Problem:  Crash on exit after closing v:stderr channel when piping
          to stdin.
Solution: Reopen stderr as /dev/null or NUL instead of closing it.
          This also avoids writing to an related file if one is opened
          after closing v:stderr.
2026-04-04 20:54:27 +08:00
zeertzjq
426cbfbd76 vim-patch:9.2.0298: Some internal variables are not modified (#38758)
Problem:  Some internal variables are not modified
Solution: Add const qualifier to static table data
          (Hirohito Higashi).

Several static arrays that are never modified at runtime were missing the
const qualifier. Add const to move them from .data to .rodata section.

closes: vim/vim#19901

3c79e33aeb

Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
2026-04-04 20:50:01 +08:00
zeertzjq
e2bced7703 vim-patch:9.2.0296: Redundant and incorrect integer pointer casts in drawline.c (#38757)
Problem:  Currently `colnr_T` and `int` and the same type, so casting
          `int *` to `colnr_T *` is redundant. Additionally, even if
          they are changed to different types in the future, these casts
          are incorrect as they won't work on big-endian platforms.
Solution: Remove the casts. Also fix two cases of passing false instead
          of 0 to an integer argument (zeertzjq).

related: vim/vim#19672
closes:  vim/vim#19907

18cd55dbc4
2026-04-04 20:49:43 +08:00
zeertzjq
d10dda8a47 vim-patch:9.2.0295: 'showcmd' shows wrong Visual block size with 'linebreak' (#38756)
Problem:  'showcmd' shows wrong Visual block size with 'linebreak' after
          end char (after 7.4.467).
Solution: Exclude 'linebreak' from end position. Also fix confusing test
          function names.

closes: vim/vim#19908

08bd9114c1
2026-04-04 20:49:26 +08:00
zeertzjq
164dfa1d5f vim-patch:9.2.0289: 'linebreak' may lead to wrong Visual block highlighting (#38749)
Problem:  'linebreak' may lead to wrong Visual block highlighting when
          end char occupies multiple cells (after 7.4.467).
Solution: Exclude 'linebreak' from the ending column instead of setting
          'virtualedit' temporarily (zeertzjq).

fixes:  vim/vim#19898
closes: vim/vim#19900

23be1889d1
2026-04-04 08:58:17 +08:00
zeertzjq
20e46cb38d vim-patch:af58a9f: runtime(doc): adjust :h 'autowrite' and :h 'autowriteall'
- Don't go over 78 columns.
- Change the first "and" to "or", as "or" is used below.
- Change "takes one" to "switches", as "one" may be mistaken as
  referring to the command instead of the user.
- Use backticks in :h 'autowriteall' like in :h 'autowrite'.

closes: vim/vim#19859

af58a9f5e9
2026-04-04 06:04:28 +08:00