mirror of
https://github.com/neovim/neovim.git
synced 2025-10-05 09:26:30 +00:00
vim-patch:9.1.0831: 'findexpr' can't be used as lambad or Funcref (#31058)
Problem: 'findexpr' can't be used for lambads
(Justin Keyes)
Solution: Replace the findexpr option with the findfunc option
(Yegappan Lakshmanan)
related: vim/vim#15905
closes: vim/vim#15976
a13f3a4f5d
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
This commit is contained in:
@@ -2049,7 +2049,6 @@ void free_buf_options(buf_T *buf, bool free_p_ff)
|
||||
clear_string_option(&buf->b_p_indk);
|
||||
clear_string_option(&buf->b_p_fp);
|
||||
clear_string_option(&buf->b_p_fex);
|
||||
clear_string_option(&buf->b_p_fexpr);
|
||||
clear_string_option(&buf->b_p_kp);
|
||||
clear_string_option(&buf->b_p_mps);
|
||||
clear_string_option(&buf->b_p_fo);
|
||||
@@ -2098,6 +2097,8 @@ void free_buf_options(buf_T *buf, bool free_p_ff)
|
||||
clear_string_option(&buf->b_p_tc);
|
||||
clear_string_option(&buf->b_p_tfu);
|
||||
callback_free(&buf->b_tfu_cb);
|
||||
clear_string_option(&buf->b_p_ffu);
|
||||
callback_free(&buf->b_ffu_cb);
|
||||
clear_string_option(&buf->b_p_dict);
|
||||
clear_string_option(&buf->b_p_tsr);
|
||||
clear_string_option(&buf->b_p_qe);
|
||||
|
@@ -543,8 +543,10 @@ struct file_buffer {
|
||||
Callback b_cfu_cb; ///< 'completefunc' callback
|
||||
char *b_p_ofu; ///< 'omnifunc'
|
||||
Callback b_ofu_cb; ///< 'omnifunc' callback
|
||||
char *b_p_tfu; ///< 'tagfunc'
|
||||
char *b_p_tfu; ///< 'tagfunc' option value
|
||||
Callback b_tfu_cb; ///< 'tagfunc' callback
|
||||
char *b_p_ffu; ///< 'findfunc' option value
|
||||
Callback b_ffu_cb; ///< 'findfunc' callback
|
||||
int b_p_eof; ///< 'endoffile'
|
||||
int b_p_eol; ///< 'endofline'
|
||||
int b_p_fixeol; ///< 'fixendofline'
|
||||
@@ -608,7 +610,6 @@ struct file_buffer {
|
||||
char *b_p_mp; ///< 'makeprg' local value
|
||||
char *b_p_efm; ///< 'errorformat' local value
|
||||
char *b_p_ep; ///< 'equalprg' local value
|
||||
char *b_p_fexpr; ///< 'findexpr' local value
|
||||
char *b_p_path; ///< 'path' local value
|
||||
int b_p_ar; ///< 'autoread' local value
|
||||
char *b_p_tags; ///< 'tags' local value
|
||||
|
@@ -109,7 +109,7 @@ static bool cmdline_fuzzy_completion_supported(const expand_T *const 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_FINDFUNC
|
||||
&& xp->xp_context != EXPAND_HELP
|
||||
&& xp->xp_context != EXPAND_KEYMAP
|
||||
&& xp->xp_context != EXPAND_LUA
|
||||
@@ -1229,7 +1229,7 @@ char *addstar(char *fname, size_t len, int context)
|
||||
|
||||
// For help tags the translation is done in find_help_tags().
|
||||
// For a tag pattern starting with "/" no translation is needed.
|
||||
if (context == EXPAND_FINDEXPR
|
||||
if (context == EXPAND_FINDFUNC
|
||||
|| context == EXPAND_HELP
|
||||
|| context == EXPAND_COLORS
|
||||
|| context == EXPAND_COMPILER
|
||||
@@ -1829,7 +1829,7 @@ static const char *set_context_by_cmdname(const char *cmd, cmdidx_T cmdidx, expa
|
||||
case CMD_sfind:
|
||||
case CMD_tabfind:
|
||||
if (xp->xp_context == EXPAND_FILES) {
|
||||
xp->xp_context = *get_findexpr() != NUL ? EXPAND_FINDEXPR : EXPAND_FILES_IN_PATH;
|
||||
xp->xp_context = *get_findfunc() != NUL ? EXPAND_FINDFUNC : EXPAND_FILES_IN_PATH;
|
||||
}
|
||||
break;
|
||||
case CMD_cd:
|
||||
@@ -2500,8 +2500,8 @@ static int expand_files_and_dirs(expand_T *xp, char *pat, char ***matches, int *
|
||||
}
|
||||
|
||||
int ret = FAIL;
|
||||
if (xp->xp_context == EXPAND_FINDEXPR) {
|
||||
ret = expand_findexpr(pat, matches, numMatches);
|
||||
if (xp->xp_context == EXPAND_FINDFUNC) {
|
||||
ret = expand_findfunc(pat, matches, numMatches);
|
||||
} else {
|
||||
if (xp->xp_context == EXPAND_FILES) {
|
||||
flags |= EW_FILE;
|
||||
@@ -2722,7 +2722,7 @@ static int ExpandFromContext(expand_T *xp, char *pat, char ***matches, int *numM
|
||||
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_FINDFUNC
|
||||
|| xp->xp_context == EXPAND_DIRS_IN_CDPATH) {
|
||||
return expand_files_and_dirs(xp, pat, matches, numMatches, flags, options);
|
||||
}
|
||||
|
@@ -107,7 +107,7 @@ enum {
|
||||
EXPAND_KEYMAP,
|
||||
EXPAND_DIRS_IN_CDPATH,
|
||||
EXPAND_SHELLCMDLINE,
|
||||
EXPAND_FINDEXPR,
|
||||
EXPAND_FINDFUNC,
|
||||
EXPAND_CHECKHEALTH,
|
||||
EXPAND_LUA,
|
||||
};
|
||||
|
@@ -186,7 +186,7 @@ INIT(= N_("E5767: Cannot use :undo! to redo or move to a different undo branch")
|
||||
|
||||
EXTERN const char e_winfixbuf_cannot_go_to_buffer[]
|
||||
INIT(= N_("E1513: Cannot switch buffer. 'winfixbuf' is enabled"));
|
||||
EXTERN const char e_invalid_return_type_from_findexpr[] INIT( = N_("E1514: 'findexpr' did not return a List type"));
|
||||
EXTERN const char e_invalid_return_type_from_findfunc[] INIT( = N_("E1514: 'findfunc' did not return a List type"));
|
||||
|
||||
EXTERN const char e_trustfile[] INIT(= N_("E5570: Cannot update trust file: %s"));
|
||||
|
||||
|
@@ -270,7 +270,6 @@ static struct vimvar {
|
||||
VV(VV_COLLATE, "collate", VAR_STRING, VV_RO),
|
||||
VV(VV_EXITING, "exiting", VAR_NUMBER, VV_RO),
|
||||
VV(VV_MAXCOL, "maxcol", VAR_NUMBER, VV_RO),
|
||||
VV(VV_CMDCOMPLETE, "cmdcomplete", VAR_BOOL, VV_RO),
|
||||
// Neovim
|
||||
VV(VV_STDERR, "stderr", VAR_NUMBER, VV_RO),
|
||||
VV(VV_MSGPACK_TYPES, "msgpack_types", VAR_DICT, VV_RO),
|
||||
@@ -462,7 +461,6 @@ void eval_init(void)
|
||||
set_vim_var_nr(VV_HLSEARCH, 1);
|
||||
set_vim_var_nr(VV_COUNT1, 1);
|
||||
set_vim_var_special(VV_EXITING, kSpecialVarNull);
|
||||
set_vim_var_bool(VV_CMDCOMPLETE, kBoolVarFalse);
|
||||
|
||||
set_vim_var_nr(VV_TYPE_NUMBER, VAR_TYPE_NUMBER);
|
||||
set_vim_var_nr(VV_TYPE_STRING, VAR_TYPE_STRING);
|
||||
@@ -4793,6 +4791,7 @@ bool garbage_collect(bool testing)
|
||||
ABORTING(set_ref_in_callback)(&buf->b_ofu_cb, copyID, NULL, NULL);
|
||||
ABORTING(set_ref_in_callback)(&buf->b_tsrfu_cb, copyID, NULL, NULL);
|
||||
ABORTING(set_ref_in_callback)(&buf->b_tfu_cb, copyID, NULL, NULL);
|
||||
ABORTING(set_ref_in_callback)(&buf->b_ffu_cb, copyID, NULL, NULL);
|
||||
}
|
||||
|
||||
// 'completefunc', 'omnifunc' and 'thesaurusfunc' callbacks
|
||||
@@ -4804,6 +4803,9 @@ bool garbage_collect(bool testing)
|
||||
// 'tagfunc' callback
|
||||
ABORTING(set_ref_in_tagfunc)(copyID);
|
||||
|
||||
// 'findfunc' callback
|
||||
ABORTING(set_ref_in_findfunc)(copyID);
|
||||
|
||||
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
||||
// window-local variables
|
||||
ABORTING(set_ref_in_item)(&wp->w_winvar.di_tv, copyID, NULL, NULL);
|
||||
|
@@ -167,7 +167,6 @@ typedef enum {
|
||||
VV_COLLATE,
|
||||
VV_EXITING,
|
||||
VV_MAXCOL,
|
||||
VV_CMDCOMPLETE,
|
||||
// Nvim
|
||||
VV_STDERR,
|
||||
VV_MSGPACK_TYPES,
|
||||
|
@@ -5165,55 +5165,68 @@ static void ex_wrongmodifier(exarg_T *eap)
|
||||
eap->errmsg = _(e_invcmd);
|
||||
}
|
||||
|
||||
/// Evaluate the 'findexpr' expression and return the result. When evaluating
|
||||
/// the expression, v:fname is set to the ":find" command argument.
|
||||
static list_T *eval_findexpr(const char *pat, bool cmdcomplete)
|
||||
/// callback function for 'findfunc'
|
||||
static Callback ffu_cb;
|
||||
|
||||
static Callback *get_findfunc_callback(void)
|
||||
{
|
||||
return *curbuf->b_p_ffu != NUL ? &curbuf->b_ffu_cb : &ffu_cb;
|
||||
}
|
||||
|
||||
/// Call 'findfunc' to obtain the list of file names.
|
||||
static list_T *call_findfunc(char *pat, BoolVarValue cmdcomplete)
|
||||
{
|
||||
const sctx_T saved_sctx = current_sctx;
|
||||
|
||||
char *findexpr = get_findexpr();
|
||||
|
||||
set_vim_var_string(VV_FNAME, pat, -1);
|
||||
set_vim_var_bool(VV_CMDCOMPLETE, cmdcomplete ? kBoolVarTrue : kBoolVarFalse);
|
||||
current_sctx = curbuf->b_p_script_ctx[BV_FEXPR].script_ctx;
|
||||
|
||||
char *arg = skipwhite(findexpr);
|
||||
typval_T args[3];
|
||||
args[0].v_type = VAR_STRING;
|
||||
args[0].vval.v_string = pat;
|
||||
args[1].v_type = VAR_BOOL;
|
||||
args[1].vval.v_bool = cmdcomplete;
|
||||
args[2].v_type = VAR_UNKNOWN;
|
||||
|
||||
// Lock the text to prevent weird things from happening. Also disallow
|
||||
// switching to another window, it should not be needed and may end up in
|
||||
// Insert mode in another buffer.
|
||||
textlock++;
|
||||
|
||||
// Evaluate the expression. If the expression is "FuncName()" call the
|
||||
// function directly.
|
||||
typval_T tv;
|
||||
list_T *retlist = NULL;
|
||||
if (eval0_simple_funccal(arg, &tv, NULL, &EVALARG_EVALUATE) == FAIL) {
|
||||
retlist = NULL;
|
||||
} else {
|
||||
if (tv.v_type == VAR_LIST) {
|
||||
retlist = tv_list_copy(NULL, tv.vval.v_list, true, get_copyID());
|
||||
} else {
|
||||
emsg(_(e_invalid_return_type_from_findexpr));
|
||||
}
|
||||
tv_clear(&tv);
|
||||
sctx_T *ctx = get_option_sctx(kOptFindfunc);
|
||||
if (ctx != NULL) {
|
||||
current_sctx = *ctx;
|
||||
}
|
||||
textlock--;
|
||||
clear_evalarg(&EVALARG_EVALUATE, NULL);
|
||||
|
||||
set_vim_var_string(VV_FNAME, NULL, 0);
|
||||
set_vim_var_bool(VV_CMDCOMPLETE, kBoolVarFalse);
|
||||
Callback *cb = get_findfunc_callback();
|
||||
typval_T rettv;
|
||||
int retval = callback_call(cb, 2, args, &rettv);
|
||||
|
||||
current_sctx = saved_sctx;
|
||||
|
||||
textlock--;
|
||||
|
||||
list_T *retlist = NULL;
|
||||
|
||||
if (retval == OK) {
|
||||
if (rettv.v_type == VAR_LIST) {
|
||||
retlist = tv_list_copy(NULL, rettv.vval.v_list, false, get_copyID());
|
||||
} else {
|
||||
emsg(_(e_invalid_return_type_from_findfunc));
|
||||
}
|
||||
|
||||
tv_clear(&rettv);
|
||||
}
|
||||
|
||||
return retlist;
|
||||
}
|
||||
|
||||
/// Find file names matching "pat" using 'findexpr' and return it in "files".
|
||||
/// Find file names matching "pat" using 'findfunc' and return it in "files".
|
||||
/// Used for expanding the :find, :sfind and :tabfind command argument.
|
||||
/// Returns OK on success and FAIL otherwise.
|
||||
int expand_findexpr(const char *pat, char ***files, int *numMatches)
|
||||
int expand_findfunc(char *pat, char ***files, int *numMatches)
|
||||
{
|
||||
*numMatches = 0;
|
||||
*files = NULL;
|
||||
|
||||
list_T *l = eval_findexpr(pat, true);
|
||||
list_T *l = call_findfunc(pat, kBoolVarTrue);
|
||||
if (l == NULL) {
|
||||
return FAIL;
|
||||
}
|
||||
@@ -5240,16 +5253,16 @@ int expand_findexpr(const char *pat, char ***files, int *numMatches)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/// Use 'findexpr' to find file 'findarg'. The 'count' argument is used to find
|
||||
/// Use 'findfunc' to find file 'findarg'. The 'count' argument is used to find
|
||||
/// the n'th matching file.
|
||||
static char *findexpr_find_file(char *findarg, size_t findarg_len, int count)
|
||||
static char *findfunc_find_file(char *findarg, size_t findarg_len, int count)
|
||||
{
|
||||
char *ret_fname = NULL;
|
||||
|
||||
const char cc = findarg[findarg_len];
|
||||
findarg[findarg_len] = NUL;
|
||||
|
||||
list_T *fname_list = eval_findexpr(findarg, false);
|
||||
list_T *fname_list = call_findfunc(findarg, kBoolVarFalse);
|
||||
int fname_count = tv_list_len(fname_list);
|
||||
|
||||
if (fname_count == 0) {
|
||||
@@ -5274,6 +5287,51 @@ static char *findexpr_find_file(char *findarg, size_t findarg_len, int count)
|
||||
return ret_fname;
|
||||
}
|
||||
|
||||
/// Process the 'findfunc' option value.
|
||||
/// Returns NULL on success and an error message on failure.
|
||||
const char *did_set_findfunc(optset_T *args)
|
||||
{
|
||||
buf_T *buf = (buf_T *)args->os_buf;
|
||||
int retval;
|
||||
|
||||
if (*buf->b_p_ffu != NUL) {
|
||||
// buffer-local option set
|
||||
retval = option_set_callback_func(buf->b_p_ffu, &buf->b_ffu_cb);
|
||||
} else {
|
||||
// global option set
|
||||
retval = option_set_callback_func(p_ffu, &ffu_cb);
|
||||
}
|
||||
|
||||
if (retval == FAIL) {
|
||||
return e_invarg;
|
||||
}
|
||||
|
||||
// If the option value starts with <SID> or s:, then replace that with
|
||||
// the script identifier.
|
||||
char **varp = (char **)args->os_varp;
|
||||
char *name = get_scriptlocal_funcname(*varp);
|
||||
if (name != NULL) {
|
||||
free_string_option(*varp);
|
||||
*varp = name;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void free_findfunc_option(void)
|
||||
{
|
||||
callback_free(&ffu_cb);
|
||||
}
|
||||
|
||||
/// Mark the global 'findfunc' callback with "copyID" so that it is not
|
||||
/// garbage collected.
|
||||
bool set_ref_in_findfunc(int copyID)
|
||||
{
|
||||
bool abort = false;
|
||||
abort = set_ref_in_callback(&ffu_cb, copyID, NULL, NULL);
|
||||
return abort;
|
||||
}
|
||||
|
||||
/// :sview [+command] file split window with new file, read-only
|
||||
/// :split [[+command] file] split window with current or new file
|
||||
/// :vsplit [[+command] file] split window vertically with current or new file
|
||||
@@ -5305,8 +5363,8 @@ void ex_splitview(exarg_T *eap)
|
||||
}
|
||||
|
||||
if (eap->cmdidx == CMD_sfind || eap->cmdidx == CMD_tabfind) {
|
||||
if (*get_findexpr() != NUL) {
|
||||
fname = findexpr_find_file(eap->arg, strlen(eap->arg),
|
||||
if (*get_findfunc() != NUL) {
|
||||
fname = findfunc_find_file(eap->arg, strlen(eap->arg),
|
||||
eap->addr_count > 0 ? eap->line2 : 1);
|
||||
} else {
|
||||
char *file_to_find = NULL;
|
||||
@@ -5512,8 +5570,8 @@ static void ex_find(exarg_T *eap)
|
||||
}
|
||||
|
||||
char *fname = NULL;
|
||||
if (*get_findexpr() != NUL) {
|
||||
fname = findexpr_find_file(eap->arg, strlen(eap->arg),
|
||||
if (*get_findfunc() != NUL) {
|
||||
fname = findfunc_find_file(eap->arg, strlen(eap->arg),
|
||||
eap->addr_count > 0 ? eap->line2 : 1);
|
||||
} else {
|
||||
char *file_to_find = NULL;
|
||||
|
@@ -260,6 +260,7 @@ local function dump_option(i, o)
|
||||
end
|
||||
|
||||
w([[
|
||||
#include "nvim/ex_docmd.h"
|
||||
#include "nvim/ex_getln.h"
|
||||
#include "nvim/insexpand.h"
|
||||
#include "nvim/mapping.h"
|
||||
|
@@ -578,6 +578,7 @@ void free_all_options(void)
|
||||
}
|
||||
free_operatorfunc_option();
|
||||
free_tagfunc_option();
|
||||
free_findfunc_option();
|
||||
XFREE_CLEAR(fenc_default);
|
||||
XFREE_CLEAR(p_term);
|
||||
XFREE_CLEAR(p_ttytype);
|
||||
@@ -4472,8 +4473,8 @@ void *get_varp_scope_from(vimoption_T *p, int scope, buf_T *buf, win_T *win)
|
||||
switch ((int)p->indir) {
|
||||
case PV_FP:
|
||||
return &(buf->b_p_fp);
|
||||
case PV_FEXPR:
|
||||
return &(buf->b_p_fexpr);
|
||||
case PV_FFU:
|
||||
return &(buf->b_p_ffu);
|
||||
case PV_EFM:
|
||||
return &(buf->b_p_efm);
|
||||
case PV_GP:
|
||||
@@ -4595,8 +4596,8 @@ void *get_varp_from(vimoption_T *p, buf_T *buf, win_T *win)
|
||||
return *buf->b_p_tsrfu != NUL ? &(buf->b_p_tsrfu) : p->var;
|
||||
case PV_FP:
|
||||
return *buf->b_p_fp != NUL ? &(buf->b_p_fp) : p->var;
|
||||
case PV_FEXPR:
|
||||
return *buf->b_p_fexpr != NUL ? &(buf->b_p_fexpr) : p->var;
|
||||
case PV_FFU:
|
||||
return *buf->b_p_ffu != NUL ? &(buf->b_p_ffu) : p->var;
|
||||
case PV_EFM:
|
||||
return *buf->b_p_efm != NUL ? &(buf->b_p_efm) : p->var;
|
||||
case PV_GP:
|
||||
@@ -4868,13 +4869,13 @@ char *get_equalprg(void)
|
||||
return curbuf->b_p_ep;
|
||||
}
|
||||
|
||||
/// Get the value of 'findexpr', either the buffer-local one or the global one.
|
||||
char *get_findexpr(void)
|
||||
/// Get the value of 'findfunc', either the buffer-local one or the global one.
|
||||
char *get_findfunc(void)
|
||||
{
|
||||
if (*curbuf->b_p_fexpr == NUL) {
|
||||
return p_fexpr;
|
||||
if (*curbuf->b_p_ffu == NUL) {
|
||||
return p_ffu;
|
||||
}
|
||||
return curbuf->b_p_fexpr;
|
||||
return curbuf->b_p_ffu;
|
||||
}
|
||||
|
||||
/// Copy options from one window to another.
|
||||
@@ -5275,8 +5276,7 @@ void buf_copy_options(buf_T *buf, int flags)
|
||||
buf->b_p_mp = empty_string_option;
|
||||
buf->b_p_efm = empty_string_option;
|
||||
buf->b_p_ep = empty_string_option;
|
||||
buf->b_p_fexpr = xstrdup(p_fexpr);
|
||||
COPY_OPT_SCTX(buf, BV_FEXPR);
|
||||
buf->b_p_ffu = empty_string_option;
|
||||
buf->b_p_kp = empty_string_option;
|
||||
buf->b_p_path = empty_string_option;
|
||||
buf->b_p_tags = empty_string_option;
|
||||
|
@@ -451,7 +451,7 @@ EXTERN char *p_ffs; ///< 'fileformats'
|
||||
EXTERN int p_fic; ///< 'fileignorecase'
|
||||
EXTERN char *p_ft; ///< 'filetype'
|
||||
EXTERN char *p_fcs; ///< 'fillchar'
|
||||
EXTERN char *p_fexpr; ///< 'findexpr'
|
||||
EXTERN char *p_ffu; ///< 'findfunc'
|
||||
EXTERN int p_fixeol; ///< 'fixendofline'
|
||||
EXTERN char *p_fcl; ///< 'foldclose'
|
||||
EXTERN OptInt p_fdls; ///< 'foldlevelstart'
|
||||
|
@@ -2906,35 +2906,35 @@ return {
|
||||
varname = 'p_fcs',
|
||||
},
|
||||
{
|
||||
abbreviation = 'fexpr',
|
||||
cb = 'did_set_optexpr',
|
||||
abbreviation = 'ffu',
|
||||
cb = 'did_set_findfunc',
|
||||
defaults = { if_true = '' },
|
||||
desc = [=[
|
||||
Expression that is evaluated to obtain the filename(s) for the |:find|
|
||||
Function that is called to obtain the filename(s) for the |:find|
|
||||
command. When this option is empty, the internal |file-searching|
|
||||
mechanism is used.
|
||||
|
||||
While evaluating the expression, the |v:fname| variable is set to the
|
||||
argument of the |:find| command.
|
||||
The value can be the name of a function, a |lambda| or a |Funcref|.
|
||||
See |option-value-function| for more information.
|
||||
|
||||
The expression is evaluated only once per |:find| command invocation.
|
||||
The expression can process all the directories specified in 'path'.
|
||||
The function is called with two arguments. The first argument is a
|
||||
|String| and is the |:find| command argument. The second argument is
|
||||
a |Boolean| and is set to |v:true| when the function is called to get
|
||||
a List of command-line completion matches for the |:find| command.
|
||||
The function should return a List of strings.
|
||||
|
||||
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|.
|
||||
The function is called only once per |:find| command invocation.
|
||||
The function can process all the directories specified in 'path'.
|
||||
|
||||
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
|
||||
If a match is found, the function should return a |List| containing
|
||||
one or more file names. If a match is not found, the function
|
||||
should return an empty List.
|
||||
|
||||
If any errors are encountered during the expression evaluation, an
|
||||
If any errors are encountered during the function invocation, an
|
||||
empty List is used as the return value.
|
||||
|
||||
Using a function call without arguments is faster |expr-option-function|
|
||||
|
||||
It is not allowed to change text or jump to another window while
|
||||
evaluating 'findexpr' |textlock|.
|
||||
executing the 'findfunc' |textlock|.
|
||||
|
||||
This option cannot be set from a |modeline| or in the |sandbox|, for
|
||||
security reasons.
|
||||
@@ -2942,27 +2942,28 @@ return {
|
||||
Examples:
|
||||
>vim
|
||||
" Use glob()
|
||||
func FindExprGlob()
|
||||
let pat = v:cmdcomplete ? $'{v:fname}*' : v:fname
|
||||
func FindFuncGlob(cmdarg, cmdcomplete)
|
||||
let pat = a:cmdcomplete ? $'{a:cmdarg}*' : a:cmdarg
|
||||
return glob(pat, v:false, v:true)
|
||||
endfunc
|
||||
set findexpr=FindExprGlob()
|
||||
set findfunc=FindFuncGlob
|
||||
|
||||
" Use the 'git ls-files' output
|
||||
func FindGitFiles()
|
||||
func FindGitFiles(cmdarg, cmdcomplete)
|
||||
let fnames = systemlist('git ls-files')
|
||||
return fnames->filter('v:val =~? v:fname')
|
||||
return fnames->filter('v:val =~? a:cmdarg')
|
||||
endfunc
|
||||
set findexpr=FindGitFiles()
|
||||
set findfunc=FindGitFiles
|
||||
<
|
||||
]=],
|
||||
full_name = 'findexpr',
|
||||
full_name = 'findfunc',
|
||||
func = true,
|
||||
scope = { 'global', 'buffer' },
|
||||
secure = true,
|
||||
short_desc = N_('expression used for :find'),
|
||||
short_desc = N_('function called for :find'),
|
||||
tags = { 'E1514' },
|
||||
type = 'string',
|
||||
varname = 'p_fexpr',
|
||||
varname = 'p_ffu',
|
||||
},
|
||||
{
|
||||
abbreviation = 'fixeol',
|
||||
|
@@ -233,9 +233,9 @@ void check_buf_options(buf_T *buf)
|
||||
check_string_option(&buf->b_p_mp);
|
||||
check_string_option(&buf->b_p_efm);
|
||||
check_string_option(&buf->b_p_ep);
|
||||
check_string_option(&buf->b_p_fexpr);
|
||||
check_string_option(&buf->b_p_path);
|
||||
check_string_option(&buf->b_p_tags);
|
||||
check_string_option(&buf->b_p_ffu);
|
||||
check_string_option(&buf->b_p_tfu);
|
||||
check_string_option(&buf->b_p_tc);
|
||||
check_string_option(&buf->b_p_dict);
|
||||
@@ -1886,9 +1886,8 @@ int expand_set_nrformats(optexpand_T *args, int *numMatches, char ***matches)
|
||||
matches);
|
||||
}
|
||||
|
||||
/// One of the '*expr' options is changed:, 'diffexpr', 'findexpr',
|
||||
/// 'foldexpr', 'foldtext', 'formatexpr', 'includeexpr', 'indentexpr',
|
||||
/// 'patchexpr' and 'charconvert'.
|
||||
/// One of the '*expr' options is changed:, 'diffexpr', 'foldexpr', 'foldtext',
|
||||
/// 'formatexpr', 'includeexpr', 'indentexpr', 'patchexpr' and 'charconvert'.
|
||||
const char *did_set_optexpr(optset_T *args)
|
||||
{
|
||||
char **varp = (char **)args->os_varp;
|
||||
|
@@ -50,13 +50,6 @@ M.vars = {
|
||||
can be used.
|
||||
]=],
|
||||
},
|
||||
cmdcomplete = {
|
||||
type = 'boolean',
|
||||
desc = [=[
|
||||
When evaluating 'findexpr': if 'findexpr' is used for cmdline
|
||||
completion the value is |v:true|, otherwise it is |v:false|.
|
||||
]=],
|
||||
},
|
||||
collate = {
|
||||
type = 'string',
|
||||
desc = [=[
|
||||
@@ -291,8 +284,7 @@ M.vars = {
|
||||
type = 'string',
|
||||
desc = [=[
|
||||
When evaluating 'includeexpr': the file name that was
|
||||
detected. When evaluating 'findexpr': the argument passed to
|
||||
the |:find| command. Empty otherwise.
|
||||
detected. Empty otherwise.
|
||||
]=],
|
||||
},
|
||||
fname_diff = {
|
||||
|
Reference in New Issue
Block a user