diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-09-30 06:30:10 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-30 06:30:10 +0800 |
commit | dbfdb52ea867ccd900575bd7dd52a71add7a7346 (patch) | |
tree | 3721bdb1fa1e07a5aca095752a681a1e4b937faa | |
parent | be463e7643fb65c49a9a13bd5a1c6fb6ac34ae77 (diff) | |
download | rneovim-dbfdb52ea867ccd900575bd7dd52a71add7a7346.tar.gz rneovim-dbfdb52ea867ccd900575bd7dd52a71add7a7346.tar.bz2 rneovim-dbfdb52ea867ccd900575bd7dd52a71add7a7346.zip |
vim-patch:9.0.1956: Custom completion skips orig cmdline if it invokes glob() (#25427)
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: vim/vim#13216
https://github.com/vim/vim/commit/28a23602e8f88937645b8506b7915ecea6e09b18
-rw-r--r-- | src/nvim/cmdexpand.c | 28 | ||||
-rw-r--r-- | src/nvim/ex_cmds_defs.h | 1 | ||||
-rw-r--r-- | test/old/testdir/test_cmdline.vim | 16 |
3 files changed, 31 insertions, 14 deletions
diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c index ed693092a1..1fb8018304 100644 --- a/src/nvim/cmdexpand.c +++ b/src/nvim/cmdexpand.c @@ -617,7 +617,7 @@ static void redraw_wildmenu(expand_T *xp, int num_matches, char **matches, int m /// Get the next or prev cmdline completion match. The index of the match is set /// in "xp->xp_selected" -static char *get_next_or_prev_match(int mode, expand_T *xp, char *orig_save) +static char *get_next_or_prev_match(int mode, expand_T *xp) { if (xp->xp_numfiles <= 0) { return NULL; @@ -677,14 +677,14 @@ static char *get_next_or_prev_match(int mode, expand_T *xp, char *orig_save) // 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; @@ -698,7 +698,7 @@ static char *get_next_or_prev_match(int mode, expand_T *xp, char *orig_save) } xp->xp_selected = findex; - return xstrdup(findex == -1 ? orig_save : xp->xp_files[findex]); + return xstrdup(findex == -1 ? xp->xp_orig : xp->xp_files[findex]); } /// Start the command-line expansion and get the matches. @@ -805,8 +805,8 @@ static char *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. @@ -841,21 +841,20 @@ static char *find_longest_match(expand_T *xp, int options) char *ExpandOne(expand_T *xp, char *str, char *orig, int options, int mode) { char *ss = NULL; - static char *orig_save = NULL; // kept value of orig int orig_saved = false; // first handle the case of using an old match if (mode == WILD_NEXT || mode == WILD_PREV || mode == WILD_PAGEUP || mode == WILD_PAGEDOWN || mode == WILD_PUM_WANT) { - return get_next_or_prev_match(mode, xp, orig_save); + return get_next_or_prev_match(mode, xp); } if (mode == WILD_CANCEL) { - ss = xstrdup(orig_save ? orig_save : ""); + ss = xstrdup(xp->xp_orig ? xp->xp_orig : ""); } else if (mode == WILD_APPLY) { ss = xstrdup(xp->xp_selected == -1 - ? (orig_save ? orig_save : "") + ? (xp->xp_orig ? xp->xp_orig : "") : xp->xp_files[xp->xp_selected]); } @@ -863,7 +862,7 @@ char *ExpandOne(expand_T *xp, char *str, char *orig, int options, int mode) if (xp->xp_numfiles != -1 && mode != WILD_ALL && mode != WILD_LONGEST) { FreeWild(xp->xp_numfiles, xp->xp_files); xp->xp_numfiles = -1; - XFREE_CLEAR(orig_save); + XFREE_CLEAR(xp->xp_orig); // The entries from xp_files may be used in the PUM, remove it. if (compl_match_array != NULL) { @@ -877,8 +876,8 @@ char *ExpandOne(expand_T *xp, char *str, char *orig, int options, int mode) } if (xp->xp_numfiles == -1 && mode != WILD_APPLY && mode != WILD_CANCEL) { - xfree(orig_save); - orig_save = orig; + xfree(xp->xp_orig); + xp->xp_orig = orig; orig_saved = true; ss = ExpandOne_start(mode, xp, str, options); @@ -927,7 +926,7 @@ char *ExpandOne(expand_T *xp, char *str, char *orig, int options, int mode) 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) { xfree(orig); } @@ -952,6 +951,7 @@ void ExpandCleanup(expand_T *xp) FreeWild(xp->xp_numfiles, xp->xp_files); xp->xp_numfiles = -1; } + XFREE_CLEAR(xp->xp_orig); } /// Display one line of completion matches. Multiple matches are displayed in diff --git a/src/nvim/ex_cmds_defs.h b/src/nvim/ex_cmds_defs.h index 4280ff70b9..78f880db56 100644 --- a/src/nvim/ex_cmds_defs.h +++ b/src/nvim/ex_cmds_defs.h @@ -245,6 +245,7 @@ struct expand { int xp_numfiles; // number of files found by file name completion int xp_col; // cursor position in line int xp_selected; // selected index in completion + char *xp_orig; // originally expanded string char **xp_files; // list of files char *xp_line; // text being completed #define EXPAND_BUF_LEN 256 diff --git a/test/old/testdir/test_cmdline.vim b/test/old/testdir/test_cmdline.vim index a85c8229af..54f5dd500b 100644 --- a/test/old/testdir/test_cmdline.vim +++ b/test/old/testdir/test_cmdline.vim @@ -3702,4 +3702,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 |