# HG changeset patch # User Christian Brabandt # Date 1696011303 -7200 # Node ID 55fefd9848e35733fb4b562997bb0aec119a8153 # Parent 6abc4476d642e2ab79072f0dda6ced42087f3a95 patch 9.0.1956: Custom completion skips orig cmdline if it invokes glob() Commit: https://github.com/vim/vim/commit/28a23602e8f88937645b8506b7915ecea6e09b18 Author: zeertzjq 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 Co-authored-by: zeertzjq diff --git a/src/cmdexpand.c b/src/cmdexpand.c --- 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 opt * 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 --- 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 --- 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*'), "\n") + endfunc + + command -nargs=* -complete=customlist,TestGlobComplete TestGlobComplete : + call writefile([], 'Xglob1', 'D') + call writefile([], 'Xglob2', 'D') + + call feedkeys(":TestGlobComplete \ \\ \\;\\"\", '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 --- a/src/version.c +++ b/src/version.c @@ -700,6 +700,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1956, +/**/ 1955, /**/ 1954,