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#19578closes: vim/vim#19581closes: vim/vim#20111c06002f3cb
Co-authored-by: magnus-rattlehead <magnus-rattlehead@users.noreply.github.com>
Problem: off-by-one bug in s:NetrwUnMarkFile()
Solution: Correctly loop through all buffers to unlet all variables
(J. Paulo Seibt)
When the function loops through buffers to clear s:netrwmarkfilelist_#
and s:netrwmarkfilemtch_#, it skips the last one at bufnr('$'), messing
up mark highlights and causing other functions that operate on those
arrays (like delete or rename) to target stale marked files.
The bufnr() help page says that bufnr("$") returns the highest buffer
number of existing buffers, so while ibuf < bufnr("$") does not clear
the last buffer-local arrays.
To reproduce:
Just opening a fresh Vim and running :Ex opens a netrw buffer at the
highest number. Then, typing mu after marking some files triggers the
mark highlight bug, and finally typing D would act like calling the
delete function against the previous marked files, as the buffer-local
arrays where not touched by s:NetrwUnMarkFile.
closes: vim/vim#201297ccc273a4c
Co-authored-by: J. Paulo Seibt <jpseibt@gmail.com>
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#20132closes: vim/vim#20143cf947e7ef0
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
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#2013788fb739918
Co-authored-by: Christian Brabandt <cb@256bit.org>
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>
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#201392bfddbea47
Problem: Test_termdebug_tbreak(), Test_termdebug_basic(), and
Test_termdebug_toggle_break() use synchronous assert_equal()
to check breakpoint signs immediately after sending commands
to gdb. On slow CI (ASAN, ARM64, macOS) gdb may not have
processed the response yet, causing the sign to be missing.
Solution: Wrap the three assertions in WaitForAssert() to poll until
the signs are placed, matching the pattern already used by
the other assertions in the same tests (Jesse Rosenstock).
closes: vim/vim#2013320a124a6e0
Co-authored-by: Jesse Rosenstock <jmr@google.com>
Co-authored-by: Gemini
Problem: termdebug: Need a few more user commands
Solution: Add the :RunOrContinue and the :ToggleBreak user commands
(bennyyip)
closes: vim/vim#18283c975d62473
Co-authored-by: bennyyip <yebenmy@gmail.com>
Problem: Info popup isn't removed when selecting an item that doesn't
have "info" in cmdline completion, which is inconsistent with
Insert mode behavior.
Solution: Set pum_call_update_screen in cmdline mode (zeertzjq).
closes: vim/vim#201283bfffcc290
Nvim already behaves correctly. Add a screen test as there are none.
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#201005c700152ae
Co-authored-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
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>
Problem: tests: Test_shortmess_F3() is flaky on MS-Windows
Solution: Increase the sleep to 3s (Yasuhiro Matsumoto)
On MS-Windows time_differs() treats mtime as unchanged unless st_mtime
differs by more than 1 second, so a 2-second sleep can fall short when
the two writes straddle a second boundary. Bump the non-nanotime sleep
to 3 seconds.
closes: vim/vim#201172219c89013
Co-authored-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Problem: tests: flaky screendump Test_smoothscroll_incsearch()
Solution: Replace screendump test by WaitForAssert()
(Yasuhiro Matsumoto)
VerifyScreenDump fails consistently on the macos-15-intel CI runner.
Replace the dump comparisons with assertions that verify the actual
invariant under test: that the visible buffer view stays unchanged
across the four incremental-search keystrokes (i.e. skipcol is not
reset). Drop the now-unused dump files.
closes: vim/vim#20118e25933014c
Co-authored-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
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`.
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#2005320e98ff1cc
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#18411closes: vim/vim#20090c2bda0add9
Co-authored-by: Maxim Kim <habamax@gmail.com>
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#20085closes: vim/vim#200916453a7c440
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#16551closes: vim/vim#20080af494af5ff
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#20043bd0f3e6da5
Co-authored-by: Luuk van Baal <luukvbaal@gmail.com>
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>
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
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>
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#20078dd9b31fb62
Problem: There is no way to do something on CTRL-Z.
Solution: Add VimSuspend and VimResume autocommand events. (closesvim/vim#7450)
100118c73a
----
Nvim implemented these events first and has enough tests.
test_suspend.vim relies on Vim 'terminal' feature.
Treat it as N/A even if all tests could be ported as Lua functional
screen/terminal tests.
----
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Problem: tests: Test_backupskip() may read from $HOME
Solution: Set $HOME to an empty value, use --clean
(D Ben Knoble)
Even though we unset HOME, we can see via scriptnames that user files
are still sourced! One of my installed plugins warns when not compiled
with +python3, so this test has a "press Enter" prompt.
Use `--clean` like most other GetVimProg()'s do to fix it. Some tests
use `system()` instead, but that turns this test into a failure rather
than passing; I'm not sure why other tests don't suffer from this.
To prove to ourselves, we can use code like this:
diff --git i/src/testdir/test_options.vim w/src/testdir/test_options.vim
index a408e20e1..044364a54 100644
--- i/src/testdir/test_options.vim
+++ w/src/testdir/test_options.vim
@@ -1179,6 +1179,7 @@ func Test_backupskip()
" P_NODUP). Run this in a separate instance and write v:errors in a file,
" so that we see what happens on startup.
let after =<< trim [CODE]
+ call writefile([execute('scriptnames')], 'foo')
let bsklist = split(&backupskip, ',')
call assert_equal(uniq(copy(bsklist)), bsklist)
call writefile(['errors:'] + v:errors, 'Xtestout')
@@ -1196,7 +1197,7 @@ func Test_backupskip()
" unset $HOME, so that it won't try to read init files
let saveenv['HOME'] = getenv("HOME")
call setenv('HOME', v:null)
- exe 'silent !' . cmd
+ exe 'silent !' . cmd .. ' --cmd "echo &rtp"'
call assert_equal(['errors:'], readfile('Xtestout'))
" restore environment variables
Here, that causes "foo" to include a bunch of files under ~/.vim. I'm
not sure why this happens, but lets paper over it for the test.
We can also tell that (orthogonal to --clean) setting HOME='' works too.
Let's do that in addition since unsetting HOME isn't quite enough.
closes: vim/vim#200518d9c383aaf
Co-authored-by: D. Ben Knoble <ben.knoble+github@gmail.com>
Problem: On slow systems tests can be flaky.
Solution: Use TermWait() instead of term-wait(). (Yegappan Lakshmanan,
closesvim/vim#6756)
733d259a83
Co-authored-by: Bram Moolenaar <Bram@vim.org>
* build(vim-patch): test_clientserver.vim is N/A
Requires 'job' and 'clientserver' features.
Both N/A for Neovim.
* build(vim-patch): test_gui_init.vim is N/A
Starts with command 'CheckCanRuiGui' .
Nvim doesn't support ':gui' (yet).
* build(vim-patch): test_plugin_vimball.vim is N/A
Run ':h vimball'.
* build(vim-patch): test_remote.vim is N/A
Needs 'clientserver', 'terminal' features.
* build(vim-patch): test_short_sleep.py is for test_terminal.vim. Both N/A
* build(vim-patch): mark N/A files from test_crypt.vim
* build(vim-patch): mark N/A file for test_terminal3.vim
* build(vim-patch): mark N/A files channel/terminal/vim9 tests
Problem:
On Windows, path separators may become inconsistent for various reasons,
which makes normalization quite painful.
Solution:
Normalize paths to `/` at the entry boundaries and always use it
internally, converting back only in rare cases where `\` is really
needed (e.g. cmd.exe/bat scripts?).
This is the first commit in a series of incremental steps.
Note:
* some funcs won't respect shellslash. e.g. `expand/fnamemodify`
* some funcs still respect shellslash, but will be updated in a follow
PR. e.g. `ex_pwd/f_chdir/f_getcwd`
* uv's built-in funcs always return `\`. e.g. `uv.cwd/uv.exepath`
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
Problem: filetype: some Beancount files are not recognized
Solution: Detect *.bean files as beancount filetype
(Bruno Belanyi)
closes: vim/vim#20037521eac1877
Co-authored-by: Bruno Belanyi <bruno@belanyi.fr>
Problem: runtime(netrw): ~ note expanded on MS Windows
(Tom Vamvanij)
Solution: Expand ~ on MS Windows (Yasuhiro Matsumoto)
On Windows, ":Explore ~" did nothing because the tilde expansion was
gated to Unix/Cygwin only. Additionally, substitute() interprets
backslashes in the replacement string specially (e.g. \U as a case
modifier), which would corrupt $HOME values like C:\Users\name even
if the branch were taken.
Include has("win32") in the guard, anchor the pattern to the start of
the string, and escape backslashes, ampersands and tildes in $HOME
before substituting.
fixes: vim/vim#20003closes: vim/vim#20014723c0acf25
Co-authored-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Problem: runtime(netrw): RFC2396 decoding double escaping spaces
(lilydjwg, after 3e60f03d942d6bb0f7eac)
Solution: Remove escape() call, since we are using fnameescape() anyhow
fixes: vim/vim#19913ab4ebb62ee
Co-authored-by: Christian Brabandt <cb@256bit.org>
Problem: tests: Test_netrw_FileUrlEdit.. fails on Windows
(after 3e60f03d942d6bb0f7)
Solution: Skip the test on Windows (Yasuhiro Matsumoto).
The Test_netrw_FileUrlEdit_pipe_injection() test fails on Windows with
E303 because '|' is not a valid filename character on Windows. Since
the pipe character cannot appear in a Windows filename, the command
injection vector this test guards against does not apply on Windows.
closes: vim/vim#19890c91081d0e5
Co-authored-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Problem: netrw: does not take port into account in hostname validation
(after v9.2.0073)
Solution: Update hostname validation check and test for an optional port
number (Miguel Barro)
closes: vim/vim#19533a6198523fb
Co-authored-by: Miguel Barro <miguel.barro@live.com>
Problem: [security]: Insufficient validation of hostname and port in
netrw URIs allows command injection via shell metacharacters
(ehdgks0627, un3xploitable).
Solution: Implement stricter RFC1123 hostname and IP validation.
Use shellescape() for the provided hostname and port.
Github Advisory:
https://github.com/vim/vim/security/advisories/GHSA-m3xh-9434-g33679348dbbc0
Co-authored-by: Christian Brabandt <cb@256bit.org>
Problem: netrw: need better tests for absolute paths
Solution: Use absolutepath(), instead of regex test (Miguel Barro).
closes: vim/vim#19477bd1dc5b1a6
Cherry-pick a typo fix from latest Vim.
Co-authored-by: Miguel Barro <miguel.barro@live.com>
Problem: Cannot apply 'scrolloff' context lines at end of file
Solution: Add the 'scrolloffpad' option to keep 'scrolloff' context even
when at the end of the file (McAuley Penney).
closes: vim/vim#19040a414630393
Co-authored-by: McAuley Penney <jacobmpenney@gmail.com>
Problem: Integer overflow with "ze" and large 'sidescrolloff'.
Solution: Check for overflow to avoid negative w_leftcol (zeertzjq).
closes: vim/vim#2002633f3965087
vim-patch:9.2.0384: stale Insstart after <Cmd> cursor move breaks undo
Problem: A <Cmd> command executed from Insert mode can sync undo and
move the cursor before the next edit. stop_arrow() saved the
new cursor line for undo, but left Insstart at the previous
insertion point. A line-start backspace could then delete
lines above the saved line without saving the joined range,
leaving a pending undo entry whose bottom resolved above
its top and raising E340.
Solution: Update Insstart and Insstart_textlen after the pending undo
save so the next edit starts from the command-updated cursor
position (Jaehwang Jung).
closes: vim/vim#20031
AI-assisted: Codex
d4fb31762e
Co-authored-by: Jaehwang Jung <tomtomjhj@gmail.com>
vim-patch:9.2.0374: c_CTRL-{G,T} does not handle offset
Problem: c_CTRL-{G,T} does not handle offset, when cycling between
matches
Solution: Refactor parsing logic into parse_search_pattern_offset() and
handle offsets, note: highlighting does not handle offsets
yet (Barrett Ruth).
fixes: vim/vim#19991closes: vim/vim#19998c62342e5cf
Problem: The "Scanning:" completion, bufwrite, and indent (there may be
more) messages which indicate progress can use the "progress" kind
for their msg_show event. Indent message does not have a kind.
Solution: Emit these messages with the "progress" kind. Set the message id
to the replaced kind so that a UI knows to replace it (and to provide
a migration path in case a UI was distinguishing these messages for
whatever reason).
Problem: filetype: ghostty config files are not recognized
Solution: Detect ghostty configuration files as ghostty filetype,
include a simple ghostty filetype plugin (Bez Hermoso)
closes: vim/vim#20002b30803b231
Co-authored-by: Bez Hermoso <bezalelhermoso@gmail.com>
Co-authored-by: Christian Brabandt <cb@256bit.org>
Problem: Ctrl-R mapping not triggered during completion.
Solution: Move Ctrl-R check out of vim_is_ctrl_x_key()
(zeertzjq).
fixes: vim/vim#20004closes: vim/vim#2000649e8630a28
vim-patch:9.2.0362: division by zero with smoothscroll and small windows
Problem: Resizing a smoothscrolled wrapped window to its textoff width
with 'showbreak' can leave wrapped continuation lines with
zero text width. win_lbr_chartabsize() still runs the partial max_head_vcol calculation in
that state and divides by width2, crashing during redraw.
Solution: Skip that partial head calculation when the wrapped
continuation width is zero, matching the other width2 guards
in charset.c (Jaehwang Jung)
closes: vim/vim#20012
AI-assisted: Codex
0e31fb024c