Commit Graph

19682 Commits

Author SHA1 Message Date
Justin M. Keyes
b351024daf build(docs): lint more quasi-keysets #39654
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.
2026-05-07 16:00:26 +00:00
Szymon Wilczek
3639f7a867 feat(server): add v:useractive, use it in serverlist(info=true) #39423
Problem:
When showing the :connect menu, it is useful to know which servers
are most-recently active. But we don't have a good way to detect that.

Solution:
- Introduce `v:useractive`.
- Include this timestamp in `serverlist({info=true})`.

Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
Signed-off-by: Szymon Wilczek <swilczek.lx@gmail.com>
2026-05-07 10:47:51 -04:00
Quentin
97a557bd1e docs: expand nvim_create_user_command docs #39540 2026-05-07 09:18:19 -04:00
Szymon Wilczek
0c3e6e1b0e fix(treesitter): crash in ts_parser_delete after gc #39497
Problem:
parser_gc() calls ts_parser_delete() but leaves the userdata pointer
pointing to freed memory. If the GC finalizer runs at an unexpected time
(e.g. inside nvim_buf_get_lines #39411), a stale pointer could cause a crash.

Solution:
- NULL out `*ud` after ts_parser_delete() in parser_gc()
- Update parser_check() to handle NULL with a clear error message,
guarding all parser methods against UAF

Co-authored-by: Lewis Russell <lewis6991@gmail.com>
Signed-off-by: Szymon Wilczek <swilczek.lx@gmail.com>
2026-05-07 08:39:07 -04:00
Justin M. Keyes
df5d559878 Merge #39626 docs 2026-05-07 05:00:55 -04:00
glepnir
1fd82615b1 refactor(excmd): remove duplicate get_cmd_argt (#39643)
Problem:
`excmd_get_argt` and `get_cmd_argt` do the same thing.

Solution:
Drop `get_cmd_argt` and update its callers to use `excmd_get_argt`.
2026-05-07 08:55:30 +00:00
Justin M. Keyes
662c556a3e docs: rename "tabpage" 2026-05-07 10:36:55 +02:00
Justin M. Keyes
80d83d75eb docs: misc, rename "tabpage"
Co-authored-by: michael-grunder <michael.grunder@gmail.com>
Co-authored-by: Olivia Kinnear <git@superatomic.dev>
Co-authored-by: Felipe Matarazzo <felipemps@protonmail.com>
2026-05-07 10:36:48 +02:00
github-actions[bot]
d12dd07c7a docs: update version.c #39466
vim-patch:1de887681 No guidance for AI coding agents
vim-patch:9.2.0421: vimball: can smuggle Vimscript into VimballRecord file
vim-patch:620557bd4 runtime(doc): Update help tags file
vim-patch:9.2.0422: popup: leave stray char when scrollbar changes
vim-patch:9.2.0431: blob encoding can be improved
vim-patch:9.2.0434: cscope: filename interpreted by /bin/sh
vim-patch:9.2.0448: Vim9: dangling cmdline pointer after skip_expr_cctx()
vim-patch:9.2.0449: Make proto fails in non GTK builds


vim-patch:9.2.0409: memory leaks in copy_substring_from_pos()
2026-05-07 03:19:43 -04:00
luukvbaal
dda30fdfbb fix(messages): disallow source="nvim" progress msg #39315
Problem:  Internal progress messages use the "nvim" source (since
          ff68fd6b), plugins shouldn't be allowed to set the progress
          message source to "nvim". The message ID used for internal
          progress messages is not identifiable as such.
Solution: Disallow setting opts->source to "nvim" with nvim_echo().
          Refactor msg_progress() and callees to bypass nvim_echo().
          Prepend message id for internal progress messages with "nvim.".
2026-05-06 12:25:25 -04:00
Szymon Wilczek
c3f803c3b6 feat(server): serverlist({info=true}) gets detailed info #39392
Problem:
UI tools and orchestration engines need more context than just raw
socket addresses from serverlist(). Without knowing if a server belongs
to the current instance or knowing its PID, UIs cannot display
meaningful options to users.

Solution:
- Added the `info=v:true` option to `serverlist()`.
- When `info` is requested, it implies `peer=true` and returns a list of
  dictionaries (defined as `vim.ServerInfo`) with `addr`, `pid` and
  `own`.
- Uses an RPC request to `getpid()` across the socket to fetch the
  peer's actual process ID.

Signed-off-by: Szymon Wilczek <swilczek.lx@gmail.com>
2026-05-06 08:55:34 -04:00
glepnir
1787965d77 feat(api): nvim_get_commands returns desc #39623
Problem:
Can't get a command's description from nvim_get_commands when
cmd is string.

Solution:
Returns "desc" field in nvim_get_commands.
`definition` is now empty when cmd is function type.
2026-05-06 06:36:39 -04:00
zeertzjq
d9a7b68795 vim-patch:9.2.0447: cindent does not ignore comments (#39622)
Problem:  When find_start_brace() scans backwards for the enclosing
          block, '{' and '}' inside // and /* */ comments are counted,
          producing wrong indent for code following such comments
          (rendcrx).
Solution: Implement FM_SKIPCOMM in findmatchlimit() to track block-
          comment state and skip matches inside comments. Pass
          FM_SKIPCOMM from cindent's call sites
          (find_start_brace, find_match_char, cin_iswhileofdo,
          get_c_indent).

fixes:  vim/vim#4
fixes:  vim/vim#648
fixes:  vim/vim#19578
closes: vim/vim#19581
closes: vim/vim#20111

c06002f3cb

Co-authored-by: magnus-rattlehead <magnus-rattlehead@users.noreply.github.com>
2026-05-06 01:45:18 +00:00
zeertzjq
60d069d422 vim-patch:9.2.0445: win_fix_scroll() called before win_comp_pos() in command_height() (#39619)
Problem:  win_fix_scroll(true) is called before win_comp_pos() in
          command_height().
Solution: Move win_fix_scroll(true) after win_comp_pos(), matching the
          ordering used in win_drag_status_line() (Jesse Rosenstock).

Patch 9.2.0413 added win_fix_scroll(true) to command_height() to handle
splitkeep when cmdheight changes, but placed the call before win_comp_pos().
win_fix_scroll() reads w_winrow to detect window movement
(620557bd48/src/window.c (L7266)),
but w_winrow is not recomputed until win_comp_pos() runs
(620557bd48/src/window.c (L6516)).
This causes incorrect scroll adjustments and was breaking
Test_smoothscroll_incsearch on macOS CI.

closes: vim/vim#20138

40fc78f0a1


Co-authored-by: Gemini

Co-authored-by: Jesse Rosenstock <jmr@google.com>
2026-05-06 09:23:09 +08:00
zeertzjq
2bb426ce4a vim-patch:9.2.0443: GUI: cancelling save dialog overwrites or discards unnamed buffer (#39617)
Problem:  When closing gvim with an unsaved unnamed buffer, choosing
          "Yes" in the "Save changes?" dialog and then "Cancel" in the
          file selection dialog either silently writes the buffer to a
          file named "Untitled" (overwriting any existing file with
          that name) or discards the buffer altogether
          (vibs29, after v9.1.0265).
Solution: In dialog_changed(), if browse_save_fname() leaves the buffer
          without a file name, treat it as a cancel and return without
          saving.  Also stop clearing the modified flag in the restore
          path on write failure, so the unsaved changes are kept and
          the caller (e.g. gui_shell_closed()) can also cancel the
          close.  Pre-fill the file dialog with "Untitled" to match
          the preceding "Save changes to ..." prompt.  Add a test for
          the write-failure path (Hirohito Higashi).

fixes:  vim/vim#20132
closes: vim/vim#20143

cf947e7ef0

Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
2026-05-06 08:19:30 +08:00
zeertzjq
d1c3d6fbaa vim-patch:9.2.0444: Cannot set 'path' option via modeline
Problem:  Cannot set 'path' option via modeline (zeertzjq, after v9.2.0435)
Solution: Revert the part that disallows setting 'path' via modeline.

closes: vim/vim#20137

88fb739918

Co-authored-by: Christian Brabandt <cb@256bit.org>
2026-05-06 07:25:00 +08:00
zeertzjq
b06f8b174f vim-patch:9.2.0435: [security]: backticks in 'path' may cause shell execution on completion
Problem:  [security]: Backticks enclosed shell commands in the 'path'
          option value are executed during completion (q1uf3ng).
Solution: Skip path entries containing backticks, add P_SECURE to 'path'
          option, so that it cannot be set from a modeline (for symmetry with
          the 'cdpath' option)

Github Advisory:
https://github.com/vim/vim/security/advisories/GHSA-hwg5-3cxw-wvvg

Supported by AI.

190cb3c2b9

Co-authored-by: Christian Brabandt <cb@256bit.org>
2026-05-06 07:23:07 +08:00
zeertzjq
d0582fcc74 vim-patch:9.2.0442: completion: i_CTRL-X_CTRL-V doesn't use dict from customlist (#39614)
Problem:  Completion with i_CTRL-X_CTRL-V doesn't use dict from cmdline
          "customlist" completion.
Solution: Include abbr/kind/menu/info in the completion items
          (zeertzjq).

closes: vim/vim#20139

2bfddbea47
2026-05-05 23:17:21 +00:00
Daigo Yamashita
97ef9f74b2 fix(events): trigger WinScrolled during 'incsearch' #39308
Problem:
With 'incsearch' enabled, the window can scroll while typing a
search pattern, but WinScrolled is not triggered until the next user
action in Normal mode. The event is effectively skipped for every
scroll that happens while the search prompt is still open.

Solution:
Call may_trigger_win_scrolled_resized() after update_screen()
in may_do_incsearch_highlighting() and finish_incsearch_highlighting().
2026-05-05 14:34:53 -04:00
zeertzjq
43669d5e07 vim-patch:bb807eb: runtime(doc): Tweak documentation style (#39597)
closes: vim/vim#20134

bb807ebc8a

Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
2026-05-05 07:59:43 +08:00
zeertzjq
37596fcd29 vim-patch:cb0b4cf: Fix a few more typos (#39596)
closes: vim/vim#20135

cb0b4cf45c

Co-authored-by: Felipe Matarazzo <felipemps@protonmail.com>
2026-05-04 23:18:52 +00:00
tao
7e813c65f7 fix(path): exepath() should respect 'shellslash' #39541
Problem:
`gx` relies on `exepath` to get the fullpath of `cmd.exe`,
and that path must use `\`; otherwise, luv's spawn will fail.

Solution:
Revert `slash_adjust` in `exepath`, so that it still respects 'shellslash'
2026-05-04 12:18:13 -04:00
zeertzjq
7fff439395 vim-patch:9.2.0433: customlist completion cannot supply pum metadata (#39584)
Problem:  customlist completion cannot supply pum metadata
Solution: Allow each item returned by a customlist function to be
          either a string or a Dict with keys "word", "abbr", "kind",
          "menu" and "info" (Yasuhiro Matsumoto).

closes: vim/vim#20100

5c700152ae

Co-authored-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
2026-05-04 11:47:54 +08:00
zeertzjq
cdccd452ff refactor(cmdexpand.c): deduplicate code (#39582) 2026-05-04 01:32:03 +00:00
zeertzjq
0e69a38026 vim-patch:9.2.0436: Buffer overflow when parsing overlong errorformat lines (#39578)
Problem:  When an error line in a file passed to :cfile / :cgetfile is
          longer than IOSIZE, qf_parse_file_pfx() copies the tail
          into the fixed-size IObuff with STRMOVE(), overflowing the heap buffer.
          The same code path can also loop indefinitely because
          qf_parse_file_pfx() always returns QF_MULTISCAN when a
          tail is present, and qf_init_ext() unconditionally goes
          to "restofline" without bounding the tail length (Nabih).
Solution: Remove the STRMOVE() into IObuff.  In the QF_MULTISCAN
          branch, alias linebuf into the tail directly and update
          linelen, requiring strict progress (new length less than
          the previous length) before retrying; otherwise ignore
          the line.

closes: vim/vim#20126

Supported by AI

77677c33de

Co-authored-by: Christian Brabandt <cb@256bit.org>
2026-05-04 07:20:16 +08:00
Justin M. Keyes
d788dd2811 refactor(excmd): pass fargs to Lua for builtin cmds #39528
Problem:
The fallback that tokenizes `eap->arg` by unescaped whitespace (when the
parser doesn't pre-split via `EX_EXPAND` etc.) lives in `nlua_do_ucmd`,
so only user-command callbacks got `eap.fargs`. Builtin commands routed
through `nlua_call_excmd` have to re-parse the args themselves
(e.g. `M.ex_lsp`).

Solution:
- Move the tokenization into `nlua_push_eap` so every Lua handler sees
  `eap.fargs`. Keep only the `EX_NOSPC` override in `nlua_do_ucmd` (the
  `nargs=1`/`?` case which is genuinely user-command-specific).
- Drop the re-parse in `M.ex_lsp`.
2026-05-02 10:46:23 -04:00
zeertzjq
ec671a2d51 vim-patch:9.2.0425: Cannot silence undo/redo messages (#39554)
Problem:  Cannot silence undo/redo messages
Solution: Add "u" flag to 'shortmess' option
          (Shougo Matsushita).

fixes:  vim/vim#20049
closes: vim/vim#20107

d25f8d1b2c

Co-authored-by: Shougo Matsushita <Shougo.Matsu@gmail.com>
2026-05-02 12:55:14 +08:00
zeertzjq
329dc30ef0 vim-patch:partial:9.2.0423: popup: wrapped cmdline truncated with wildoptions=pum (#39553)
Problem:  popup: wrapped cmdline truncated with wildoptions=pum
Solution: Call msg_starthere() in redrawcmd() to reset lines_left
          before each redraw (Yasuhiro Matsumoto).

redrawcmd() leaves lines_left at its previous value, which decrements
across successive redraws (e.g. when wildtrigger() refreshes the popup
on every keystroke) until 0, after which msg_no_more aborts drawing
the wrapped cmdline. Call msg_starthere() to reset it.

related: vim/vim#20081

587447ec64

The problem mentioned in the PR cannot be reproduced in Nvim. It's not
clear if this change will solve or cause any problems in Nvim, so let's
first try it without adding the test.

Co-authored-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
2026-05-02 11:38:31 +08:00
glepnir
941f2f9522 vim-patch:9.2.0418: wildcards in expanded env vars reinterpreted by glob (#39517)
Problem:  With $d='[dir]', `:e $d/file.txt` opens the wrong file,
          `:e $d/<Tab>` fails to complete, and `glob('$d/*')` returns
          nothing. Wildcard characters inside expanded environment
          variables get picked up by globbing again.
Solution: Turn the 4th parameter of expand_env_esc() from a bool into a
          string of characters to escape in each expanded value. Callers
          that pass the result to wildcard expansion should include
          PATH_ESC_WILDCARDS in addition to " \t" (glepnir).

closes: vim/vim#20053

20e98ff1cc
2026-05-02 10:51:44 +08:00
altermo
a6ea3a1055 fix: vim._with may silence all cmdline-errors #34301
Problem:
vim._with may silence all cmdline-errors if emsg_silent=true, silent=false.

Steps to reproduce:
`nvim --clean -u repro.lua`, then `:echoerr 123`, nothing is shown.

    local api, fn = vim.api, vim.fn
    -- api.nvim_create_autocmd("CursorMovedC", {
    api.nvim_create_autocmd("CmdlineChanged", {
      callback = function(args)
        if args.match ~= ":" then
          return
        end
        -- vim.cmd([[silent! ]])
        vim._with({ emsg_silent = true }, function()
          -- return api.nvim_parse_cmd(fn.getcmdline(), {})
        end)
      end,
    })

Solution:
Force CMOD_SILENT if CMOD_ERRSILENT.
2026-05-01 10:33:45 -04:00
Riccardo Mazzarini
ad2cf23435 fix(style): drop clang-format #39514
Problem: C formatting is enforced in CI via uncrustify, but when working
on C code clangd formats on save via clang-format, forcing users to
manually run `make formatc` after they're done.

Solution: disable clang-format.
2026-05-01 10:01:40 -04:00
Justin M. Keyes
7c4845ff46 fix(ui): z=, tselect with async vim.ui.select
Problem:
After 55ceb31,  z= and tselect don't work if `vim.ui.select` is an async
provider (especially terminal buffers).

Solution:
Drop the `vim.wait()` approach, use an async approach.

fix #39506
2026-04-30 19:19:42 +02:00
Justin M. Keyes
18d7dd485b feat(ui): use vim.ui.select for :oldfiles, :recover
Problem:
followup to 55ceb314ca #39478
`:oldfiles` and swapfile `:recover` do not delegate to `vim.ui.select`.

Solution:
- Delegate to `vim.ui.select`.
- Fix a long-standing `recover_names` bug where `concat_fnames(dir_name,
  files[i], true)` produced malformed `<dir>//<dir>/<file>` paths (also
  fixes `swapfilelist()`).
2026-04-30 17:44:31 +02:00
Justin M. Keyes
6a87ef75b3 fix(env): force uppercase environ() keys on Windows #39523 2026-04-30 11:43:04 -04:00
zeertzjq
668ccd97b6 vim-patch:9.2.0416: Unix: filename completion splits at space for single-file Ex commands (#39520)
Problem:  SPACE_IN_FILENAME is defined on most platforms but not on Unix.
	  As a result, set_context_for_wildcard_arg() on Unix always resets the
	  completion pattern at white space for Ex commands that take a
          single file argument.
Solution: Drop the SPACE_IN_FILENAME ifdef (Maxim Kim)

fixes:  vim/vim#18411
closes: vim/vim#20090

c2bda0add9

Co-authored-by: Maxim Kim <habamax@gmail.com>
2026-04-30 13:11:49 +00:00
Justin M. Keyes
d9ed4c8566 refactor(tty): tty.request() #39489
Problem:
- Various `TermRequest` handlers which all do similar things.
- `tty.query` is specific to `XTGETTCAP DCS`, can't be reused for other kinds of terminal queries.

Solution:
Provide `tty.request()`.
2026-04-30 07:26:40 -04:00
zeertzjq
071f9748c0 vim-patch:9.2.0415: Wrong behavior when executing register that ends in Insert mode (#39518)
Problem:  Wrong behavior when executing register that ends in Insert
          mode from Ctrl-O (Emilien Breton)
Solution: Use :startinsert etc. to restore Insert mode after executing
          the register contents (zeertzjq).

fixes:  vim/vim#20085
closes: vim/vim#20091

6453a7c440
2026-04-30 11:14:28 +00:00
glepnir
c79d5f5028 vim-patch:9.2.0417: completion: no support for "noinsert" with 'wildmode' (#39516)
Problem:  completion: no support for "noinsert" with 'wildmode' and
          commandline completion
Solution: Add "noinsert" value to the 'wildmode' option, mirroring
          'completeopt' "noinsert" behaviour (glepnir).

fixes:  vim/vim#16551
closes: vim/vim#20080

af494af5ff
2026-04-30 11:13:47 +00:00
Justin M. Keyes
1e06e95662 docs: misc #39511 2026-04-29 17:37:47 -04:00
tao
040bdf0bc5 refactor(path): more slash normalization #39426
Problem:
1. `vim_getenv` is followed by `TO_SLASH` when getting
path-related variables.
2. cmd exits when launched with forward slash.

Solution:
1. try calling `TO_SLASH` in `vim_getenv`.
2. pass fullpath via `lpApplicationName`, only include `cmd.exe`
in cmdline.

Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2026-04-29 16:33:22 -04:00
zeertzjq
0697c24601 vim-patch:9.2.0413: Scrolling wrong with 'splitkeep' when changing 'cmdheight' (#39493)
Problem:  Cursor is not adjusted when 'cmdheight' is changed to cover
          the cursor with 'splitkeep' ~= "cursor".
Solution: Handle window resize for 'splitkeep' after changing 'cmdheight'.
          Ensure previous window height is set when changing 'splitkeep'
          (Luuk van Baal).

closes: vim/vim#20043

bd0f3e6da5

Co-authored-by: Luuk van Baal <luukvbaal@gmail.com>
2026-04-29 13:42:02 +08:00
zeertzjq
f04dc2fcfc vim-patch:9.2.0408: Insert-mode <Cmd> edits can corrupt undo (#39492)
Problem:  A <Cmd> command in Insert mode can edit the current buffer,
          e.g., with setline(). That edit appends to the current undo
          block, but Insert mode does not know that the cursor line may
          need to be saved again before the next typed edit. If the next
          typed edit is a <BS> at the start of a line, it can join away
          the line that was changed by the <Cmd> command before Insert
          mode saves that updated line. The newest undo entry can then
          still refer to the joined-away line, so undo sees a range past
          the end of the buffer and fails with E438.
Solution: If a <Cmd> command in Insert mode changes the buffer, set
          ins_need_undo so stop_arrow() refreshes Insstart. This lets
          the next edit properly decide whether a new undo entry is
          needed (Jaehwang Jung)

closes: vim/vim#20087
AI-assisted: Codex

e47daed442

Co-authored-by: Jaehwang Jung <tomtomjhj@gmail.com>
2026-04-29 13:09:55 +08:00
zeertzjq
c33e60f748 revert: "vim-patch:9.2.0405: when jumping to tags, will open URLs (#39461)" (#39487)
This reverts commit 72bc6c5801.

Fix #39480
2026-04-28 23:18:02 +00:00
Justin M. Keyes
55ceb314ca feat(ui): use vim.ui.select for :tselect, z= #39478
Problem:
`:tselect` and `z=` (spell suggest) have their own bespoke select menus.

Solution:
- Delegate to `vim.ui.select` instead.
- Bonus:
  - `:tselect` gains mouse support. `print_tag_list` didn't suport mouseclick.

This causes some minor regressions, which are not blockers:

- `z=` no longer draws the list right-left if 'rightleft' is set.
  - TODO: can/should `vim.ui.select` / `vim.fn.inputlist()` handle that?
- `:tselect`
  - No "column" headings (`# pri kind tag file`).
  - No highlighting: (HLF_T: tag name, HLF_D: file, HLF_CM: extra fields).
  - TODO: can `vim.ui.select()` support highlighted chunks (`[[text, hl_id], ...]`) ?

fix https://github.com/neovim/neovim/issues/25814
fix https://github.com/neovim/neovim/issues/31987
2026-04-28 18:29:17 -04:00
luukvbaal
62db5bebdd fix(messages): message kind for :recover and swapfile attention #39444
Problem:  No message kind and multiple events for :recover and
          (non-prompt) swapfile attention messages.
Solution: Assign these the "list_cmd" and "wmsg" kind.
2026-04-28 10:05:06 -04:00
zeertzjq
72bc6c5801 vim-patch:9.2.0405: when jumping to tags, will open URLs (#39461)
Problem:  when jumping to tags, will open URLs
          (Srinivas Piskala Ganesh Babu)
Solution: Disallow trying to open remote files.

closes: vim/vim#20068

Supported by AI

ae196b2d58

Co-authored-by: Christian Brabandt <cb@256bit.org>
2026-04-28 08:07:57 +08:00
Barrett Ruth
0a7201095b vim-patch:9.2.0400: sandbox callbacks selected through 'complete' (#39452)
Problem:  Modeline-tainted 'complete' values can invoke completion
          callbacks outside the sandbox.
Solution: Enter the sandbox for both 'complete' callback phases and add
          a regression test (Barrett Ruth)

closes: vim/vim#20078

dd9b31fb62
2026-04-27 23:09:33 +00:00
Till Bungert
a0820481f2 fix(excmd): use realtime for v:starttime, :uptime #39425
Problem:
`v:starttime`, `:uptime` use a monotonic high-resolution timer. This
only works as long as the timer keeps running (if the computer is
suspended the timer is paused). This is somewhat unintuitive, and
doesn't match the behavior of the `uptime` shell command.

Solution:
Implement `os_realtime` to get the real time since the
epoch in nanoseconds.
2026-04-27 19:01:47 -04:00
zeertzjq
46c83ce321 fix(marks): don't use spell decorations from other lines (#39441)
Spell decorations from other lines aren't relevant to the current line.
Also, decor_redraw_col() can only go forward, while spell navigation
needs to go both forward and backward.
2026-04-28 07:00:23 +08:00
Lewis Russell
c822a2657c refactor(lua): move vim.wait into runtime Lua
Move vim.wait into runtime/lua/vim/_core/editor.lua and replace
the C entrypoint with narrow vim._core helpers for polling, UI
flushing, and interrupt checks.

Keep the existing interval semantics by retaining the dummy timer that
wakes the loop while it is otherwise idle.

Update the docs to describe the success return values correctly, and
adjust the test expectation for the new vim.validate() callback error.

AI-assisted: Codex
2026-04-27 11:33:47 +01:00