Problem: transstr() appends with STRCAT()/STRLEN() from the start of
the result on every iteration, making it quadratic to the
length of the string.
Solution: Keep a tail pointer and append at it. (Samuel Schlesinger).
closes: vim/vim#20925124c86868c
Co-authored-by: Samuel Schlesinger <sgschlesinger@gmail.com>
Problem: "zb" scrolls incorrectly with cursor just above fold.
Solution: Handle boff.lnum being set to the last line of a fold
(zeertzjq).
With the cursor just above fold, botline_forw() moves boff.lnum to the
last line of the fold, but curwin->w_botline is at the first line of the
fold, so the boff.lnum == curwin->w_botline condition never holds.
Instead, check that boff.lnum has just moved to or past w_botline by
comparing its previous value with w_botline.
Also make a similar change to the loff.lnum check above for symmetry.
That one doesn't change behavior, as topline_back() sets loff.lnum to
the first line of a fold.
related: neovim/neovim#41122
closes: vim/vim#20923aee686334c
Problem: The test comparing the top line before and after using the
autocommand window is flaky in the GUI.
Solution: Run the test in a window with a fixed size. In the GUI a
pending resize of the shell is applied at the end of a screen
update, thus the size may change between the two measurements.
related: vim/vim#20884
closes: vim/vim#2091385b8034dff
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Problem: With 'virtualedit' set to "all" and 'cursorcolumn' set, the wrong
column may be highlighted after a command that moved the cursor
into virtual space and back (van-de-bugger).
Solution: Make sure the virtual column is up to date before drawing the
window (Hirohito Higashi).
fixes: vim/vim#2576closes: vim/vim#209025a90b9dbd2
Test only. This was already fixed by #39159.
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Problem: filetype: ed script files not recognised.
Solution: Add filetype detection for *.ed files and shebang lines,
include syntax script and syntax tests.
Features of the ed syntax file:
- BSD and GNU extensions are supported
- Andrew L. Moore's ed extensions are not supported
- Rebuild synmenu.vim
closes: vim/vim#19602c28515b999
Co-authored-by: Doug Kearns <dougkearns@gmail.com>
Problem: The :compiler command causes a crash. (Daniel Steinberg)
Solution: Do not use the script index if it isn't set.
----
ex_vim9script() is N/A.
----
165315584d
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Problem: With 'smoothscroll' the scroll position in a long line is lost when
a window is temporarily squeezed to a couple of lines, for example
when opening and closing a help window.
Solution: When the cursor ends up in the skipped columns, skip up to the
screen line the cursor is in instead of showing the start of the
line.
closes: vim/vim#2089215f8ba5cec
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Problem: With 'smoothscroll' the scroll position in a long line is lost when
moving to a column with "|".
Solution: Adjust the skipped columns for the column the cursor ends up in,
not for column zero.
related: vim/vim#20885
closes: vim/vim#208905ed8fc10fa
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Problem: :bwipe crashes if WinLeave wipes all other buffers
(after 9.1.2068).
Solution: Check for NULL pointer.
related: neovim/neovim#41066closes: vim/vim#208883e4019a082
Problem:
Cannot assign Lua functions/closures to "func" ('completefunc',
'tagfun', …) or "expr" ('foldexpr', 'indentexpr', …) options.
Solution:
- Store "func"/"expr" options as `Callback` instead of string.
- Delete oceans of copy-pasted code.
- BREAKING: LuaRef returned via RPC/Vimscript is now represented as
`"<Lua N: file:line>"` (like what `:map` shows) instead of `nil`.
- Note: `man.vim` still uses `v:lua` string, bc it's a vimscript ftplugin.
Helped-by: Lewis Russell <lewis6991@gmail.com>
Problem: With 'smoothscroll' the scroll position of a window is lost when
its height changes.
Solution: Only reset the skipped columns when 'smoothscroll' is off, where
they just serve to keep the cursor visible.
closes: vim/vim#2088517f3923b8c
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Problem: The window scrolls when an autocommand window is used while the
cursor is behind multi-byte characters.
Solution: Use the byte column instead of the character count when computing
how many screen lines the text up to the cursor takes.
fixes: vim/vim#12085closes: vim/vim#208847fe3ea7658
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Problem: The zip autoload script aborts loading when the "zip"
command is not available, so even read-only browsing of an
archive fails with E117 (zip#Browse undefined) on systems
that have "unzip" but not "zip" (e.g. the Windows CI
runner). Regressed in b0e0b22.
Solution: Drop the load-time executable gate and check each command
per operation instead, so a missing "zip" only affects
writing. Update the test to match the reworded message.
e241ac0a62
Co-authored-by: Christian Brabandt <cb@256bit.org>
Problem: When the only window has 'winfixheight' set and 'laststatus'
is one, splitting it leaves one screen line unused. This
happens for example when jumping to an item from a maximized
quickfix window (rendcrx)
Solution: Do not subtract the height of the status line twice
(Hirohito Higashi)
fixes: vim/vim#20495closes: vim/vim#20871ab36bcc870
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Problem: checkSmall() compares the fold size of window "wp" against
the current window's 'foldminlines'. A fold of another
window, e.g. measured while it is redrawn, is judged by an
unrelated option value.
Solution: Use 'foldminlines' of the window containing the fold
(Igor Mikushkin).
closes: vim/vim#20864773dc19f14
Co-authored-by: Igor Mikushkin <igor.mikushkin@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Problem:
The bundled `zip` plugin is implemented in Vimscript, making it harder to
maintain and build on with Nvim's Lua runtime infrastructure.
Solution:
Add an opt-out `zip.lua` browser backed by `nvim.dir`, and disable the legacy
Vimscript implementation by moving it to `pack/dist/opt/zip/`. Load it with
`:packadd zip`.
Problem: An insecurely-set 'indentexpr', 'formatexpr', 'includeexpr'
or 'complete' value can end up evaluated outside the
sandbox after buf_copy_options() and clears the flag.
Solution: Copy the insecure flag alongside the value in
buf_copy_options(), and make 'complete' a per-buffer
insecure-flags field
Supported by AI.
closes: vim/vim#2086135f7fdfdfb
I'm a bit hesitant to port this, but it's a follow-up to #39452.
Co-authored-by: Christian Brabandt <cb@256bit.org>
Problem:
Want `gQ` for _le multicursor_.
Solution:
- Don't use `gQ` for exmode.
- Introduce `:exmode`.
- Introduce `[count]q:` as an alias to `:exmode`.
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: '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: [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>
Problem: [security]: arbitrary Ex command execution during C
omni-completion (Threonine)
Solution: Match tags typeref literally to block Ex command injection
(Yasuhiro Matsumoto).
Escaping only "/" and "\" left the typeref able to break out of the
:vimgrep pattern without a "/": an unclosed "[" makes vimgrep's pattern
skipping fail, and the parser then treats a following "|" as a command
separator, so the tag value runs as Ex commands during C omni-completion.
Match the field literally with \V so no regex metacharacter can affect
pattern parsing.
Github Security Advisory:
https://github.com/vim/vim/security/advisories/GHSA-cx73-phcg-3j5g2f628d8104
Co-authored-by: Yasuhiro Matsumoto <mattn.jp@gmail.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: 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: filetype: .git-blame-ignore-revs file is not recognized
Solution: Detect .git-blame-ignore-revs file as gitrevlist filetype,
include syntax and filetype plugins (Fionn Fitzmaurice)
A Git revision list is
> a list of object names (i.e. one unabbreviated SHA-1 per line)...,
> comments (#), empty lines, and any leading and trailing whitespace are
> ignored.
(from Git's fsck.skipList documentation).
The default output of git rev-list will match this. It is also suitable
as input to git blame --ignore-revs-file.
This adds filetype detection matching .git-blame-ignore-revs files,
syntax highlighting and basic filetype settings.
closes: vim/vim#20702a8d5be9284
Co-authored-by: Fionn Fitzmaurice <fionn@github.com>
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: 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: 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: :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: ml_get error when changing hidden buffer in Python.
Solution: Block updating folds. (closesvim/vim#7598)
----
"ctx_switch()", "ctx_restore()" obsolete "switch_buffer()" and
"restore_buffer()".
Latter are unused since https://github.com/neovim/neovim/pull/15831.
Mark them as N/A (until some test fails).
----
3e0107ea16
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Problem: Visual block reselection wrong with 'virtualedit' when line
lengths are different (Alex Yang, after 8.2.3494).
Solution: Set the entire cursor position to old position when computing
target curswant, since the check_cursor() added in 8.2.3494
may change cursor column as well (zeertzjq).
fixes: vim/vim#20746closes: vim/vim#207488cddbfe468
Problem: extend() and extendnew() don't handle NULL expr2 properly
(Mao-Yining)
Solution: Still set the return value when expr2 is NULL (zeertzjq).
fixes: vim/vim#20758closes: vim/vim#20759e397c82a04
Problem: filetype: hip files are not recognized
Solution: Detect *.hip files as hip filetype, include filetype, syntax
and indent plugins, update makemenu.vim and synmenu.vim (Young)
Round out HIP (Heterogeneous-compute Interface for Portability) support
to mirror the existing CUDA files:
- autoload/dist/ft.vim: detect the ".hip" extension as filetype "hip"
- ftplugin/hip.vim: behave like C++ by sourcing ftplugin/cpp.vim
- indent/hip.vim: use cindent, like indent/cuda.vim
- makemenu.vim / synmenu.vim: add a Syntax menu entry
The syntax/hip.vim file already sources syntax/cpp.vim and adds the
HIP-specific keywords, matching syntax/cuda.vim.
closes: vim/vim#20773b3ad239038
Co-authored-by: Young <young20050727@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Problem: Test_spelldump_prefixtree_overflow() resets 'runtimepath' to
defaults, which can expose personal spell files to later tests
(Jun-ichi Takimoto, after v9.2.0662)
Solution: Save and restore the test runner's 'runtimepath' value (coyaSONG).
fixes: vim/vim#20765closes: vim/vim#20766f16e30e19d
Co-authored-by: coyaSONG <66289470+coyaSONG@users.noreply.github.com>
Co-authored-by: OpenAI Codex <noreply@openai.com>
Problem:
Continue separators normalization, and try to keep it at the
nvim <-> external boundary, e.g., `fn.xxx`, `api.xxx`, `:xxx`
Solution:
some key changes
- normalize `$HOME-windows`
- normalize entry points of changing directory
- `nvim_set_current_dir()`, `chdir()`
- normalize the named pipe
- `--listen` arg, `--server` arg, `:restart`
- `serverstart()`, `sockconnect()`, `serverstop()`
- make `expand()` respect 'shellslash' again
- clean up `did_set_shellslash`
- replace `forward_slash` with `TO_SLASH`
- remove obsolete `TMP_PATHSEPSTR`
- remove `slash_adjust` in `do_autocmd_dirchanged`?
- make `fnamemodify()` always return `/` (except when substituting
separators via `:s`, `:gs` ?)
Note:
- these funcs still apply `slash_adjust` on return, as before:
`:pwd`, `chdir()`, `exepath()`, `getcwd()`
- these funcs alwarys return `/`, unlike before the normalization PRs
- `getcompletion()`, `finddir()`, `findfile()`
Also
- clean up code, comments, formatting and tests
- move `TO_SLASH` from `f_chdir` to `changedir_func`
- move `TO_SLASH` from `f_bufadd` to `buflist_new`
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
Problem:
Test_set_cursor is flaky in CI. MsgPack::Raw Perl module
has a heap-overflow issue.
See https://github.com/jacquesg/p5-MsgPack-Raw/issues/4
Solution:
Skip the test until the upstream module is fixed.