patch 9.2.0209: freeze during wildmenu completion
Commit:
https://github.com/vim/vim/commit/332dd22ed48244d67524933453049c6c866bcabf
Author: Yasuhiro Matsumoto <[email protected]>
Date: Thu Mar 19 21:59:45 2026 +0000
patch 9.2.0209: freeze during wildmenu completion
Problem: Vim may freeze if setcmdline() is called while the wildmenu or
cmdline popup menu is active (rendcrx)
Solution: Cleanup completion state if cmdbuff_replaced flag has been set
(Yasuhiro Matsumoto)
fixes: #19742
closes: #19744
Co-authored-by: zeertzjq <[email protected]>
Signed-off-by: Yasuhiro Matsumoto <[email protected]>
Signed-off-by: Christian Brabandt <[email protected]>
diff --git a/src/ex_getln.c b/src/ex_getln.c
index ce28088d5..917e67529 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -1899,6 +1899,21 @@ getcmdline_int(
c = safe_vgetc();
} while (c == K_IGNORE || c == K_NOP);
+ // If the cmdline was replaced externally (e.g. by setcmdline()
+ // during an <expr> mapping), clean up the wildmenu completion
+ // state to avoid using stale completion data.
+ if (ccline.cmdbuff_replaced && xpc.xp_numfiles > 0)
+ {
+ if (cmdline_pum_active())
+ cmdline_pum_remove(&ccline, FALSE);
+ (void)ExpandOne(&xpc, NULL, NULL, 0, WILD_FREE);
+ did_wild_list = FALSE;
+ xpc.xp_context = EXPAND_NOTHING;
+ wim_index = 0;
+ wildmenu_cleanup(&ccline);
+ }
+ ccline.cmdbuff_replaced = FALSE;
+
// Skip wildmenu during history navigation via Up/Down keys
if (c == K_WILD && did_hist_navigate)
{
@@ -4518,6 +4533,7 @@ set_cmdline_str(char_u *str, int pos)
p->cmdpos = pos < 0 || pos > p->cmdlen ? p->cmdlen : pos;
new_cmdpos = p->cmdpos;
+ p->cmdbuff_replaced = TRUE;
redrawcmd();
diff --git a/src/structs.h b/src/structs.h
index 2b8cb3db1..0e61aedef 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -716,6 +716,8 @@ typedef struct
char_u *xp_arg; // user-defined expansion arg
int input_fn; // when TRUE Invoked for input()
function
#endif
+ int cmdbuff_replaced; // when TRUE cmdline was replaced
externally
+ // (e.g. by setcmdline())
} cmdline_info_T;
/*
diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim
index 419d48723..2810e0b7e 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -4488,6 +4488,23 @@ func Test_setcmdline()
call feedkeys(":a\<CR>", 'tx')
call assert_equal('let foo=0', @:)
cunmap a
+
+ " setcmdline() during wildmenu completion should not freeze.
+ " Stripping completion state when cmdline was replaced externally.
+ set wildmenu
+ call mkdir('Xsetcmdlinedir', 'pR')
+ call writefile([], 'Xsetcmdlinedir/Xfile1')
+ call writefile([], 'Xsetcmdlinedir/Xfile2')
+ func g:SetCmdLineEmpty()
+ call setcmdline('', 1)
+ return "\<Left>"
+ endfunc
+ cnoremap <expr> a g:SetCmdLineEmpty()
+ call feedkeys(":e Xsetcmdlinedir/\<Tab>a\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"', @:)
+ cunmap a
+ delfunc g:SetCmdLineEmpty
+ set nowildmenu
endfunc
func Test_rulerformat_position()
diff --git a/src/version.c b/src/version.c
index bd95e9e3c..820096693 100644
--- a/src/version.c
+++ b/src/version.c
@@ -734,6 +734,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 209,
/**/
208,
/**/
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/vim_dev/E1w3Ldv-00DkkQ-Ri%40256bit.org.