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.

Raspunde prin e-mail lui