summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-10-28 22:05:26 +0100
committerChristian Brabandt <cb@256bit.org>2024-10-28 22:05:26 +0100
commit20e045f78148c0ef0143c33ffe686fee72d29376 (patch)
tree6429282d46880d3a57b574ed8f3370c9ce62cade
parentbaab7c08653a4e1b7227d6426d96cab030ccf9e8 (diff)
patch 9.1.0821: 'findexpr' completion doesn't set v:fname to cmdline argumentv9.1.0821
Problem: 'findexpr' completion doesn't set v:fname to cmdline argument. Solution: Set v:fname to the cmdline argument as-is (zeertzjq). closes: #15934 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
-rw-r--r--runtime/doc/eval.txt7
-rw-r--r--runtime/doc/options.txt9
-rw-r--r--runtime/doc/tags2
-rw-r--r--src/cmdexpand.c10
-rw-r--r--src/errors.h2
-rw-r--r--src/evalvars.c2
-rw-r--r--src/ex_docmd.c20
-rw-r--r--src/testdir/test_findfile.vim55
-rw-r--r--src/version.c2
-rw-r--r--src/vim.h4
10 files changed, 75 insertions, 38 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 80ccce8f69..027cf08c5b 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1,4 +1,4 @@
-*eval.txt* For Vim version 9.1. Last change: 2024 Oct 22
+*eval.txt* For Vim version 9.1. Last change: 2024 Oct 28
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -2026,6 +2026,11 @@ v:cmdbang Set like v:cmdarg for a file read/write command. When a "!"
was used the value is 1, otherwise it is 0. Note that this
can only be used in autocommands. For user commands |<bang>|
can be used.
+
+ *v:cmdcomplete* *cmdcomplete-variable*
+v:cmdcomplete When evaluating 'findexpr': if 'findexpr' is used for cmdline
+ completion the value is |v:true|, otherwise it is |v:false|.
+
*v:collate* *collate-variable*
v:collate The current locale setting for collation order of the runtime
environment. This allows Vim scripts to be aware of the
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 229ce13fd3..e221fe3e29 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt* For Vim version 9.1. Last change: 2024 Oct 22
+*options.txt* For Vim version 9.1. Last change: 2024 Oct 28
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -3567,6 +3567,10 @@ A jump table for the options with a short description can be found at |Q_op|.
The expression is evaluated only once per |:find| command invocation.
The expression can process all the directories specified in 'path'.
+ The expression may be evaluated for command-line completion as well,
+ in which case the |v:cmdcomplete| variable will be set to |v:true|,
+ otherwise it will be set to |v:false|.
+
If a match is found, the expression should return a |List| containing
one or more file names. If a match is not found, the expression
should return an empty List.
@@ -3586,7 +3590,8 @@ A jump table for the options with a short description can be found at |Q_op|.
>
" Use glob()
func FindExprGlob()
- return glob(v:fname, v:false, v:true)
+ let pat = v:cmdcomplete ? $'{v:fname}*' : v:fname
+ return glob(pat, v:false, v:true)
endfunc
set findexpr=FindExprGlob()
diff --git a/runtime/doc/tags b/runtime/doc/tags
index 9e93a75389..886b28c987 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -6510,6 +6510,7 @@ close_cb channel.txt /*close_cb*
closure eval.txt /*closure*
cmdarg-variable eval.txt /*cmdarg-variable*
cmdbang-variable eval.txt /*cmdbang-variable*
+cmdcomplete-variable eval.txt /*cmdcomplete-variable*
cmdline-arguments vi_diff.txt /*cmdline-arguments*
cmdline-changed version5.txt /*cmdline-changed*
cmdline-completion cmdline.txt /*cmdline-completion*
@@ -10933,6 +10934,7 @@ v:charconvert_from eval.txt /*v:charconvert_from*
v:charconvert_to eval.txt /*v:charconvert_to*
v:cmdarg eval.txt /*v:cmdarg*
v:cmdbang eval.txt /*v:cmdbang*
+v:cmdcomplete eval.txt /*v:cmdcomplete*
v:collate eval.txt /*v:collate*
v:colornames eval.txt /*v:colornames*
v:completed_item eval.txt /*v:completed_item*
diff --git a/src/cmdexpand.c b/src/cmdexpand.c
index 406135cffb..3862d69eda 100644
--- a/src/cmdexpand.c
+++ b/src/cmdexpand.c
@@ -50,6 +50,7 @@ cmdline_fuzzy_completion_supported(expand_T *xp)
&& xp->xp_context != EXPAND_FILES
&& xp->xp_context != EXPAND_FILES_IN_PATH
&& xp->xp_context != EXPAND_FILETYPE
+ && xp->xp_context != EXPAND_FINDEXPR
&& xp->xp_context != EXPAND_HELP
&& xp->xp_context != EXPAND_KEYMAP
&& xp->xp_context != EXPAND_OLD_SETTING
@@ -1418,7 +1419,8 @@ addstar(
// For help tags the translation is done in find_help_tags().
// For a tag pattern starting with "/" no translation is needed.
- if (context == EXPAND_HELP
+ if (context == EXPAND_FINDEXPR
+ || context == EXPAND_HELP
|| context == EXPAND_COLORS
|| context == EXPAND_COMPILER
|| context == EXPAND_OWNSYNTAX
@@ -2138,7 +2140,8 @@ set_context_by_cmdname(
case CMD_sfind:
case CMD_tabfind:
if (xp->xp_context == EXPAND_FILES)
- xp->xp_context = EXPAND_FILES_IN_PATH;
+ xp->xp_context = *get_findexpr() != NUL ? EXPAND_FINDEXPR
+ : EXPAND_FILES_IN_PATH;
break;
case CMD_cd:
case CMD_chdir:
@@ -2850,7 +2853,7 @@ expand_files_and_dirs(
}
}
- if (xp->xp_context == EXPAND_FILES_IN_PATH && *get_findexpr() != NUL)
+ if (xp->xp_context == EXPAND_FINDEXPR)
{
#ifdef FEAT_EVAL
ret = expand_findexpr(pat, matches, numMatches);
@@ -3119,6 +3122,7 @@ ExpandFromContext(
if (xp->xp_context == EXPAND_FILES
|| xp->xp_context == EXPAND_DIRECTORIES
|| xp->xp_context == EXPAND_FILES_IN_PATH
+ || xp->xp_context == EXPAND_FINDEXPR
|| xp->xp_context == EXPAND_DIRS_IN_CDPATH)
return expand_files_and_dirs(xp, pat, matches, numMatches, flags,
options);
diff --git a/src/errors.h b/src/errors.h
index 2299f2c50c..6c172e09c0 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -3653,4 +3653,4 @@ EXTERN char e_wrong_character_width_for_field_str[]
EXTERN char e_winfixbuf_cannot_go_to_buffer[]
INIT(= N_("E1513: Cannot switch buffer. 'winfixbuf' is enabled"));
EXTERN char e_invalid_return_type_from_findexpr[]
- INIT(= N_("E1514: findexpr did not return a List type"));
+ INIT(= N_("E1514: 'findexpr' did not return a List type"));
diff --git a/src/evalvars.c b/src/evalvars.c
index f18b51637b..9f03ada09a 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -161,6 +161,7 @@ static struct vimvar
{VV_NAME("t_typealias", VAR_NUMBER), NULL, VV_RO},
{VV_NAME("t_enum", VAR_NUMBER), NULL, VV_RO},
{VV_NAME("t_enumvalue", VAR_NUMBER), NULL, VV_RO},
+ {VV_NAME("cmdcomplete", VAR_BOOL), NULL, VV_RO},
};
// shorthand
@@ -234,6 +235,7 @@ evalvars_init(void)
set_vim_var_nr(VV_SEARCHFORWARD, 1L);
set_vim_var_nr(VV_HLSEARCH, 1L);
set_vim_var_nr(VV_EXITING, VVAL_NULL);
+ set_vim_var_nr(VV_CMDCOMPLETE, VVAL_FALSE);
set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc_lock(VAR_FIXED));
set_vim_var_list(VV_ERRORS, list_alloc());
set_vim_var_dict(VV_EVENT, dict_alloc_lock(VAR_FIXED));
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index fa370fefc9..807b470d8b 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -6929,7 +6929,7 @@ ex_wrongmodifier(exarg_T *eap)
* the expression, v:fname is set to the ":find" command argument.
*/
static list_T *
-eval_findexpr(char_u *ptr)
+eval_findexpr(char_u *pat, int cmdcomplete)
{
sctx_T saved_sctx = current_sctx;
char_u *findexpr;
@@ -6939,7 +6939,8 @@ eval_findexpr(char_u *ptr)
findexpr = get_findexpr();
- set_vim_var_string(VV_FNAME, ptr, -1);
+ set_vim_var_string(VV_FNAME, pat, -1);
+ set_vim_var_nr(VV_CMDCOMPLETE, cmdcomplete ? VVAL_TRUE : VVAL_FALSE);
current_sctx = curbuf->b_p_script_ctx[BV_FEXPR];
arg = skipwhite(findexpr);
@@ -6962,6 +6963,7 @@ eval_findexpr(char_u *ptr)
clear_evalarg(&EVALARG_EVALUATE, NULL);
set_vim_var_string(VV_FNAME, NULL, 0);
+ set_vim_var_nr(VV_CMDCOMPLETE, VVAL_FALSE);
current_sctx = saved_sctx;
return retlist;
@@ -6977,21 +6979,11 @@ expand_findexpr(char_u *pat, char_u ***files, int *numMatches)
{
list_T *l;
int len;
- char_u *regpat;
*numMatches = 0;
*files = NULL;
- // File name expansion uses wildchars. But the 'findexpr' expression
- // expects a regular expression argument. So convert wildchars in the
- // argument to regular expression patterns.
- regpat = file_pat_to_reg_pat(pat, NULL, NULL, FALSE);
- if (regpat == NULL)
- return FAIL;
-
- l = eval_findexpr(regpat);
-
- vim_free(regpat);
+ l = eval_findexpr(pat, TRUE);
if (l == NULL)
return FAIL;
@@ -7037,7 +7029,7 @@ findexpr_find_file(char_u *findarg, int findarg_len, int count)
cc = findarg[findarg_len];
findarg[findarg_len] = NUL;
- fname_list = eval_findexpr(findarg);
+ fname_list = eval_findexpr(findarg, FALSE);
fname_count = list_len(fname_list);
if (fname_count == 0)
diff --git a/src/testdir/test_findfile.vim b/src/testdir/test_findfile.vim
index 3a1066bf31..25cd9daa7b 100644
--- a/src/testdir/test_findfile.vim
+++ b/src/testdir/test_findfile.vim
@@ -374,7 +374,7 @@ func Test_findexpr()
" Expression returning a string
set findexpr='abc'
- call assert_fails('find Xfindexpr1.c', 'E1514: findexpr did not return a List type')
+ call assert_fails('find Xfindexpr1.c', "E1514: 'findexpr' did not return a List type")
set findexpr&
delfunc! FindExpr1
@@ -454,29 +454,52 @@ endfunc
" Test for expanding the argument to the :find command using 'findexpr'
func Test_findexpr_expand_arg()
- func FindExpr1()
- let fnames = ['Xfindexpr1.c', 'Xfindexpr2.c', 'Xfindexpr3.c']
- return fnames->copy()->filter('v:val =~? v:fname')
+ let s:fnames = ['Xfindexpr1.c', 'Xfindexpr2.c', 'Xfindexpr3.c']
+
+ " 'findexpr' that accepts a regular expression
+ func FindExprRegexp()
+ return s:fnames->copy()->filter('v:val =~? v:fname')
endfunc
- set findexpr=FindExpr1()
- call feedkeys(":find \<Tab>\<C-B>\"\<CR>", "xt")
- call assert_equal('"find Xfindexpr1.c', @:)
+ " 'findexpr' that accepts a glob
+ func FindExprGlob()
+ let pat = glob2regpat(v:cmdcomplete ? $'*{v:fname}*' : v:fname)
+ return s:fnames->copy()->filter('v:val =~? pat')
+ endfunc
+
+ for regexp in [v:true, v:false]
+ let &findexpr = regexp ? 'FindExprRegexp()' : 'FindExprGlob()'
+
+ call feedkeys(":find \<Tab>\<C-B>\"\<CR>", "xt")
+ call assert_equal('"find Xfindexpr1.c', @:)
+
+ call feedkeys(":find Xfind\<Tab>\<Tab>\<C-B>\"\<CR>", "xt")
+ call assert_equal('"find Xfindexpr2.c', @:)
- call feedkeys(":find Xfind\<Tab>\<Tab>\<C-B>\"\<CR>", "xt")
- call assert_equal('"find Xfindexpr2.c', @:)
+ call assert_equal(s:fnames, getcompletion('find ', 'cmdline'))
+ call assert_equal(s:fnames, getcompletion('find Xfind', 'cmdline'))
- call feedkeys(":find *3*\<Tab>\<C-B>\"\<CR>", "xt")
- call assert_equal('"find Xfindexpr3.c', @:)
+ let pat = regexp ? 'X.*1\.c' : 'X*1.c'
+ call feedkeys($":find {pat}\<Tab>\<C-B>\"\<CR>", "xt")
+ call assert_equal('"find Xfindexpr1.c', @:)
+ call assert_equal(['Xfindexpr1.c'], getcompletion($'find {pat}', 'cmdline'))
- call feedkeys(":find Xfind\<C-A>\<C-B>\"\<CR>", "xt")
- call assert_equal('"find Xfindexpr1.c Xfindexpr2.c Xfindexpr3.c', @:)
+ call feedkeys(":find 3\<Tab>\<C-B>\"\<CR>", "xt")
+ call assert_equal('"find Xfindexpr3.c', @:)
+ call assert_equal(['Xfindexpr3.c'], getcompletion($'find 3', 'cmdline'))
- call feedkeys(":find abc\<Tab>\<C-B>\"\<CR>", "xt")
- call assert_equal('"find abc', @:)
+ call feedkeys(":find Xfind\<C-A>\<C-B>\"\<CR>", "xt")
+ call assert_equal('"find Xfindexpr1.c Xfindexpr2.c Xfindexpr3.c', @:)
+
+ call feedkeys(":find abc\<Tab>\<C-B>\"\<CR>", "xt")
+ call assert_equal('"find abc', @:)
+ call assert_equal([], getcompletion('find abc', 'cmdline'))
+ endfor
set findexpr&
- delfunc! FindExpr1
+ delfunc! FindExprRegexp
+ delfunc! FindExprGlob
+ unlet s:fnames
endfunc
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index e042965678..6abc802840 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 821,
+/**/
820,
/**/
819,
diff --git a/src/vim.h b/src/vim.h
index 74e6b95435..f4acaf92fa 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -845,6 +845,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
#define EXPAND_KEYMAP 58
#define EXPAND_DIRS_IN_CDPATH 59
#define EXPAND_SHELLCMDLINE 60
+#define EXPAND_FINDEXPR 61
// Values for exmode_active (0 is no exmode)
@@ -2188,7 +2189,8 @@ typedef int sock_T;
#define VV_TYPE_TYPEALIAS 107
#define VV_TYPE_ENUM 108
#define VV_TYPE_ENUMVALUE 109
-#define VV_LEN 110 // number of v: vars
+#define VV_CMDCOMPLETE 110
+#define VV_LEN 111 // number of v: vars
// used for v_number in VAR_BOOL and VAR_SPECIAL
#define VVAL_FALSE 0L // VAR_BOOL