mirror of
https://github.com/vim/vim.git
synced 2026-05-28 00:21:37 +02:00
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 <zeertzjq@outlook.com>
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
67ae763557
commit
332dd22ed4
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
/*
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -734,6 +734,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
209,
|
||||
/**/
|
||||
208,
|
||||
/**/
|
||||
|
||||
Reference in New Issue
Block a user