summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-09-29 19:58:35 +0200
committerChristian Brabandt <cb@256bit.org>2023-09-29 19:58:35 +0200
commit28a23602e8f88937645b8506b7915ecea6e09b18 (patch)
tree83677a9ee654a632ae39646e12f8adc9d91d6a24
parentee865f37acab6cac2cee6a171d60e1b365f852b0 (diff)
patch 9.0.1956: Custom completion skips orig cmdline if it invokes glob()v9.0.1956
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>
-rw-r--r--src/cmdexpand.c29
-rw-r--r--src/structs.h1
-rw-r--r--src/testdir/test_cmdline.vim16
-rw-r--r--src/version.c2
4 files changed, 33 insertions, 15 deletions
diff --git a/src/cmdexpand.c b/src/cmdexpand.c
index e5b96fbe9c..40778cc219 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 9813c4e94d..d718efec2c 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 b2566cdfb1..a54c507387 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*'), "\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
diff --git a/src/version.c b/src/version.c
index da13c18e1d..3165cef295 100644
--- a/src/version.c
+++ b/src/version.c
@@ -700,6 +700,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1956,
+/**/
1955,
/**/
1954,