Problem: A preselected item is inserted even with "noinsert", and the
first added preselected item wins over the first one shown
in the menu.
Solution: Use K_DOWN when "noinsert" is set; pick the first preselected
item that made it into the menu.
Problem:
POSIX-compatible Ex-mode requires special-cases all over the codebase to
match various quirks that don't actually matter to users.
- The main utility of *interactive* Ex-mode is its REPL behavior, and
that can be achieved with `cmdwin`, which also gains extra UX
benefits.
- The main utility of *non-interactive* `nvim -es` is for shell
scripting, where Ex-mode quirks are mostly unhelpful (e.g. the
"Entering Ex mode" message).
Solution:
- Reimplement *interactive* Ex-mode as a "persistent, insert-mode
cmdwin" in Lua.
- "nvim -e/-E" is simply an alias to "gQ".
- Reframe *non-interactive* Ex-mode (`nvim -es`) as "script mode".
- Drop POSIX Ex-mode quirks.
Improvements:
- "nvim -V1 -es" output ends with a final newline!
- "nvim -V1 -es" no longer shows the "Entering Ex mode" msg. (This was
pointless noise, unwanted for scripting purposes.)
- stdin is no longer typeahead. Scripts (":lua io.read()") can read
stdin as data.
- Empty line is a no-op: a stray blank line no longer moves the cursor
(deviates from POSIX ex "+1"), no longer exits 1 at EOF (E501).
Preserved behavior:
- cursor starts at "$"
- mode()=="cv" (for non-interactive)
- multiline commands (:append/:function/heredoc pull continuation lines)
- bare-range print
- :print=>stdout
- -V1=>stderr
- CRLF input
- continue-after-error and exit codes
Dropped (regressed) POSIX behavior (non-interactive):
- Event loop only ticks while/between commands, not while blocked
waiting for a stdin line.
- ":g/pat/visual...Q"
- input()/getchar()/":s/x/y/c" no longer consume stdin lines as
answers: Nvim stops at end-of-input, skipping the rest of the script,
exit 0. Use ":lua io.read()" instead.
- If users care about this they should use interactive Ex-mode (`gQ`).
- ":@r" stops at end of the register instead of continuing to read
cmdline input from stdin.
Problem:
The current check is intended to match DOS device paths starting with
`\\?` or `\\.` but will match any path starting with `?` or `.`,
including relative paths such as `.\`.
This is because the leading slashes are removed before the comparison.
Solution:
Changes the check to include the path's prefix, assuring the path has
the correct amount of separators for a DOS device path.
vim-patch:8.2.4761: documentation for using LSP messages is incomplete
vim-patch:8.2.4780: parsing an LSP message fails when it is split
vim-patch:9.0.0979: ch_log() text can be hard to find in the log file
vim-patch:7c948644f runtime(doc): Update the version9.txt with a template for version 9.1 enhancements (#13165)
vim-patch:15935e7f5 runtime(doc): Add a place holder section for version 9.2 (#14060)
vim-patch:1a946044f runtime(doc): correct return types for job_start() and job_status()
vim-patch:1cd31a450 runtime(doc): update return type for job_info()
vim-patch:15141208e runtime(doc): -x is only available when compiled with crypt feature
vim-patch:a37fd7274 runtime(doc): Remove accidental option name highlighting from :help channel.txt
vim-patch:1ff963e15 runtime(doc): Update version9.txt with numbered patches
vim-patch:9.1.2134: Terminal doesn't handle split UTF-8 sequence after ASCII
vim-patch:9.1.2141: Truncation when serializing libsodium encryption parameters
vim-patch:9.1.2145: intstalltutor Makefile target does not create the tutor/sv dir
vim-patch:9.1.2148: [security]: Buffer overflow in netbeans interface
vim-patch:9.2.0021: channel: connection timeout fails to fall back to IPv4
vim-patch:9.2.0314: channel: can bind to all network interfaces
vim-patch:9.2.0317: listener functions do not check secure flag
vim-patch:60e925ca0 runtime(doc): Tweak documentation style in channel.txt
vim-patch:9.2.0843: [security]: popup: opacity mask indexed out of bounds
vim-patch:9.2.0844: [security]: use-after-free on json decode error
vim-patch:9.2.0847: [security]: vimball: code execution via .VimballRecord file
vim-patch:b0e6baab8 Update .gitignore and .hgignore files
vim-patch:9.2.0851: Focus autocommands triggered inconsistently
vim-patch:9.2.0852: GTK: ligatures not correctly displayed
vim-patch:9.2.0853: popup: popup images do not support scaling
vim-patch:3886a8ffc runtime(osc52): don't use osc52 provider if gui is running
vim-patch:f5882d534 CI: Bump the github-actions group across 1 directory with 3 updates
vim-patch:9.2.0856: GTK4: undercurl rendering is inefficient
vim-patch:9.2.0841: [security]: heap overflow when adding > 65535 text properties
vim-patch:9.2.0842: [security]: stack buffer overflow in socket server
Problem: Shortening the name of a buffer whose full name is the current
directory + path sep yields empty string -> buf unnamed.
This doesn't interact well with things like `:mksession`, which
for example could `:badd` with no arg -> E471.
Solution: Keep the full path when shortening yields an empty name, as
`path_try_shorten_fname()` already does.
Problem: 'showcmd' not redrawn with empty mapping triggered on timeout.
Solution: Don't postpone redraw when inside vgetorpeek(). Also move test
for tabline 'showcmd' to test_tabline.vim.
fixes: vim/vim#20839closes: vim/vim#208402e9687647a
Problem: The `showcmd` statusline item may show internal command keys when a
`<Cmd>` or `<ScriptCmd>` mapping redraws the statusline, and may
leave stale text behind when `%S` is rendered directly.
Solution: Do not add these internal mapping dispatch keys to the `showcmd`
buffer, and keep the clear state in sync when `%S` renders it
(Barrett Ruth)
closes: vim/vim#20769bd730293dc
Co-authored-by: Barrett Ruth <br@barrettruth.com>
Problem: `q:` in visual mode does not insert `'<,'>` automatically in
the current line on cmdwin.
Solution: Insert `'<,'>` in the current line on cmdwin when `q:` is used
in visual mode.
Problem: `:browse edit` (and variants) without an argument fails instead
of opening a browser.
Solution: Dispatch to dir.lua using the cwd as the implied directory.
Replace the inherited GUI-only documentation with the supported
behavior. Support vsplit, split, tabedit variants.
Problem: Memory leak when a spell file has an SN_SAL section before an
SN_SOFO section: set_sofo() reuses sl_sal without freeing the
salitem_T entries left by read_sal_section() (after v9.2.0846).
Solution: Factor the SAL free loop into free_sal_items() and call it
before set_sofo() reuses sl_sal.
closes: vim/vim#20836
Supported by AI.
5a7ce2733a
Co-authored-by: Christian Brabandt <cb@256bit.org>
Problem: [security]: heap buffer overflow in set_sofo()
(Yazan Balawneh)
Solution: Reset sl_sal_first (Yasuhiro Matsumoto).
A crafted spell file with an empty SN_SAL section before an SN_SOFO
section reaches set_sofo() with sl_sal_first[] already set to -1 by
set_sal_first(). The counting loop then under-counts colliding
multi-byte "from" characters, allocates an undersized list and writes
past its end.
Github Security Advisory:
https://github.com/vim/vim/security/advisories/GHSA-9jqx-hgpr-6v6405c41c9223
Co-authored-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Problem: When a tagfunc returns a "cmd" that is neither a line number nor
a search pattern, the tag entry is corrupted: the "kind" field is
lost and taglist() returns a mangled "cmd".
Solution: Accept any Ex command in "cmd" as in a tags file, terminate a
generic command with a bar so the trailing fields are preserved,
and reject a value that cannot be stored in a tag line with E987
(Hirohito Higashi).
fixes: vim/vim#20781
related: vim/vim#20790
closes: vim/vim#2082886adef19fc
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Mao-Yining <mao.yining@outlook.com>
The parent commit made a valiant effort to store "dict options" in their
reified form, but this is more trouble than it's worth:
- inconsistent model for developers to understand.
- string lifetime issues (the "varp" convention is to pass around an
aliased, long-lived option value).
- lots of extra plumbing to deal with the 2 different option-storage
paradigms.
Problem:
Options parsing is still painful for dict-style options.
Solution:
schema-maxxing => better `opt:get()` (will be the basis for `vim.o()`),
unified (and more-detailed) err msgs.
- Drop bespoke structure-builder in `_core/options.lua`.
- Define `schema` for all non-primitive options (except 'guicursor' and
statusline-style options); generate reified keysets `OptKeyDict`).
- Generate 'fillchars' => `fcs_tab`, 'listchars' => `lcs_tab`.
- `nvim_set_option_value`:
- Return the improved structures. Also from `vim.opt.x:get()`.
- Eliminate api <=> lua roundtrip, centralize option structure
handling.
- Improve/unify errors.
- Bump ERR_BUFLEN 80 → 256 so the "one of" list isn't truncated.
- Eliminate old 'diffopt' order-dependence (`iwhiteall` before `iwhite`)
Error samples:
Typed-key path (opt_strings_check → diffopt/mousescroll/breakindentopt):
E474: Unknown item 'foo'
E474: 'context' requires a number
E474: 'ver' number is out of range
E474: 'algorithm' must be one of: myers, minimal, patience, histogram
E474: 'filler' does not take a value
Related:
- #31084
- #34661
- #31820
- #14739
- #20107
- fix#18875
- :get() returns `{ sbr = true, shift = '3' }` (reified-keyset) instead of `{'sbr', 'shift:3'}`
- Setting via table now works too. `object_as_optval_for` `is_map` now recognizes struct options.
- fix#30296
- instead of `E474: Invalid argument`, errors now look like:
```
E474: Invalid value 'x', expected one of: single, double: ambiwidth=x
E474: Unknown item 'foo': diffopt=foo
E474: 'context' requires a number: diffopt=context:x
```
simplify `win_float_parse_option` from #26799.
Problem:
The preview-window (:pedit, etc.) always uses a split, but it would be
useful as a floatwin (or "popup").
Solution:
Support Vim's 'previewpopup' option.
Problem:
`:restart` on Windows always forces `AllocConsole`, even though we could
reuse old server's existing console + unnecessary env.
Analysis:
After d5516daf12 changed the restart
lifecycle and 789741bb83 separated the
Windows console paths, we no longer need to force `AllocConsole()` for
`:restart`. The `:detach` path now allocates its own console when it
actually runs.
Solution:
Try to attach the replacement server to its parent’s console and fall
back to `AllocConsole()` if attachment fails. Drop the restart-specific
env that forced allocation.
As documented by Microsoft, [“A console is closed when the last process
attached to it terminates or calls
`FreeConsole`.”](https://learn.microsoft.com/en-us/windows/console/attachconsole)
Btw, this way we can preserve `io.stdout:write()`, though if for some
reason `AttachConsole` would fail then it won't work; but now at least
it's not always not rendering on `:restart`.
vim-patch:9.2.0820: GUI: hidden popup image is displayed and not erased
vim-patch:9.2.0822: GTK4: crash menu id is null in gui_mch_destroy_menu()
vim-patch:9.2.0823: tests: Test_clientserver_servlist_list may fail
vim-patch:9.2.0824: Makefile: Make tags depends on configure
vim-patch:9.2.0828: GTK4: hardware rendering can be improved
vim-patch:2f0178afe Update .gitignore and .hgignore files
vim-patch:9.2.0832: socketserver: remote commands can be processed in reverse order
vim-patch:9.2.0833: GTK4: menu mnemonics do not work properly
vim-patch:bb86a1866 runtime(doc): clarify re-sourcing of Vim9 script behaviour
Co-authored-by: marvim <marvim@users.noreply.github.com>
Problem: When the terminal reports no colors ("t_Co" is 0 or 1) the
insert mode completion popup menu is not shown at all, while
the command line completion popup menu ('wildoptions' contains
"pum") is shown. In 'wildmenu' completion the current match
cannot be told apart from the other matches (Maxim Kim)
Solution: Show the insert mode completion popup menu regardless of the
number of colors and add "term" attributes to the default
highlighting of Pmenu, PmenuSel and PmenuThumb. The wildmenu
is drawn with the attributes of the status line, which is
reversed, and on most terminals the standout mode is the same
as the reverse mode, thus use the underline mode for the
default highlighting of WildMenu (Hirohito Higashi).
fixes: vim/vim#20800closes: vim/vim#2080352485e0d24
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Problem:
When buffer is open in multiple windows and its line count changes, any
'statusline' or 'rulerformat' items depending on it (e.g. %P) will
become invalid in non-current windows because w_redr_status is only set
on first change.
Solution:
Set w_redr_status on all windows with the buffer when the line count
changes.
Signed-off-by: Ondrej Balaz <blami@blami.net>
Problem:
Redundant code.
Solution:
Combine path_has_wildcard() and path_has_exp_wildcard(). They have similar logic.
Also, the latter operates on whatever wildcards remain after shell/env/backtick
expansion, so the two felt somewhat related.
Also drop some unnecessary MB_PTR_ADV calls.
Problem: ":startinsert" enters Insert mode in a buffer where
'modifiable' is off, the error only appears when a character
is typed. Typing "i" gives the error right away (Barrett Ruth)
Solution: Give the error when the buffer is not modifiable, like "i"
does. Keep ignoring the command in a terminal window, where
":startinsert" is documented to be ineffective, and keep
accepting it when 'insertmode' is set, like "i" does
(Hirohito Higashi).
fixes: vim/vim#20804closes: vim/vim#208066ab1976e49
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Problem: do_sub() only checks the timeout limit after finishing a line.
A pathological regex will run on a single line input unbounded
until the compute is completed.
Solution: Pass the timeout limit to `vim_regexec_multi()` so the
computation on the regex engine is bounded per-line.
Signed-off-by: XiaowenHu96 <me@xiaowenhu.com>
Problem: With the NFA engine a sub-expression inside a variable width
look-behind, e.g. "\v(.)@<=", is empty for the first match on
every line except the first one. The old engine is correct
(Mukundan)
Solution: The look-behind is retried from the previous line, because the
width of "." is over-estimated. While scanning that line the
start state is added at the end of the line, where it gets the
position of the line break as its start position, even though
the match actually starts on the next line. Use the position
of the start of the next line in that case (Hirohito Higashi).
fixes: vim/vim#20802closes: vim/vim#20805ade577e4dc
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Problem:
emmylua reports `unresolved-require` for `require('test.testutil')` and
friends, and a file under `test/` cannot even resolve its own siblings.
This happens because `test/.emmyrc.json` and `test/.luarc.json`, cause
vim.lsp to root the workspace at `test/` instead of the repo top-level.
Solution:
Drop the nested configs:
src/.luarc.json
test/.luarc.json
test/.emmyrc.json
Outcomes:
- No "libraries" needed: luv types come from `runtime/lua/uv/_meta.lua`,
not `${3rd}/luv` (which would only duplicate them).
- Drop `test/` from the root `.luarc.json` `ignoreDir` so its modules are
resolvable by LuaLS/Emmylua.
- Note: this means that LuaLS diagnostics will now be reported for
`test/`, but that is not a bad thing...
Problem:
Generated API bindings for Lua contain unused jump labels when the API
function has a non-KeyDict (e.g., Array) param after a KeyDict param, causing
the build to fail.
Solution:
Don't output a label when the current parameter is not a KeyDict but the
previous one is.
vim-patch:9.2.0807: MS-Windows: ellipsis character is garbled
vim-patch:9.2.0816: GTK4: Memory leak in gui_gtk_set_dnd_targets()
vim-patch:8.2.0142: possible to enter popup window with CTRL-W p
vim-patch:8.2.0743: can move to another buffer from a terminal in popup window
vim-patch:8.2.0745: crash on exit when not all popups are closed
vim-patch:8.2.1729: endless loop when ":normal" feeds popup window filter
vim-patch:8.2.1997: window changes when using bufload() while in a terminal popup
vim-patch:8.2.2183: Vim9: value of 'edcompatible' and 'gdefault' are used
vim-patch:8.2.2519: Vim9: no reason to keep strange Vi behavior
vim-patch:8.2.2527: Vim9: lambda return type is not determined at script level
vim-patch:9.2.0797: Memory leak in get_qfline_items() on alloc failure
vim-patch:9.2.0800: Memory leak in call_func() on alloc failure
vim-patch:9.2.0803: Memory leak on alloc failure with taglist/gettagstack()
vim-patch:9.2.0808: getregionpos: double-free on alloc failure
vim-patch:9.2.0809: getframelayout() uses wrong function to free lists
vim-patch:9.2.0810: add_llist_tags() uses wrong function to free dict
Problem: Deeply nested regexp groups can cause uncontrolled recursion
in the regexp compiler and exhaust the C stack.
Solution: Limit recursive regexp parsing depth in both the backtracking
and NFA compilers (lipengyu)
closes: vim/vim#20731a79cd6bfc3
Co-authored-by: lipengyu <lipengyu@kylinos.cn>
Problem: dict_add_func() references the function only after a
successful dict_add(), on failure dictitem_free()
calls func_unref() without a matching func_ref(), corrupting
the reference count of a lambda or numbered function.
Solution: Take the reference before dict_add() so the unref on the
failure path is balanced (Yasuhiro Matsumoto).
related: vim/vim#20668
closes: vim/vim#207424a403b48c6
Co-authored-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Problem: :argdelete with pattern leads to wrong argidx().
Solution: Correct argidx() in both branches of ex_argdelete(). Also use
ARGCOUNT macro in two more places (zeertzjq).
related: patch 7.4.1119
related: neovim/neovim#40564
closes: vim/vim#206973b40a14a46
Problem:
The title is combined with window's attributes only if the title is a
string (which implies the FloatTitle / FloatFooter highlight groups),
but not when the title is text-hl chunks.
Solution:
Combine specified highlight group with window-local Normal highlight as
well.
Problem:
w_float_is_info conflates a window's role with its floating layout,
which are orthogonal properties.
Solution:
Replace w_float_is_info with a w_kind enum for the window's role.
Problem:
The list-item indentation logic in `gen_help_html.lua` tracks `opt.indent` that
only decrements by one level when a list item is less indented than its sibling.
Dedenting across multiple nesting levels at once produces the wrong left margin.
Solution:
Track the exact leading whitespace for each indent level in a `opt.indent_ws` stack:
- On reset or a top-level item initialize the stack with the current item's
whitespace.
- When indenting deeper push the current whitespace at the new level.
- When dedenting pop every level whose tracked whitespace is deeper than the
current item (reaching the correct ancestor level).