patch 9.0.1956: Custom completion skips orig cmdline if it invokes glob()

Commit: 
https://github.com/vim/vim/commit/28a23602e8f88937645b8506b7915ecea6e09b18
Author: zeertzjq <zeert...@outlook.com>
Date:   Fri Sep 29 19:58:35 2023 +0200

    patch 9.0.1956: Custom completion skips orig cmdline if it invokes glob()
    
    Problem:  Custom cmdline completion skips original cmdline when pressing
              Ctrl-P at first match if completion function invokes glob().
    Solution: Move orig_save into struct expand_T.
    
    closes: #13216
    
    Signed-off-by: Christian Brabandt <c...@256bit.org>
    Co-authored-by: zeertzjq <zeert...@outlook.com>

diff --git a/src/cmdexpand.c b/src/cmdexpand.c
index e5b96fbe9..40778cc21 100644
--- a/src/cmdexpand.c
+++ b/src/cmdexpand.c
@@ -696,8 +696,7 @@ win_redr_status_matches(
     static char_u *
 get_next_or_prev_match(
        int             mode,
-       expand_T        *xp,
-       char_u          *orig_save)
+       expand_T        *xp)
 {
     int findex = xp->xp_selected;
     int ht;
@@ -757,14 +756,14 @@ get_next_or_prev_match(
     // When wrapping around, return the original string, set findex to -1.
     if (findex < 0)
     {
-       if (orig_save == NULL)
+       if (xp->xp_orig == NULL)
            findex = xp->xp_numfiles - 1;
        else
            findex = -1;
     }
     if (findex >= xp->xp_numfiles)
     {
-       if (orig_save == NULL)
+       if (xp->xp_orig == NULL)
            findex = 0;
        else
            findex = -1;
@@ -780,7 +779,7 @@ get_next_or_prev_match(
     xp->xp_selected = findex;
 
     if (findex == -1)
-       return vim_strsave(orig_save);
+       return vim_strsave(xp->xp_orig);
 
     return vim_strsave(xp->xp_files[findex]);
 }
@@ -915,8 +914,8 @@ find_longest_match(expand_T *xp, int options)
  * Return NULL for failure.
  *
  * "orig" is the originally expanded string, copied to allocated memory.  It
- * should either be kept in orig_save or freed.  When "mode" is WILD_NEXT or
- * WILD_PREV "orig" should be NULL.
+ * should either be kept in "xp->xp_orig" or freed.  When "mode" is WILD_NEXT
+ * or WILD_PREV "orig" should be NULL.
  *
  * Results are cached in xp->xp_files and xp->xp_numfiles, except when "mode"
  * is WILD_EXPAND_FREE or WILD_ALL.
@@ -956,7 +955,6 @@ ExpandOne(
     int                mode)
 {
     char_u     *ss = NULL;
-    static char_u *orig_save = NULL;   // kept value of orig
     int                orig_saved = FALSE;
     int                i;
     long_u     len;
@@ -964,13 +962,13 @@ ExpandOne(
     // first handle the case of using an old match
     if (mode == WILD_NEXT || mode == WILD_PREV
            || mode == WILD_PAGEUP || mode == WILD_PAGEDOWN)
-       return get_next_or_prev_match(mode, xp, orig_save);
+       return get_next_or_prev_match(mode, xp);
 
     if (mode == WILD_CANCEL)
-       ss = vim_strsave(orig_save ? orig_save : (char_u *)"");
+       ss = vim_strsave(xp->xp_orig ? xp->xp_orig : (char_u *)"");
     else if (mode == WILD_APPLY)
        ss = vim_strsave(xp->xp_selected == -1
-                           ? (orig_save ? orig_save : (char_u *)"")
+                           ? (xp->xp_orig ? xp->xp_orig : (char_u *)"")
                            : xp->xp_files[xp->xp_selected]);
 
     // free old names
@@ -978,7 +976,7 @@ ExpandOne(
     {
        FreeWild(xp->xp_numfiles, xp->xp_files);
        xp->xp_numfiles = -1;
-       VIM_CLEAR(orig_save);
+       VIM_CLEAR(xp->xp_orig);
 
        // The entries from xp_files may be used in the PUM, remove it.
        if (compl_match_array != NULL)
@@ -991,8 +989,8 @@ ExpandOne(
 
     if (xp->xp_numfiles == -1 && mode != WILD_APPLY && mode != WILD_CANCEL)
     {
-       vim_free(orig_save);
-       orig_save = orig;
+       vim_free(xp->xp_orig);
+       xp->xp_orig = orig;
        orig_saved = TRUE;
 
        ss = ExpandOne_start(mode, xp, str, options);
@@ -1045,7 +1043,7 @@ ExpandOne(
     if (mode == WILD_EXPAND_FREE || mode == WILD_ALL)
        ExpandCleanup(xp);
 
-    // Free "orig" if it wasn't stored in "orig_save".
+    // Free "orig" if it wasn't stored in "xp->xp_orig".
     if (!orig_saved)
        vim_free(orig);
 
@@ -1075,6 +1073,7 @@ ExpandCleanup(expand_T *xp)
        FreeWild(xp->xp_numfiles, xp->xp_files);
        xp->xp_numfiles = -1;
     }
+    VIM_CLEAR(xp->xp_orig);
 }
 
 /*
diff --git a/src/structs.h b/src/structs.h
index 9813c4e94..d718efec2 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -610,6 +610,7 @@ typedef struct expand
                                        // file name completion
     int                xp_col;                 // cursor position in line
     int                xp_selected;            // selected index in completion
+    char_u     *xp_orig;               // originally expanded string
     char_u     **xp_files;             // list of files
     char_u     *xp_line;               // text being completed
 #define EXPAND_BUF_LEN 256
diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim
index b2566cdfb..a54c50738 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -3549,4 +3549,20 @@ func Test_custom_completion()
   delfunc Check_customlist_completion
 endfunc
 
+func Test_custom_completion_with_glob()
+  func TestGlobComplete(A, L, P)
+    return split(glob('Xglob*'), "
")
+  endfunc
+
+  command -nargs=* -complete=customlist,TestGlobComplete TestGlobComplete :
+  call writefile([], 'Xglob1', 'D')
+  call writefile([], 'Xglob2', 'D')
+
+  call feedkeys(":TestGlobComplete \<Tab> \<Tab>\<C-N> 
\<Tab>\<C-P>;\<C-B>\"\<CR>", 'xt')
+  call assert_equal('"TestGlobComplete Xglob1 Xglob2 ;', @:)
+
+  delcommand TestGlobComplete
+  delfunc TestGlobComplete
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index da13c18e1..3165cef29 100644
--- a/src/version.c
+++ b/src/version.c
@@ -699,6 +699,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1956,
 /**/
     1955,
 /**/

-- 
-- 
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 vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/E1qmI11-00HWOE-LV%40256bit.org.

Raspunde prin e-mail lui