Mercurial > vim
changeset 33395:55fefd9848e3 v9.0.1956
patch 9.0.1956: Custom completion skips orig cmdline if it invokes glob()
Commit: https://github.com/vim/vim/commit/28a23602e8f88937645b8506b7915ecea6e09b18
Author: zeertzjq <zeertzjq@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 <cb@256bit.org>
Co-authored-by: zeertzjq <zeertzjq@outlook.com>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Fri, 29 Sep 2023 20:15:03 +0200 |
parents | 6abc4476d642 |
children | fd2a38ac6dce |
files | src/cmdexpand.c src/structs.h src/testdir/test_cmdline.vim src/version.c |
diffstat | 4 files changed, 33 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- 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); } /*
--- 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
--- 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 \<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