Nvim uses utf8proc or an older process involving "src/unicode/"
and "download-unicode-files.sh" to decouple unicode characters
from "mbyte.c".
These unicode patches should be auto N/A but the diff hunk xfuncname
is wrong for utf_char2cells().
Is it because of the `#ifdef`?
Need a volunteer to inspect if these patches still have relevant
changes
Nvim
```c
/// same as utf_composinglike but operating on UCS-4 values
bool utf_iscomposing(int c1, int c2, GraphemeState *state)
{
return (!utf8proc_grapheme_break_stateful(c1, c2, state)
|| arabic_combine(c1, c2));
}
```
Vim
```c
/*
* Return TRUE if "c" is a composing UTF-8 character. This means it will be
* drawn on top of the preceding character.
* Based on code from Markus Kuhn.
*/
int
utf_iscomposing(int c)
{
// Sorted list of non-overlapping intervals.
// Generated by ../runtime/tools/unicode.vim.
static struct interval combining[] =
{
{0x0300, 0x036f},
{0x0483, 0x0489},
{0x0591, 0x05bd},
// ...
{0x0300, 0x036f},
{0x0483, 0x0489},
{0x0591, 0x05bd},
};
return intable(combining, sizeof(combining), c);
}
```
Problem: A completion asked for with CTRL-X CTRL-O while
'autocompletedelay' is running is given the look of an
automatic one, the implicit "noselect" among it.
Solution: Turn autocompletion off where a typed key takes the completion
over. A completion already on screen goes on being what it
was (Hirohito Higashi).
closes: vim/vim#21158c8e432b266
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Problem: A SwapExists autocmd can re-open the buffer being edited,
causing ml_close() to free the memfile that
ml_open_file() still holds a local pointer to, causing
use-after-free.
Solution: After findswapname() returns, verify that buf->b_ml.ml_mfp
is still the same as the copy mfp we hold.
closes: vim/vim#211717aecb2cca8
Co-authored-by: Christian Brabandt <cb@256bit.org>
Problem:
The Vim "stuff" concept breaks the ability to reason about the call
stack and thus the boundaries of a `CmdAtom`: a stuffed translation ("x"
=> "dl") defers to the main loop. This "continuation" must be modeled in
`CmdAtom`, by checking global flags at undefined times, during undefined
circumstances.
Solution:
- After a stuffed "translation", eagerly execute the stuff buffer
(`exec_stuffed()`).
- Delete the CmdAtom "continuation" junk.
Note:
- op_colon runs its cmdline "nested", but that's fine because operators
already nest interactive sessions there (op_change runs edit()), and
the cmdline is frameless so the operator's frame can own/capture it.
Problem:
If an autocommand handler focuses the tab page we're closing during a
`:tabonly` (with some conditions), we hit an assert failure in
`win_close_othertab()`.
For this to occur, we need:
- `nvim_buf_delete()` to trigger `close_windows()` (as is done in
`cmdwin.lua`'s `_cleanup()`)
- `close_windows()` then calls `win_close_othertab()`, removing the
window (`win_free_mem()`)
- then in the caller, `tabpage_close_other()`, the loop continues (we
don't detect `tp_lastwin == wp` since we've unlinked the window)
- the loop assumes that `curtab != tp`
but we've refocused `curtab` so the `ex_win_close()` call passes `tp` as
`curtab`, causing the assert to fail
Solution:
Detect the focus of `curtab` and abort closing the tab.
Problem:
gen_help_html.lua only outputs HTML, but Typst is useful for producing PDFs.
Solution:
Add gen_one_typ() and ts_node_to_typ(), which mirror the existing
gen_one_html() and ts_node_to_html().
Problem:
Undo places the cursor wherever the cursor happened to sit at "save
time" (`uh_cursor` is sampled lazily on the first change).
Examples:
- `i` preserves, but `a` does not
- `diw`, `atest<Esc>`, `d^` abandon the original position
- `D`, `o` restore it (by accident).
Solution:
`composite` tracks the pending atom (and its `origin`) across frames.
A `stuffed` continuation frame inherits the `origin` + prepped redo.
Store `origin` info in the undo header, so undo can restore it.
- Not for a mid-command undo break (i_CTRL-G_u).
- Undoing a mapping restores where the mapping started (which
technically may be different than where the "edit" started).
Problem: `restore_size` is scoped to all of `makeopens()`, so a window
excluded by 'sessionoptions' latches it off for every tabpage written
afterwards: with `sessionoptions-=terminal`, a terminal in tab 2 makes
tab 3 restore with `wincmd =` instead of its stored sizes.
Solution: Recompute it per tabpage.
Problem:
An insert-session entered by a scheduled `feedkeys('i','n')` is
classified on entry (as "not typed"), and not reevaluated after that,
thus user input following it is not captured.
Repro: an `:imap` that does `feedkeys('<esc>','n')` and schedules
re-entering insert, emits one CmdAtom for the first press, then nothing
else.
Solution:
Sample `maptick` (ticked by `gotchars()` on typed input, including
mappings) at session start; if it advanced by session end, the session
is user input.
I got annoyed about so many repeated `win_float_pos` events
for the popupmenu. This fixes some of them but not all of them.
vibe-less explanation: `need_highlight_changed = true` is very expensive
should not be needed when using a window-local highlight namespace. This
was only necessary when overriding the global highlight namespace. This
can instead be handled by using the correct `hl_attr_active` instead of
`highlight_attr`.
Also `pum_grid.pending_comp_index_update` can be cleared when using
win_float_pos prior to redraw.
I wanted to add a test for no repeated win_float_pos event in the same
redraw:flush cycle but that requires deeper cleanups, like
getting rid of crazy redraw panic intermingled deep into insexpand.c
(if "state" is correct, a single update_screen() after the weird
multilayer recursive dance should be enough.)
Problem:
`nlua_pcall()` references `_G.debug.traceback`. If user code deletes it
or breaks it some other way, various Lua features are broken.
_G.debug = nil
vim.schedule(function() end)
vim.wait(100)
E5113: Lua chunk: attempt to index a nil value
stack traceback:
[C]: in function 'loop_poll'
[string "vim/_core/editor"]:176: in function 'wait'
crash.lua:3: in main chunk
PANIC: unprotected error in call to Lua API (attempt to index a nil value)
Solution:
Check `_G.debug.traceback` before using it as errfunc. If it's broken,
omit the traceback and say so in the error message.
Note: We could cache `_G.debug` in LUA_REGISTRYINDEX on startup, but
that would prevent plugins from providing custom functionality there
(and we happen to do so in `tui_spec.lua` for example).
libvterm reads the first three sub-parameters of an SGR 38:2 or 48:2 sequence
as R:G:B, so a colour space id shifts the channels: the empty slot becomes red
via CSI_ARG_MISSING truncating to 255, and green and blue move over one.
Skip the colour space id when the colon-separated group holds more than three
arguments. The group length comes from CSI_ARG_HAS_MORE rather than the raw
argument count, so a following semicolon-separated parameter is not consumed.
vim-patch:8.1.2195: Vim does not exit when the terminal window is last window
vim-patch:8.1.2219: no autocommand for open window with terminal
vim-patch:8.2.1160: Vim9: memory leak in allocated types
vim-patch:8.2.2331: Vim9: wrong error when modifying dict declared with :final
vim-patch:8.2.4153: MS-Windows: Global IME is no longer supported
vim-patch:8.2.4586: Vim9: no error for using lower case name for "func" argument
vim-patch:9.0.0627: "const" and "final" both make the type a constant
vim-patch:9.0.1605: crash when calling method on super in child constructor
vim-patch:9.0.1760: vim9 class problem with new() constructor
vim-patch:9.1.0050: Win32 Keyboard handling is sub-optimal
vim-patch:9.1.0270: a few minor issues to fix
vim-patch:fb745756d runtime(doc): add MsgArea to 'highlight' option description
vim-patch:f0837ba0b runtime(doc): In builtin overview use {buf} as param for appendbufline/setbufline
vim-patch:6081c1789 runtime(doc): update help-toc description
vim-patch:2afdb3a65 runtime(doc): Fix minor typo in options.txt
vim-patch:ba0062b0c runtime(helptoc): the helptoc package can be improved
vim-patch:9340aa1bf runtime(helptoc): add s keymap to split and jump to selected entry
vim-patch:b2e21cccc runtime(doc): Tweak documentation in vi_diff.txt
vim-patch:3913f13a7 runtime(doc): Improve :help builtin-function-list table formatting
vim-patch:b8f58dd69 runtime(doc): Fix typos in version9.txt
vim-patch:9.2.0973: Vim9: internal error when a class member is initialized with a closure
vim-patch:9.2.0974: tests: Test_clientserver_serverlist_list() is flaky
vim-patch:9.2.0975: Vim9: assignment to a member of an object member fails
vim-patch:9.2.0977: tests: test_terminal_visual_empty_listchars() is flaky
vim-patch:9.2.0988: tests: Test_terminal_csi_resize_oob() returns early
vim-patch:9.2.0989: libvterm: hang when rendering REP with no preceding char
vim-patch:9.2.0990: libvterm: crash when a scroll region outlives a resize
vim-patch:9.2.0992: popup filter gets the key at the hit-enter prompt
vim-patch:9.2.0994: Vim9: No error for :open during compilation
vim-patch:b618f7ea1 CI: Bump github/codeql-action
vim-patch:b7e0c1cb3 runtime(doc): correct typo in bug report in version5.txt
vim-patch:632abba51 runtime(doc): fix typos and grammar in CONTRIBUTING.md
vim-patch:9.2.0999: serverlist() fails when there is no connection to the server
vim-patch:9.2.1000: Vim9: listener_add() fails when given only a callback
vim-patch:9.2.1003: popup: border is not shown when the popup does not fit
vim-patch:3e46ee723 patch 9.2.1010: compile error when folding feature is disabled
Problem: ins_compl_dict_alloc() builds the same dict as
fill_complete_info_dict().
Solution: Call fill_complete_info_dict() instead (glepnir).
closes: vim/vim#21140303a153694
Problem: A function used through 'omnifunc' or 'complete' is called the
same way whether 'autocomplete' started the completion or a
key asked for one, so it cannot answer differently.
Solution: Report which of the two it is in complete_info() as "auto". It
is returned only when asked for in {what}, so what
complete_info() says by itself does not change
(Hirohito Higashi).
closes: vim/vim#211431f56c351de
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Problem: backupcopy=auto overwrites a file in place when umask is restrictive.
The probe treats permission restore as impossible and writes in
place, keeping the same inode.
Solution: When creating the probe file, open() applies umask, so a 0644
file becomes 0600 with umask 0077. Use fchmod() to fix the
permissions of the probe (Pranav Dwivedi).
closes: vim/vim#21137fd8aea135d
Co-authored-by: Pranav Dwivedi <dwivedipranav2021@gmail.com>
Problem: With 'completeopt' "fuzzy", a re-sort after complete() leaves the
last match unsorted at the end of the list.
Solution: Find the original text by its flag instead of assuming
compl_shows_dir points at it.
closes: vim/vim#211037e74722999
Problem:
The runs ":helptags", which needs the tree-sitter-vimdoc parser.
This may cause problems for package maintainers / distros?
Solution:
Use running to generate the tags, like the zig build already does.
It also errors on duplicate tags, which is good.
The `:helptags` command still uses treesitter.
Problem:
Parent commit regressed some behavior of the old C helptags-gen impl:
- helpfiles in sub-directories are named by basename, so :help fails
- "help-tags" always names "tags", never "tags-nl"
- E150 E151 E152 E153 are never reported
- existing tags file is not overwritten if no tags were found
- a duplicate tag aborts the run, skipping the remaining directories
- `*.TXT` and `*.FRX` (uppercase) are not recognized as helpfiles
- tree-sitter-vimdoc accepts tags that the C parser rejected: `*a|b*`
(breaks |links|) and unterminated `*tag`
- PUC Lua "<" compares with (localized) `strcoll()`, so the tags file is
not sorted by byte value (E432)
- requiring `vim.treesitter` at load time breaks :help itself, not just
:helptags, where the module is unavailable
- `vim.pack` runs :helptags for plugins that have no "doc/" directory,
so every install/update emits E150
Solution:
- Fail the build if generating helptags reports any `v:errmsg`.
- Restore old behavior: tags generated for runtime/doc are now identical
to those from the C implementation. Errors are non-fatal messages
instead of exceptions, so all directories are still processed.
- Load treesitter lazily, report a plain error if parser is missing.
Problem:
Tags are manually parsed in C which is not flexible and prone to errors.
Extending the help system to allow for other formats (e.g. Markdown)
would require a large rewrite in the C core, while with Treesitter it
only needs a query update.
Solution:
Use the power of treesitter to extract the tags from helpfiles.
- build: set `$VIMRUNTIME` when generating helptags, like
`cmake/Util.cmake` already does for other generators.
- fix(help): only accept tags delimited by whitespace. The old C parser
only accepted a `*tag*` preceded by start-of-line or whitespace and
followed by whitespace or end-of-line. The vimdoc parser also captures
tags followed by other text, e.g. `*$XDG_STATE_HOME*/.../logs` in
starting.txt, which caused an E154 duplicate tag error for docs that
were previously fine.
Problem:
In order for ui2 to graduate to the main "messages ui" its configuration
needs to graduate into actual options.
Solution:
Migrate some of its config to 'messagesopt':
- "maxheight" (note: currently this is an integer treated as
a "percentage"; if we want to support a row count we could allow
values with units, like `"42%"`)
- "pager"
- "timeout"
Also improves error messages:
messagesopt=hit-enter,history:500,bogus E474: Unknown item 'bogus'
messagesopt=hit-enter,history:500,progress:x E474: 'progress' must be one of: , c
messagesopt=hit-enter,history:abc E474: 'history' requires a number
Problem:
`vim.on_key()` callbacks are invoked for keys that `getchar()` consumes,
which never reach the main loop, and there is no way to tell such a key
apart. With ui2 the `on_key` handler activated after interactive
cmdline, handles it as `pager_char` (thus enters the ui2 pager).
Solution:
Skip `vim.on_key()` callbacks during `getchar()`/`getcharstr()`.
Problem: complete_info() omits "abbr_hlgroup" and "kind_hlgroup".
Solution: Keep the highlight group ID with the match instead of the
resolved attribute and add both entries to the returned items
(glepnir).
closes: vim/vim#211051c32cede0a
Problem: In the debugger ">up" and ">frame" select an older function call
frame, but get_funccal_local_ht() and the related functions check
current_funccal while returning a dictionary of the frame that
get_funccal() selected. A :def function keeps its local variables
on the vim9 stack, its funccall_T has no l: and a: dictionaries and
is allocated cleared, so with such a frame selected the returned
hashtab has a NULL ht_array and evaluating any variable name at the
debug prompt crashes in hash_lookup().
Solution: Check the funccal that is actually used and return NULL when it has
no l: variables, so that the variable is reported as undefined
instead.
closes: vim/vim#211115ad47b07af
Co-authored-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1) The complete example plugin at :h write-plugin the end of the
documentation didn't reflect the snippets provided during the
tutorial. In most of the Add() function, interpolated strings are
used, but the final result used concatenated strings.
2) The example provided in readdir() to get a list of files ending in
".txt" didn't properly escape the dot in the regular expression:
readdir(dirname, {n -> n =~ '.txt$'})
This would match any file ending with "txt" that is at least 4
characters long, instead it should be:
readdir(dirname, {n -> n =~ '\.txt$'})
closes: vim/vim#2112363d08d4386
Co-authored-by: Josep Puigdemont <josep.puigdemont@gmail.com>
Problem:
When ui2 is enabled, opening an already-open file in another Neovim
instance results in the error `E812: Autocommands changed buffer…`.
Analysis:
On E812 the file is not loaded. The default SwapExists handler notifies
`W325: Ignoring swapfile…`, and ui2 shows that message by opening
a window, which is a temp context switch. `ctx_dirs_restore()`
re-shortens every buffer name on the way out, and `shorten_buf_fname()`
always frees and reallocates `b_sfname`. `readfile()` aliases `b_fname`
across `check_need_swap()` and compares the pointer to detect a rename.
Regression by b296666e41, which replaced the `cs_save_sfname` restore
(that kept curbuf's pointer) with `shorten_fnames(true)`.
Solution:
Keep the allocation in `shorten_buf_fname()` when the short name is
unchanged. Pointer stability is what the E200/E201/E812 guards actually
assert.
Problem:
A mapping that enters terminal-mode (`:FzfLua files` via `:startinsert`)
never reaches a composite-end: terminal-mode runs no "normal" CmdFrames.
The composite collects the entire terminal session (and more) into `lhs`.
E.g. if I have `<M-/>` mapped to open `:FzfLua files`, then interact
with fzf-lua UI, the emitted CmdAtom looks like:
<M-/>… => { type='mapping', lhs='<M-/><C-N><C-N><CR>', keys=nil }
Solution:
End the composite when terminal-mode is entered, which emits a more
meaningful and repeatable atom:
<M-/>… => { type='mapping', lhs='<M-/>', keys=nil }
Problem:
The "!" operator stuffs its cmdline continuation (`:.,.+1!`), so its
frame ends before capture (stuff pending) and the redo-prep disappears
with it.
!ipsort<CR> => { type='excmd', lhs=':.,.+1!sort<NL>', keys=':.,.+1!sort<NL>' }
Compare to builtin "." which works bc `do_bang()` completes the redo
(`!ip` + `sort<NL>`).
Solution:
Appoint the stuffed continuation frame as the "redo-prep" frame.
!ipsort<CR> => { type='operator', operator='!', lhs='!ipsort<NL>', keys='!ipsort<NL>' }
Notes:
- atom_cmd_end(): a frame ending with stuff pending re-points its
redo-prep to the next frame.
- atom_cmd_start(): a stuffed continuation frame (`KeyStuffed`) keeps
the redo-prep; flushed stuff discards it.
Problem:
1. `ctx_dirs_restore()` is the only chdir site that doesn't re-shorten
buffer names; `post_chdir()`, `update_cwd()` and `do_autochdir()` all
call `shorten_fnames(true)`. So after a temp window-context switch
that moved the CWD, every buffer's `b_fname` is still relative to the
other directory. ui2 renders messages in a float, and entering it is
such a switch, so with a `:bcd` in a `BufReadPost` handler 'statusline'
"%f" shows ".config/nvim/init.lua" while the CWD is already
`~/.config/nvim`, and :write resolves the name against it:
```
E212: Can't open file for writing: no such file or directory
```
2. `msg_multihl()` leaves `msg_ext_id` pointing at the caller's storage
when nothing was emitted (e.g. 'msg_silent'): the reset only ran on
a flush that produced chunks. The next message then ships a dead
stack frame as its msg_show id. After ":silent write" the id is
buf_write()'s `msg_id[MAXPATHL + 32]`:
```
id = "\0\0\0\0\0\0\0\0\29\0(<C6>k\24R\17p<C7><C7><C7>\1\0\0\0..."
```
Solution:
1. `shorten_fnames(true)` after restoring the CWD. Drop `cs_save_sfname`,
which was a partial workaround for the same bug.
2. Release the id in `msg_multihl()`, where it is set and the caller's
frame is still alive. Stop reading `.data.integer` out of a String
union member.
Problem:
With 'linebreak', a word is moved to the next screen line when it does
not fit on the current one. The check measures only the buffer text, so
inline virtual text anchored inside the word is not counted. The word is
kept on a line it cannot fit, and the virtual text is split across the
screen line boundary.
Solution:
Count the width of inline virtual text anchored within the word, so the
check uses the width that is actually displayed.
Problem:
`buf_write()` captures the buffer's `fname`/`sfname`/`ffname`, then emits its
progress-message before opening the file. This may run user code
synchronously: the `Progress` autocmd, and the `msg_show` handler of an
in-process UI (ui2). Either can change the CWD, and `shorten_fnames()`
then frees/reallocs every buffer's short name. The rest of `buf_write()`
reads the freed name...
"foldtext()" [New] 41L, 997B written
E212: Can't open file for writing: illegal byte sequence
ASAN, with ui2 enabled and a `BufEnter` handler that runs `:lcd`:
READ path_skip_sep <- path_tail <- match_file_list <- buf_write
FREE shorten_buf_fname <- shorten_fnames <- update_cwd <- set_curbuf
<- win_set_buf <- nvim_open_win <- ui2 msg_show handler
<- ui_call_msg_show <- msg_ext_ui_flush <- buf_write
Solution:
Copy the names after the `*Pre` autocmds.
Note: `readfile()` has the same shape, but its messages pass no
progress-id, so they skip `msg_progress()`. Safe, for now...
The perf cost is negligible, but it's easy to address so might as well.
CID 653826: Performance inefficiencies (PASS_BY_VALUE)
/src/nvim/input_cmdatom.c: 385 in atom_push_raw()
384 /// Takes ownership of the atom's allocated members. Caller sets `atom.changed`.
>>> CID 653826: Performance inefficiencies (PASS_BY_VALUE)
>>> Passing parameter atom of type "CmdAtom" (size 176 bytes) by value, which exceeds the low threshold of 128 bytes.
385 void atom_push_raw(bool cascade, CmdAtom atom)
CID 653825: Performance inefficiencies (PASS_BY_VALUE)
/src/nvim/input_cmdatom.c: 438 in atom_stage_set()
436 /// Stages an atom built before its command executes (do_pending_operator() prep-exempt, Visual
437 /// ops), in the command's frame; pushed at frame end, once `changed` is known.
>>> CID 653825: Performance inefficiencies (PASS_BY_VALUE)
>>> Passing parameter atom of type "CmdAtom" (size 176 bytes) by value, which exceeds the low threshold of 128 bytes.
438 static void atom_stage_set(CmdAtom atom)
CID 653824: Performance inefficiencies (PASS_BY_VALUE)
/src/nvim/input_cmdatom.c: 427 in atom_push()
425 /// Pushes an atom (emit + maybe cascade), or drops it if replay/Visual/internal-op already
426 /// in-progress.
>>> CID 653824: Performance inefficiencies (PASS_BY_VALUE)
>>> Passing parameter atom of type "CmdAtom" (size 176 bytes) by value, which exceeds the low threshold of 128 bytes.
427 static void atom_push(bool cascade, CmdAtom atom)
Problem:
A mapping that ends mid-operation (`nnoremap ,D d`) emits a content-free
"mapping" atom plus a `pending` field, and the "continuation" motion
arrives as a sibling atom. Consumers must stitch the two together (which
has broken cases, e.g. Insert-opening mappings (",i") lose their session
entirely).
- ",i": the session atom is dropped bc the mapping RHS is consumed
before the session starts (typebuf_maplen()==0), so
atom_is_user_input()=false.
- ":normal"-in-opfunc: the opfunc internal "v..y" session (a) became
kVatomTyped just because the deferred composite was open, masking the
real operator capture via atom_captures, and (b) its nested frames
re-derived the outer redo.
- "Motion" based on `moved=true`, has false negatives.
- `CmdAtom.remap` is unnecessary, and clutters the docs/usage.
Solution:
- Introduce `frame_id` to identify CmdFrames.
- Classify `type=motion` better, via `NV_MOTION` flag on the `nv_cmds` table.
- Drop `CmdAtom.pending`, `CmdAtom.remap`.
- Defer atom_composite_end() at the clock edge while an operator is
pending, Visual is active, or `restart_edit` is set: the composite
keeps collecting, so the continuation is captured in the mapping atom.
- ",i": Now an open composite counts as user input.
- ":normal"-in-opfunc: Now handled correctly.
- `remap` is now decided by `composite.payload || 0 subatoms`.
atom_payload_mark() records the read the resolution never captures.
- `toplevel` is now decided by `CmdFrame.parent == NULL`.
before/after:
INPUT BEFORE AFTER
---------------------------------------------------------------------
,D w {mapping lhs=,D pending=operator} {operator lhs=,Dw keys=dw}
+ {operator keys=dw}
ysiw" {mapping lhs=ys pending=operator} {operator lhs=ysiw" keys=g@iw"}
+ {operator lhs=g@iw"}
,v d {mapping pending=visual} {visual lhs=,vd keys=viwd}
+ {visual lhs=viwd}
,i XY<Esc> {normal keys=i lhs=,iXY<Esc>} {insert keys=1iXY<Esc> text=XY}
* build(deps): bump tree-sitter to baad4174e
* build(deps): bump wasmtime to v48.0.0
Tree-sitter bumped their wasmtime dependency from v36 to v48 (the new LTS), so we must follow suit. This change brings in significant performance improvements for wasm parsers (although they are still significantly slower than native parsers).
Problem:
- `lhs` is not fully realized. E.g. for a "payload" mapping
`lhs` omits the `getchar()` payload during a mapping (vim-surround
`ds'` reports `lhs="ds"`). This means plugins like vim-repeat are
still needed...
- The "delta" fields of a CmdAtom are calculated too late.
- `<abuf>` and `changed` check whatever (wrong) buffer a command
(":bnext") might land in.
- CTRL-W_w between two windows on the same buffer reports type="motion".
Solution:
- `CmdOrigin` samples (buf/win/cursor/changedtick) at each "scope" entry
(CmdFrame, composite, Visual session, insert session).
- `dd<C-w>l` reports `changed=true` for the buffer it edited, regardless
of where the cursor ends up.
- New fields:
- `pos`: cursor position at command start.
- `moved`: indicates whether the cursor moved (in same buffer).
- `undoseq`: undo state at settlement.
- lhs now includes the payload: "ds)" reports lhs="ds)" instead of "ds".
- Easy for users to "replay" any atom.
- Rename: type "command" => "normal", "ex" => "excmd"; `arg` => `cmdarg`
- Drop `cascade` field (no reason to expose it)
Problem: Heap-buffer-overflow in spell_suggest() when the cursor is
beyond the end of the line, because a SpellFileMissing
autocommand changed the buffer (dvaave2025).
Solution: parse_spelllang() may run autocommands, so validate the cursor
position and re-take the saved position afterwards.
fixes: vim/vim#21097closes: vim/vim#21100
Supported by AI.
6073903cda
Co-authored-by: Christian Brabandt <cb@256bit.org>
Problem: Multiline messages exceeding 'cmdheight' not visible when a
mapping starts cmdline immediately after it (after 9.2.0967).
Solution: Revert patch 9.2.0967 and use a different solution (zeertzjq).
fixes: vim/vim#21098closes: vim/vim#21101fb4866a2dd
Problem:
An unreplayable Visual operation does not emit a CmdAtom event. That's
maybe not super important, but it hints at a flaw in how `vatom`
"voiding" is plumbed: `vatom.state=kVatomVoid` replaces the "kind", so
that info is lost to later parts in the lifecycle.
Solution:
- Define `VatomState` as "flags", so `kVatomVoid` can "poison"
`vatom.state` without losing its kind flag.
- Unify `lhs`: always report the original user input in `CmdAtom.lhs`,
for all kinds of user actions: visual, "translated"/"stuffed" cmds,
and dot-repeat (".") itself.
- Unreplayable Visual atom emits CmdAtom with non-empty `lhs` and empty
`keys`, like a mapping/macro composite.
vim-patch:8.1.2195: Vim does not exit when the terminal window is last window
vim-patch:8.1.2219: no autocommand for open window with terminal
vim-patch:8.2.0897: list of functions in patched version is outdated
vim-patch:8.2.3323: Vim9: Cannot use :silent with :endwhile
vim-patch:8.2.3589: failure when "term_rows" of term_start() is an unusual value
vim-patch:8.2.3597: Vim seems to hang when writing a long text to a terminal
vim-patch:8.2.3913: help for expressions does not mention Vim9 syntax
vim-patch:8.2.4153: MS-Windows: Global IME is no longer supported
vim-patch:8.2.4586: Vim9: no error for using lower case name for "func" argument
vim-patch:b09c32003 patch 8.2.4720: ABB Rapid files are not recognized properly
vim-patch:8.2.5000: no patch for documentation updates
vim-patch:eb4904187 release version 9.0
vim-patch:9.0.1818: dynamically linking perl is broken
vim-patch:6ffcc58be runtime(help): Updated documentation on editorconfig
vim-patch:b043ff34c runtime(doc): fix two typos in `vim9.txt` and `options.txt`
vim-patch:9.0.1994: inconsistent feature description
vim-patch:9.0.2026: win32: python3 dll loading can be improved
vim-patch:3c81f47a0 runtime(doc): correct <PageUp>/<PageDown> behavior in 'wildmenu'
vim-patch:a5a153475 runtime(doc): small updates to the documentation for varargs
vim-patch:5985879e3 runtime(doc): Fix typos in several documents
vim-patch:a56f02d82 runtime(doc): missing code formatting in if_pyth.txt
vim-patch:5f5131d77 runtime(doc): clarify bracketed paste mode
vim-patch:08b1c61e8 runtime(doc): clarify terminal capabilities for focus reporting
vim-patch:bee966d3f runtime(doc): clarify `:help inclusion` section
vim-patch:2c5240ec8 runtime(doc): Update usr_51.txt to be more inclusive
vim-patch:6ffe084e6 runtime(doc): document proper notation of gVim, document vim-security list
vim-patch:ca2eca7c7 runtime(doc): reference 'go-!' inside os_win32.txt for !start
vim-patch:0280c0b9a runtime(doc): sort option-list alphabetically
vim-patch:c23fc3647 runtime(doc): Update eval.txt
vim-patch:5872bcb6e runtime(doc): Create Changelog until v9.0.2175
vim-patch:59df9ad68 runtime(doc): Include Vim9 class features in version9.txt
vim-patch:74512e0ad runtime(doc): Add help tags to items in version9.txt
vim-patch:0ede5e361 runtime(doc): Update Version9.txt for release 9.1
vim-patch:6c1afa3d0 runtime(doc): add missing help tags
vim-patch:963fd7d6e runtime(doc): Fix typos in reltime() help.
vim-patch:7b7672d5c runtime(doc): Fix typos in version9.txt
vim-patch:9.1.0050: Win32 Keyboard handling is sub-optimal
vim-patch:1b7fbe726 runtime(doc): Update help for Wayland support
vim-patch:ec9c32637 runtime(doc): clarify expand() for :terminal windows
vim-patch:db7622ea8 runtime(doc): Fix typo in usr_41.txt
vim-patch:b1289f19e runtime(doc): Fix typo under *kitty-terminal* in term.txt
vim-patch:0e17f7e97 runtime(doc): clarify close behaviour for :term
vim-patch:7f0bba259 runtime(doc): Improve docs for empty(), len(), and string() on objects
vim-patch:9.1.0233: Vim9: string() output of enum is problematic
vim-patch:957402258 runtime(doc): Fill in a few details regarding :enums
vim-patch:9.1.0270: a few minor issues to fix
vim-patch:7b0c4b64e runtime(doc): typo in intro.txt
vim-patch:014b7759e runtime(doc): fix typos in starting.txt
vim-patch:a13290f82 runtime(doc): minor fixes to starting.txt
vim-patch:158673680 runtime(doc): minor spell fix in starting.txt
vim-patch:5400a5d42 runtime(comment): include a simple comment toggling plugin
vim-patch:ca4b81a7a runtime(doc): Add tags about lazyloading of menu
vim-patch:fb745756d runtime(doc): add MsgArea to 'highlight' option description
vim-patch:93e0d2e81 runtime(doc): update vi_diff.txt: add default value for 'flash'
vim-patch:e595e9c31 runtime(doc): clarify instal instructions for comment package
vim-patch:9.1.0417: if_py: find_module has been removed in Python 3.12.0a7
vim-patch:5cf5301e2 runtime(doc): clarify temporary file clean up
vim-patch:5f7571473 runtime(doc): clarify why E195 is returned
vim-patch:d801edfb1 runtime(doc): mention comment plugin at :h 'commentstring'
vim-patch:ce6fe84db runtime(man): update Vim manpage
vim-patch:5674c9a7d runtime(doc): add return type info for Vim function descriptions
vim-patch:c593b9ead runtime(doc): Added definitions of Vim scripts and plugins
vim-patch:c52a85607 runtime(doc): revert unintended formatting changes for termdebug
vim-patch:946f61c40 runtime(doc): clarify when text properties are cleared
vim-patch:84ac2126f runtime(doc): Fix typos in several documents
vim-patch:f0837ba0b runtime(doc): In builtin overview use {buf} as param for appendbufline/setbufline
vim-patch:950292152 runtime(doc): mention $XDG_CONFIG_HOME instead of $HOME/.config
vim-patch:49ddeefec runtime(doc): add reference to xterm-focus-event from FocusGained/Lost
vim-patch:b3c232215 runtime(doc): Correct shell command to get $VIMRUNTIME into shell
vim-patch:7298565c8 runtime(doc): autocmd_add() accepts a list not a dict
vim-patch:c5e24ee24 runtime(doc): add a note for netrw bug reports
vim-patch:6d6dffa61 runtime(doc): document global insert behavior
vim-patch:03d20aaac runtime(doc): 'cpoptions': Include "z" in the documented default
vim-patch:d24aaa998 runtime(doc): using wrong highlight for UTF-8
vim-patch:e7a4523b0 runtime(doc): fix typo "a xterm" -> "an xterm"
vim-patch:52e7cc26d runtime(doc): tweak documentation style a bit
vim-patch:90e1fe4b7 runtime(doc): fix a few style issues
vim-patch:ff1680722 runtime(doc): Remove mentioning of the voting feature
vim-patch:890f97ce5 runtime(doc): improve typedchar documentation for KeyInputPre autocmd
vim-patch:fd01eb21e runtime(doc): Update outdated man.vim plugin information
vim-patch:82f6134b1 runtime(doc): Update version9.txt and mention $MYVIMDIR
vim-patch:0b2285c96 runtime(doc): Fix typo in :help :hide text
vim-patch:fdd1819b5 runtime(doc): reword and reformat how to use defaults.vim
vim-patch:770b38df4 runtime(doc): fix typo in version9.txt nrformat -> nrformats
vim-patch:8ee0e0b8e runtime(doc): Fix to two-space convention in user manual
vim-patch:738ebfea4 runtime(doc): Fix style in documents
vim-patch:6e56484f0 runtime(doc): correct `vi` registers 1-9 documentation error
vim-patch:015c84ce5 runtime(doc): add missing usr_52 entry to toc
vim-patch:1961cafc9 runtime(doc): mention conversion rules for remote_expr()
vim-patch:5dcee3c72 runtime(doc): link help-writing from write-local-help
vim-patch:539349cb3 runtime(doc): improve the :colorscheme documentation
vim-patch:92b59c628 runtime(doc): Fix wrong Mac default options
vim-patch:d52fb2fab runtime(doc): Clean up minor formatting issues for builtin functions
vim-patch:b3ec5643c runtime(doc): include a TOC Vim9 plugin
vim-patch:6081c1789 runtime(doc): update help-toc description
vim-patch:ac2bb9dfe runtime(doc): add help specific modeline to pi_tutor.txt
vim-patch:39cd9061b runtime(doc): update default value for fillchars option
vim-patch:c9e864047 runtime(doc): Add pi_tutor.txt to help TOC
vim-patch:624bb8361 runtime(doc): Tweak documentation style a bit
vim-patch:18defabae runtime(doc): add a table of supported Operating Systems
vim-patch:dbf231a4b runtime(doc): mention option-backslash at :h CompilerSet
vim-patch:cb34507b5 runtime(doc): add helptag for :HelpToc command
vim-patch:a01148d2c runtime(doc): Expand docs on :! vs. :term
vim-patch:b534e8000 runtime(doc): Tweak documentation style a bit
vim-patch:73785accf runtime(doc): updated version9.txt with changes from v9.1.0905
vim-patch:9.1.0932: new Italian tutor not installed
vim-patch:9c3330de2 runtime(doc): fix some small errors
vim-patch:af0fed598 runtime(doc): Add a note about handling symbolic links in starting.txt
vim-patch:08be9ddc8 runtime(doc): move help tag E1182
vim-patch:ae01b9600 runtime(help): fix typo s/additional/arbitrary/
vim-patch:223d6c0a9 runtime(doc): update version9.txt for bash filetype
vim-patch:f6ba8defc runtime(doc): update for new keyprotocol option value (after v9.1.0969)
vim-patch:6de7191c3 runtime(doc): mention how NUL bytes are handled
vim-patch:34e271b32 runtime(doc): use standard SGR format at :h xterm-true-color
vim-patch:e80f345b5 runtime(doc): Tweak documentation about base64 function
vim-patch:27f2e473e runtime(doc): update index.txt
vim-patch:9598a6369 runtime(doc): add package-<name> helptags for included packages
vim-patch:6472e5836 runtime(doc): fix base64 encode/decode examples
vim-patch:71028a32d runtime(doc): rename last t_BG reference to t_RB
vim-patch:195fcc90d runtime(doc): Tweak documentation style a bit
vim-patch:9.1.1105: Vim9: no support for protected new() method
vim-patch:14e8208d8 runtime(doc): get rid of the titlestring hack for terminal-api
vim-patch:8d67cbfa1 runtime(doc): document vim syntax switches
vim-patch:7db96134c runtime(doc): Update doc 52.6
vim-patch:5f2a95955 runtime(doc): symlinking netrw.txt causes problems during install on Windows
vim-patch:9.1.1230: inconsistent CTRL-C behaviour for popup windows
vim-patch:932a535bf runtime(doc): update and correct str2blob() and blob2str() examples
vim-patch:92e109fc1 runtime(doc): Fix an omission in the documentation.
vim-patch:721be7fd0 runtime(doc): add back help tag "pi_netrw.txt"
vim-patch:1c2f47585 runtime(doc): Update the tuple help text
vim-patch:9.1.1274: Vim9: no support for object<type> as variable type
vim-patch:2afdb3a65 runtime(doc): Fix minor typo in options.txt
vim-patch:2525573de runtime(doc): rename wrong option to 'pummaxwidth'
vim-patch:0ed11ba22 runtime(doc): Tweak documentation style a bit
vim-patch:f39de6060 runtime(doc): style: clarify to prefer 2 spaces after a sentence
vim-patch:b753d80e5 runtime(doc): clarify return type for findfile()/finddir()
vim-patch:ba0062b0c runtime(helptoc): the helptoc package can be improved
vim-patch:9.1.1368: GTK3 and GTK4 will drop numeric cursor support.
vim-patch:ba19b6589 runtime(doc): fix typo in description of :redrawtabpanel
vim-patch:9.1.1418: configures GUI auto detection favors GTK2
vim-patch:d65cdadb7 runtime(doc): Fix typos and language in documentation for tabpanel.
vim-patch:6b2c1ad05 runtime(doc): clarify behaviour of set maxcombine=0
vim-patch:8f7256a5e runtime(doc): fix some style issues and remove obsolete docs
vim-patch:b657310bd runtime(doc): Fix modeline in wayland.txt
vim-patch:651edf33e runtime(doc): Tweak documentation style
vim-patch:57d6d0043 runtime(doc): Add documentation style
vim-patch:9.1.1529: Win32: the toolbar in the GUI is old and dated
vim-patch:bc84fd145 runtime(doc): handle newlines in base64 string encode example
vim-patch:d3170f59e runtime(doc): Tweak documentation about tab pages
vim-patch:9340aa1bf runtime(helptoc): add s keymap to split and jump to selected entry
vim-patch:fc3c204bb runtime(doc): Fix style and typos in builtin.txt and usr_41.txt
vim-patch:6b9cf3139 runtime(doc): update :call with a range and remove space
vim-patch:308a3130b runtime(doc): Update help for the items() function
vim-patch:39a67920f runtime(doc): Fix missing heading in remote.txt
vim-patch:dc725a04f runtime(doc): update termguicolors default description
vim-patch:e0196f3e2 runtime(doc): Tweak documentation style
vim-patch:6a2d0496a runtime(doc): add missing da1 value to TermResponseAll doc
vim-patch:5f8e31fec runtime(doc): remove documentation for t_Ms terminal code
vim-patch:b2e21cccc runtime(doc): Tweak documentation in vi_diff.txt
vim-patch:9.1.1743: Haiku: no full-screen support
vim-patch:5291fe89b runtime(doc): mention hl-PreInsert in version9.txt
vim-patch:f35a2af8e runtime(doc): improve 'complete' option description
vim-patch:450d59145 runtime(doc): tweak documentation style
vim-patch:235e77a3a runtime(doc): Tweak documentation style more in options and ft_hare
vim-patch:f9dad9e39 runtime(doc): Fix typos in eval.txt
vim-patch:f79e262ff runtime(doc): clarify how to call complete() funcs
vim-patch:a73963ed8 runtime(doc): fix typo, reorder, mention zip plugin at :h changed-9.2
vim-patch:a7680a1a6 runtime(doc): mention improved rendering with 'termguicolors'
vim-patch:07c68245d runtime(doc): MS-Windows: Improve documentation about VTP support
vim-patch:377339dff runtime(doc): make order of verbs match order of operators
vim-patch:4aa4a5690 runtime(doc): update getwininfo() documentation about popups
vim-patch:3b1901eb5 runtime(doc): Tweak documentation style
vim-patch:a67f2699b runtime(doc): update if_perl after v9.1.1822)
vim-patch:9.1.1826: Patch v9.1.1230 causes confusion about Ctrl-C behaviour
vim-patch:c58f91c03 runtime(doc): Whitespace updates
vim-patch:7bb56b49e runtime(doc): Fix option markup at :help 'pumborder'
vim-patch:9.1.1882: Vim9: Not able to use a lambda with :defer
vim-patch:07da26710 runtime(doc): Fix a few typos
vim-patch:7f60105cb runtime(doc): fix typo in "appendbufline()", builtin.txt
vim-patch:4bb44b287 runtime(doc): Change termdebug_config debug value to v:true in terminal.txt
vim-patch:911ecdcd0 runtime(doc): fix return value in 'exists' and 'exists_compiled()'
vim-patch:e9a983326 runtime(doc): Tweak documentation style in eval.txt and options.txt
vim-patch:a2b45646a runtime(doc): Update version9.txt for v9.1.1966
vim-patch:fdd21ca37 runtime(doc): fix wrong help tag reference in eval.txt
vim-patch:93d9d196e runtime(doc): use codepoint consistently
vim-patch:a820a4540 runtime(doc): Fix "Vim script" formatting at :help clipboard-providers
vim-patch:3913f13a7 runtime(doc): Improve :help builtin-function-list table formatting
vim-patch:08953f711 runtime(doc): Minor updates to version9.txt
vim-patch:745335c87 runtime(doc): fix return type in getqflist() and getloclist()
vim-patch:5268b9515 runtime(doc): clarify the help style a bit
vim-patch:7599a1899 runtime(doc): Mark the use of "\n" in the tabpanel as experimental
vim-patch:f39e7a89f runtime(doc): update win_findbuf() return value
vim-patch:db4ff9a40 runtime(doc): Add Swedish to help-translated list
vim-patch:f73bd2546 runtime(doc): clarify term_cols allowed range in terminal.txt
vim-patch:52507a733 runtime(doc): Mark 'scrollfocus' as non-functional
vim-patch:b8f58dd69 runtime(doc): Fix typos in version9.txt
vim-patch:ac1d379f3 runtime(doc): correct XDG runtimepath
vim-patch:48677d774 runtime(doc): Update version9.txt, update the description of getwininfo()
vim-patch:9ebb666b8 runtime(doc): Update runtimepath default locations
vim-patch:06a604dc8 runtime(doc): Mention xdg.vim in version9.txt
vim-patch:3c1594533 runtime(doc): update option type of 'termresize' option (after v9.2.0139)
vim-patch:751b59e53 runtime(doc): clarify :silent usage for system()/systemlist()
vim-patch:7a9548c40 runtime(doc): Update help tags references
vim-patch:3f53a2ce2 runtime(doc): Fix typo in cmdline.txt
vim-patch:9.2.0198: cscope: can escape from restricted mode
vim-patch:9.2.0205: xxd: Cannot NUL terminate the C include file style
vim-patch:9.2.0248: json_decode() is not strict enough
vim-patch:0646047b6 runtime(doc): clarify term_start() I/O behavior for Unix pty and MS-Windows ConPTY
vim-patch:9d9381fb2 runtime(doc): Tweak documentation style a bit
vim-patch:01e967021 runtime(doc): Update documentation on statusline click handler
vim-patch:9.2.0336: libvterm: no terminal reflow support
vim-patch:4b6f3f1d1 runtime(doc): Tweak documentation style in options.txt
vim-patch:32a30cb5a runtime(doc): Update docs about tabpanel
vim-patch:9.2.0404: redraw_listener_add() does not check secure flag
vim-patch:30b424073 runtime(doc): Update docs related to tabpanel
vim-patch:9.2.0412: channel: term_start() out_cb/err_cb no longer deliver raw chunks
vim-patch:e7e35b9e3 runtime(doc): clarify that viminfo file should be trusted
vim-patch:f793e9806 runtime(doc): clarify separator cell on status line rows
vim-patch:37d61dae7 runtime(doc): update doc for clipboard provider
vim-patch:07dc94023 runtime(doc): document new GTK4 GUI in version9.txt
vim-patch:d0af3bcee runtime(doc): fix help tags for removed/reused error codes
vim-patch:6574102fb runtime(doc): Tweak documentation style
vim-patch:9.2.0534: GTK UI does not support fullscreen mode
vim-patch:18c6b91ca runtime(doc): fix a typo in :write-plugin
vim-patch:66a42052e runtime(doc): document that +multi_byte is always enabled
vim-patch:4bc842b0b runtime(doc): Tweak some documentation style
vim-patch:9.2.0723: term_start() does not support "noclose"
vim-patch:26dfed583 runtime(doc): Add installer updates to version9.txt
vim-patch:5680e3b29 runtime(doc): clarify behaviour of 'title' and 'iconstring'
vim-patch:7b11d840c runtime(doc): Improve fuzzy file picker doc
vim-patch:648d16e4c runtime(doc): clarify 'icon' and 'title' interaction for screen 5
vim-patch:726ce3094 runtime(doc): improve suggested detection method for WSL
vim-patch:02c0a9040 runtime(doc): document &t_8u as &t_8f and &t_8b
vim-patch:ac78f14b9 runtime(doc): Tweak documentation style a bit
vim-patch:4a997e146 runtime(doc): GTK: document that "font" in a highlight group has no effect
vim-patch:b4ae16ca3 runtime(doc): clarify 'laststatus' effect
vim-patch:7203411bc runtime(doc): add a few more references to 'guiligatures'
vim-patch:9.2.0916: configure: honor `--disable-hardcopy-pango` with GTK UI
vim-patch:95e8f2e93 runtime(doc): v:windowid is x11 only
vim-patch:b4b3a62a4 runtime(doc): mark the GTK4 GUI as still experimental
vim-patch:a0f057dac runtime(doc): Tweak documentation style a bit
vim-patch:1d14eea96 runtime(doc): Add clipboard provider example for WSL
vim-patch:9.2.0973: Vim9: internal error when a class member is initialized with a closure
vim-patch:9.2.0974: tests: Test_clientserver_serverlist_list() is flaky
vim-patch:9.2.0975: Vim9: assignment to a member of an object member fails
vim-patch:9.2.0977: tests: test_terminal_visual_empty_listchars() is flaky
Remove the note about "this function is called only once per :find
command invocation".
fixes: vim/vim#21062bce3eb1fae
Co-authored-by: Christian Brabandt <cb@256bit.org>
Problem:
`signal_ignore_deadly` doesn't work for Windows, where the console still
may terminate Nvim during teardown (after `signal_teardown`), while it
is already trying to exit. Besides interrupting any housekeeping we are
doing, it results in an unpredictable exit code (flaky tests).
[Process exited -1073741510] // 0xC000013A STATUS_CONTROL_C_EXIT
Solution:
Register our own CTRL_CLOSE_EVENT handler which "blocks" the signal.
Note: if exit takes longer than 5s, Windows will consider the process
"hung" and kill it anyway.
Problem:
A deadly signal arriving during teardown can kill Nvim while it is
preserving swapfiles. `os_exit()` ignores deadly signals via
`signal_reject_deadly()`, but `signal_teardown()` => `uv_signal_stop()`
resets them to the default behavior, so SIGHUP arriving after that
kills the process:
[Process exited 129] // 128 + SIGHUP
This is a race when closing a pty: kernel sends SIGHUP to foreground
process group *and* the reads return EOF, so `chanclose()` on a TUI job
prepares to exit twice. This means it is unpredictable whether Nvim
exits 1 or is terminated.
Solution:
Ignore deadly signals once the watchers are closed. Only SIGKILL
interrupts it now.