Skip to content

Commit 28a2360

Browse files
zeertzjqchrisbra
authored andcommitted
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 <[email protected]> Co-authored-by: zeertzjq <[email protected]>
1 parent ee865f3 commit 28a2360

4 files changed

Lines changed: 33 additions & 15 deletions

File tree

src/cmdexpand.c

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -696,8 +696,7 @@ win_redr_status_matches(
696696
static char_u *
697697
get_next_or_prev_match(
698698
int mode,
699-
expand_T *xp,
700-
char_u *orig_save)
699+
expand_T *xp)
701700
{
702701
int findex = xp->xp_selected;
703702
int ht;
@@ -757,14 +756,14 @@ get_next_or_prev_match(
757756
// When wrapping around, return the original string, set findex to -1.
758757
if (findex < 0)
759758
{
760-
if (orig_save == NULL)
759+
if (xp->xp_orig == NULL)
761760
findex = xp->xp_numfiles - 1;
762761
else
763762
findex = -1;
764763
}
765764
if (findex >= xp->xp_numfiles)
766765
{
767-
if (orig_save == NULL)
766+
if (xp->xp_orig == NULL)
768767
findex = 0;
769768
else
770769
findex = -1;
@@ -780,7 +779,7 @@ get_next_or_prev_match(
780779
xp->xp_selected = findex;
781780

782781
if (findex == -1)
783-
return vim_strsave(orig_save);
782+
return vim_strsave(xp->xp_orig);
784783

785784
return vim_strsave(xp->xp_files[findex]);
786785
}
@@ -915,8 +914,8 @@ find_longest_match(expand_T *xp, int options)
915914
* Return NULL for failure.
916915
*
917916
* "orig" is the originally expanded string, copied to allocated memory. It
918-
* should either be kept in orig_save or freed. When "mode" is WILD_NEXT or
919-
* WILD_PREV "orig" should be NULL.
917+
* should either be kept in "xp->xp_orig" or freed. When "mode" is WILD_NEXT
918+
* or WILD_PREV "orig" should be NULL.
920919
*
921920
* Results are cached in xp->xp_files and xp->xp_numfiles, except when "mode"
922921
* is WILD_EXPAND_FREE or WILD_ALL.
@@ -956,29 +955,28 @@ ExpandOne(
956955
int mode)
957956
{
958957
char_u *ss = NULL;
959-
static char_u *orig_save = NULL; // kept value of orig
960958
int orig_saved = FALSE;
961959
int i;
962960
long_u len;
963961

964962
// first handle the case of using an old match
965963
if (mode == WILD_NEXT || mode == WILD_PREV
966964
|| mode == WILD_PAGEUP || mode == WILD_PAGEDOWN)
967-
return get_next_or_prev_match(mode, xp, orig_save);
965+
return get_next_or_prev_match(mode, xp);
968966

969967
if (mode == WILD_CANCEL)
970-
ss = vim_strsave(orig_save ? orig_save : (char_u *)"");
968+
ss = vim_strsave(xp->xp_orig ? xp->xp_orig : (char_u *)"");
971969
else if (mode == WILD_APPLY)
972970
ss = vim_strsave(xp->xp_selected == -1
973-
? (orig_save ? orig_save : (char_u *)"")
971+
? (xp->xp_orig ? xp->xp_orig : (char_u *)"")
974972
: xp->xp_files[xp->xp_selected]);
975973

976974
// free old names
977975
if (xp->xp_numfiles != -1 && mode != WILD_ALL && mode != WILD_LONGEST)
978976
{
979977
FreeWild(xp->xp_numfiles, xp->xp_files);
980978
xp->xp_numfiles = -1;
981-
VIM_CLEAR(orig_save);
979+
VIM_CLEAR(xp->xp_orig);
982980

983981
// The entries from xp_files may be used in the PUM, remove it.
984982
if (compl_match_array != NULL)
@@ -991,8 +989,8 @@ ExpandOne(
991989

992990
if (xp->xp_numfiles == -1 && mode != WILD_APPLY && mode != WILD_CANCEL)
993991
{
994-
vim_free(orig_save);
995-
orig_save = orig;
992+
vim_free(xp->xp_orig);
993+
xp->xp_orig = orig;
996994
orig_saved = TRUE;
997995

998996
ss = ExpandOne_start(mode, xp, str, options);
@@ -1045,7 +1043,7 @@ ExpandOne(
10451043
if (mode == WILD_EXPAND_FREE || mode == WILD_ALL)
10461044
ExpandCleanup(xp);
10471045

1048-
// Free "orig" if it wasn't stored in "orig_save".
1046+
// Free "orig" if it wasn't stored in "xp->xp_orig".
10491047
if (!orig_saved)
10501048
vim_free(orig);
10511049

@@ -1075,6 +1073,7 @@ ExpandCleanup(expand_T *xp)
10751073
FreeWild(xp->xp_numfiles, xp->xp_files);
10761074
xp->xp_numfiles = -1;
10771075
}
1076+
VIM_CLEAR(xp->xp_orig);
10781077
}
10791078

10801079
/*

src/structs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,7 @@ typedef struct expand
610610
// file name completion
611611
int xp_col; // cursor position in line
612612
int xp_selected; // selected index in completion
613+
char_u *xp_orig; // originally expanded string
613614
char_u **xp_files; // list of files
614615
char_u *xp_line; // text being completed
615616
#define EXPAND_BUF_LEN 256

src/testdir/test_cmdline.vim

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3549,4 +3549,20 @@ func Test_custom_completion()
35493549
delfunc Check_customlist_completion
35503550
endfunc
35513551

3552+
func Test_custom_completion_with_glob()
3553+
func TestGlobComplete(A, L, P)
3554+
return split(glob('Xglob*'), "\n")
3555+
endfunc
3556+
3557+
command -nargs=* -complete=customlist,TestGlobComplete TestGlobComplete :
3558+
call writefile([], 'Xglob1', 'D')
3559+
call writefile([], 'Xglob2', 'D')
3560+
3561+
call feedkeys(":TestGlobComplete \<Tab> \<Tab>\<C-N> \<Tab>\<C-P>;\<C-B>\"\<CR>", 'xt')
3562+
call assert_equal('"TestGlobComplete Xglob1 Xglob2 ;', @:)
3563+
3564+
delcommand TestGlobComplete
3565+
delfunc TestGlobComplete
3566+
endfunc
3567+
35523568
" vim: shiftwidth=2 sts=2 expandtab

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,8 @@ static char *(features[]) =
699699

700700
static int included_patches[] =
701701
{ /* Add new patch number below this line */
702+
/**/
703+
1956,
702704
/**/
703705
1955,
704706
/**/

0 commit comments

Comments
 (0)