0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

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>
This commit is contained in:
zeertzjq 2023-09-29 19:58:35 +02:00 committed by Christian Brabandt
parent ee865f37ac
commit 28a23602e8
No known key found for this signature in database
GPG Key ID: F3F92DA383FDDE09
4 changed files with 33 additions and 15 deletions

View File

@ -696,8 +696,7 @@ win_redr_status_matches(
static char_u * static char_u *
get_next_or_prev_match( get_next_or_prev_match(
int mode, int mode,
expand_T *xp, expand_T *xp)
char_u *orig_save)
{ {
int findex = xp->xp_selected; int findex = xp->xp_selected;
int ht; int ht;
@ -757,14 +756,14 @@ get_next_or_prev_match(
// When wrapping around, return the original string, set findex to -1. // When wrapping around, return the original string, set findex to -1.
if (findex < 0) if (findex < 0)
{ {
if (orig_save == NULL) if (xp->xp_orig == NULL)
findex = xp->xp_numfiles - 1; findex = xp->xp_numfiles - 1;
else else
findex = -1; findex = -1;
} }
if (findex >= xp->xp_numfiles) if (findex >= xp->xp_numfiles)
{ {
if (orig_save == NULL) if (xp->xp_orig == NULL)
findex = 0; findex = 0;
else else
findex = -1; findex = -1;
@ -780,7 +779,7 @@ get_next_or_prev_match(
xp->xp_selected = findex; xp->xp_selected = findex;
if (findex == -1) if (findex == -1)
return vim_strsave(orig_save); return vim_strsave(xp->xp_orig);
return vim_strsave(xp->xp_files[findex]); return vim_strsave(xp->xp_files[findex]);
} }
@ -915,8 +914,8 @@ find_longest_match(expand_T *xp, int options)
* Return NULL for failure. * Return NULL for failure.
* *
* "orig" is the originally expanded string, copied to allocated memory. It * "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 * should either be kept in "xp->xp_orig" or freed. When "mode" is WILD_NEXT
* WILD_PREV "orig" should be NULL. * or WILD_PREV "orig" should be NULL.
* *
* Results are cached in xp->xp_files and xp->xp_numfiles, except when "mode" * Results are cached in xp->xp_files and xp->xp_numfiles, except when "mode"
* is WILD_EXPAND_FREE or WILD_ALL. * is WILD_EXPAND_FREE or WILD_ALL.
@ -956,7 +955,6 @@ ExpandOne(
int mode) int mode)
{ {
char_u *ss = NULL; char_u *ss = NULL;
static char_u *orig_save = NULL; // kept value of orig
int orig_saved = FALSE; int orig_saved = FALSE;
int i; int i;
long_u len; long_u len;
@ -964,13 +962,13 @@ ExpandOne(
// first handle the case of using an old match // first handle the case of using an old match
if (mode == WILD_NEXT || mode == WILD_PREV if (mode == WILD_NEXT || mode == WILD_PREV
|| mode == WILD_PAGEUP || mode == WILD_PAGEDOWN) || 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) 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) else if (mode == WILD_APPLY)
ss = vim_strsave(xp->xp_selected == -1 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]); : xp->xp_files[xp->xp_selected]);
// free old names // free old names
@ -978,7 +976,7 @@ ExpandOne(
{ {
FreeWild(xp->xp_numfiles, xp->xp_files); FreeWild(xp->xp_numfiles, xp->xp_files);
xp->xp_numfiles = -1; 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. // The entries from xp_files may be used in the PUM, remove it.
if (compl_match_array != NULL) if (compl_match_array != NULL)
@ -991,8 +989,8 @@ ExpandOne(
if (xp->xp_numfiles == -1 && mode != WILD_APPLY && mode != WILD_CANCEL) if (xp->xp_numfiles == -1 && mode != WILD_APPLY && mode != WILD_CANCEL)
{ {
vim_free(orig_save); vim_free(xp->xp_orig);
orig_save = orig; xp->xp_orig = orig;
orig_saved = TRUE; orig_saved = TRUE;
ss = ExpandOne_start(mode, xp, str, options); ss = ExpandOne_start(mode, xp, str, options);
@ -1045,7 +1043,7 @@ ExpandOne(
if (mode == WILD_EXPAND_FREE || mode == WILD_ALL) if (mode == WILD_EXPAND_FREE || mode == WILD_ALL)
ExpandCleanup(xp); 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) if (!orig_saved)
vim_free(orig); vim_free(orig);
@ -1075,6 +1073,7 @@ ExpandCleanup(expand_T *xp)
FreeWild(xp->xp_numfiles, xp->xp_files); FreeWild(xp->xp_numfiles, xp->xp_files);
xp->xp_numfiles = -1; xp->xp_numfiles = -1;
} }
VIM_CLEAR(xp->xp_orig);
} }
/* /*

View File

@ -610,6 +610,7 @@ typedef struct expand
// file name completion // file name completion
int xp_col; // cursor position in line int xp_col; // cursor position in line
int xp_selected; // selected index in completion int xp_selected; // selected index in completion
char_u *xp_orig; // originally expanded string
char_u **xp_files; // list of files char_u **xp_files; // list of files
char_u *xp_line; // text being completed char_u *xp_line; // text being completed
#define EXPAND_BUF_LEN 256 #define EXPAND_BUF_LEN 256

View File

@ -3549,4 +3549,20 @@ func Test_custom_completion()
delfunc Check_customlist_completion delfunc Check_customlist_completion
endfunc 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 " vim: shiftwidth=2 sts=2 expandtab

View File

@ -699,6 +699,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1956,
/**/ /**/
1955, 1955,
/**/ /**/