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.