mirror of
https://github.com/neovim/neovim.git
synced 2024-12-20 11:15:14 -07:00
vim-patch:8.2.3751: cannot assign a lambda to an option that takes a function
Problem: Cannot assign a lambda to an option that takes a function.
Solution: Automatically convert the lambda to a string. (Yegappan
Lakshmanan, closes vim/vim#9286)
6409553b6e
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
This commit is contained in:
parent
f91d200c05
commit
42e44d6d33
@ -315,7 +315,8 @@ Note: In the future more global options can be made |global-local|. Using
|
||||
*option-value-function*
|
||||
Some options ('completefunc', 'imactivatefunc', 'imstatusfunc', 'omnifunc',
|
||||
'operatorfunc', 'quickfixtextfunc', 'tagfunc' and 'thesaurusfunc') are set to
|
||||
a function name or a function reference or a lambda function. Examples:
|
||||
a function name or a function reference or a lambda function. When using a
|
||||
lambda it will be converted to the name, e.g. "<lambda>123". Examples:
|
||||
>
|
||||
set opfunc=MyOpFunc
|
||||
set opfunc=function('MyOpFunc')
|
||||
@ -325,10 +326,10 @@ a function name or a function reference or a lambda function. Examples:
|
||||
let Fn = function('MyTagFunc')
|
||||
let &tagfunc = string(Fn)
|
||||
" set using a lambda expression
|
||||
let &tagfunc = "{t -> MyTagFunc(t)}"
|
||||
let &tagfunc = {t -> MyTagFunc(t)}
|
||||
" set using a variable with lambda expression
|
||||
let L = {a, b, c -> MyTagFunc(a, b , c)}
|
||||
let &tagfunc = string(L)
|
||||
let &tagfunc = L
|
||||
<
|
||||
|
||||
Setting the filetype
|
||||
|
@ -487,7 +487,7 @@ static getoption_T access_option_value(char *key, long *numval, char **stringval
|
||||
bool get, Error *err)
|
||||
{
|
||||
if (get) {
|
||||
return get_option_value(key, numval, stringval, opt_flags);
|
||||
return get_option_value(key, numval, stringval, NULL, opt_flags);
|
||||
} else {
|
||||
char *errmsg;
|
||||
if ((errmsg = set_option_value(key, *numval, *stringval, opt_flags))) {
|
||||
|
@ -131,7 +131,7 @@ bool ctx_restore(Context *ctx, const int flags)
|
||||
}
|
||||
|
||||
char *op_shada;
|
||||
get_option_value("shada", NULL, &op_shada, OPT_GLOBAL);
|
||||
get_option_value("shada", NULL, &op_shada, NULL, OPT_GLOBAL);
|
||||
set_option_value("shada", 0L, "!,'100,%", OPT_GLOBAL);
|
||||
|
||||
if (flags & kCtxRegs) {
|
||||
|
@ -3689,10 +3689,10 @@ static int eval_index(char **arg, typval_T *rettv, int evaluate, int verbose)
|
||||
int get_option_tv(const char **const arg, typval_T *const rettv, const bool evaluate)
|
||||
FUNC_ATTR_NONNULL_ARG(1)
|
||||
{
|
||||
int opt_flags;
|
||||
int scope;
|
||||
|
||||
// Isolate the option name and find its value.
|
||||
char *option_end = (char *)find_option_end(arg, &opt_flags);
|
||||
char *option_end = (char *)find_option_end(arg, &scope);
|
||||
if (option_end == NULL) {
|
||||
if (rettv != NULL) {
|
||||
semsg(_("E112: Option name missing: %s"), *arg);
|
||||
@ -3712,7 +3712,7 @@ int get_option_tv(const char **const arg, typval_T *const rettv, const bool eval
|
||||
char c = *option_end;
|
||||
*option_end = NUL;
|
||||
getoption_T opt_type = get_option_value(*arg, &numval,
|
||||
rettv == NULL ? NULL : &stringval, opt_flags);
|
||||
rettv == NULL ? NULL : &stringval, NULL, scope);
|
||||
|
||||
if (opt_type == gov_unknown) {
|
||||
if (rettv != NULL) {
|
||||
@ -7794,19 +7794,19 @@ void ex_execute(exarg_T *eap)
|
||||
///
|
||||
/// @return NULL when no option name found. Otherwise pointer to the char
|
||||
/// after the option name.
|
||||
const char *find_option_end(const char **const arg, int *const opt_flags)
|
||||
const char *find_option_end(const char **const arg, int *const scope)
|
||||
{
|
||||
const char *p = *arg;
|
||||
|
||||
p++;
|
||||
if (*p == 'g' && p[1] == ':') {
|
||||
*opt_flags = OPT_GLOBAL;
|
||||
*scope = OPT_GLOBAL;
|
||||
p += 2;
|
||||
} else if (*p == 'l' && p[1] == ':') {
|
||||
*opt_flags = OPT_LOCAL;
|
||||
*scope = OPT_LOCAL;
|
||||
p += 2;
|
||||
} else {
|
||||
*opt_flags = 0;
|
||||
*scope = 0;
|
||||
}
|
||||
|
||||
if (!ASCII_ISALPHA(*p)) {
|
||||
|
@ -560,8 +560,6 @@ static char *ex_let_one(char *arg, typval_T *const tv, const bool copy, const bo
|
||||
{
|
||||
char *arg_end = NULL;
|
||||
int len;
|
||||
int opt_flags;
|
||||
char *tofree = NULL;
|
||||
|
||||
// ":let $VAR = expr": Set environment variable.
|
||||
if (*arg == '$') {
|
||||
@ -582,12 +580,12 @@ static char *ex_let_one(char *arg, typval_T *const tv, const bool copy, const bo
|
||||
&& vim_strchr(endchars, *skipwhite(arg)) == NULL) {
|
||||
emsg(_(e_letunexp));
|
||||
} else if (!check_secure()) {
|
||||
char *tofree = NULL;
|
||||
const char c1 = name[len];
|
||||
name[len] = NUL;
|
||||
const char *p = tv_get_string_chk(tv);
|
||||
if (p != NULL && op != NULL && *op == '.') {
|
||||
char *s = vim_getenv(name);
|
||||
|
||||
if (s != NULL) {
|
||||
tofree = concat_str(s, p);
|
||||
p = (const char *)tofree;
|
||||
@ -611,7 +609,8 @@ static char *ex_let_one(char *arg, typval_T *const tv, const bool copy, const bo
|
||||
return NULL;
|
||||
}
|
||||
// Find the end of the name.
|
||||
char *const p = (char *)find_option_end((const char **)&arg, &opt_flags);
|
||||
int scope;
|
||||
char *const p = (char *)find_option_end((const char **)&arg, &scope);
|
||||
if (p == NULL
|
||||
|| (endchars != NULL
|
||||
&& vim_strchr(endchars, *skipwhite(p)) == NULL)) {
|
||||
@ -623,11 +622,13 @@ static char *ex_let_one(char *arg, typval_T *const tv, const bool copy, const bo
|
||||
char *stringval = NULL;
|
||||
const char *s = NULL;
|
||||
bool failed = false;
|
||||
uint32_t opt_p_flags;
|
||||
char *tofree = NULL;
|
||||
|
||||
const char c1 = *p;
|
||||
*p = NUL;
|
||||
|
||||
opt_type = get_option_value(arg, &numval, &stringval, opt_flags);
|
||||
opt_type = get_option_value(arg, &numval, &stringval, &opt_p_flags, scope);
|
||||
if (opt_type == gov_bool
|
||||
|| opt_type == gov_number
|
||||
|| opt_type == gov_hidden_bool
|
||||
@ -636,8 +637,13 @@ static char *ex_let_one(char *arg, typval_T *const tv, const bool copy, const bo
|
||||
n = (long)tv_get_number(tv);
|
||||
}
|
||||
|
||||
// Avoid setting a string option to the text "v:false" or similar.
|
||||
if (tv->v_type != VAR_BOOL && tv->v_type != VAR_SPECIAL) {
|
||||
if ((opt_p_flags & P_FUNC) && tv_is_func(*tv)) {
|
||||
// If the option can be set to a function reference or a lambda
|
||||
// and the passed value is a function reference, then convert it to
|
||||
// the name (string) of the function reference.
|
||||
s = tofree = encode_tv2string(tv, NULL);
|
||||
} else if (tv->v_type != VAR_BOOL && tv->v_type != VAR_SPECIAL) {
|
||||
// Avoid setting a string option to the text "v:false" or similar.
|
||||
s = tv_get_string_chk(tv);
|
||||
}
|
||||
|
||||
@ -674,7 +680,7 @@ static char *ex_let_one(char *arg, typval_T *const tv, const bool copy, const bo
|
||||
|
||||
if (!failed) {
|
||||
if (opt_type != gov_string || s != NULL) {
|
||||
char *err = set_option_value(arg, n, s, opt_flags);
|
||||
char *err = set_option_value(arg, n, s, scope);
|
||||
arg_end = p;
|
||||
if (err != NULL) {
|
||||
emsg(_(err));
|
||||
@ -685,6 +691,7 @@ static char *ex_let_one(char *arg, typval_T *const tv, const bool copy, const bo
|
||||
}
|
||||
*p = c1;
|
||||
xfree(stringval);
|
||||
xfree(tofree);
|
||||
}
|
||||
// ":let @r = expr": Set register contents.
|
||||
} else if (*arg == '@') {
|
||||
|
@ -29,14 +29,14 @@ local type_flags={
|
||||
}
|
||||
|
||||
local redraw_flags={
|
||||
ui_option='P_UI_OPTION',
|
||||
tabline='P_RTABL',
|
||||
statuslines='P_RSTAT',
|
||||
tabline = 'P_RTABL',
|
||||
current_window='P_RWIN',
|
||||
current_window_only='P_RWINONLY',
|
||||
current_buffer='P_RBUF',
|
||||
all_windows='P_RALL',
|
||||
curswant='P_CURSWANT',
|
||||
ui_option='P_UI_OPTION',
|
||||
}
|
||||
|
||||
local list_flags={
|
||||
@ -78,6 +78,7 @@ local get_flags = function(o)
|
||||
{'deny_in_modelines', 'P_NO_ML'},
|
||||
{'deny_duplicates', 'P_NODUP'},
|
||||
{'modelineexpr', 'P_MLE'},
|
||||
{'func'}
|
||||
}) do
|
||||
local key_name = flag_desc[1]
|
||||
local def_name = flag_desc[2] or ('P_' .. key_name:upper())
|
||||
|
@ -2842,6 +2842,7 @@ int findoption(const char *const arg)
|
||||
/// Gets the value for an option.
|
||||
///
|
||||
/// @param stringval NULL when only checking existence
|
||||
/// @param flagsp set to the option flags (P_xxxx) (if not NULL)
|
||||
///
|
||||
/// @returns:
|
||||
/// Number option: gov_number, *numval gets value.
|
||||
@ -2851,7 +2852,8 @@ int findoption(const char *const arg)
|
||||
/// Hidden Toggle option: gov_hidden_bool.
|
||||
/// Hidden String option: gov_hidden_string.
|
||||
/// Unknown option: gov_unknown.
|
||||
getoption_T get_option_value(const char *name, long *numval, char **stringval, int opt_flags)
|
||||
getoption_T get_option_value(const char *name, long *numval, char **stringval, uint32_t *flagsp,
|
||||
int scope)
|
||||
{
|
||||
if (get_tty_option(name, stringval)) {
|
||||
return gov_string;
|
||||
@ -2862,7 +2864,12 @@ getoption_T get_option_value(const char *name, long *numval, char **stringval, i
|
||||
return gov_unknown;
|
||||
}
|
||||
|
||||
char_u *varp = (char_u *)get_varp_scope(&(options[opt_idx]), opt_flags);
|
||||
char_u *varp = (char_u *)get_varp_scope(&(options[opt_idx]), scope);
|
||||
|
||||
if (flagsp != NULL) {
|
||||
// Return the P_xxxx option flags.
|
||||
*flagsp = options[opt_idx].flags;
|
||||
}
|
||||
|
||||
if (options[opt_idx].flags & P_STRING) {
|
||||
if (varp == NULL) { // hidden option
|
||||
@ -3092,7 +3099,7 @@ char *set_option_value(const char *const name, const long number, const char *co
|
||||
numval = -1;
|
||||
} else {
|
||||
char *s = NULL;
|
||||
(void)get_option_value(name, &numval, &s, OPT_GLOBAL);
|
||||
(void)get_option_value(name, &numval, &s, NULL, OPT_GLOBAL);
|
||||
}
|
||||
}
|
||||
if (flags & P_NUM) {
|
||||
@ -3701,15 +3708,17 @@ void unset_global_local_option(char *name, void *from)
|
||||
}
|
||||
|
||||
/// Get pointer to option variable, depending on local or global scope.
|
||||
char *get_varp_scope(vimoption_T *p, int opt_flags)
|
||||
///
|
||||
/// @param scope can be OPT_LOCAL, OPT_GLOBAL or a combination.
|
||||
char *get_varp_scope(vimoption_T *p, int scope)
|
||||
{
|
||||
if ((opt_flags & OPT_GLOBAL) && p->indir != PV_NONE) {
|
||||
if ((scope & OPT_GLOBAL) && p->indir != PV_NONE) {
|
||||
if (p->var == VAR_WIN) {
|
||||
return GLOBAL_WO(get_varp(p));
|
||||
}
|
||||
return (char *)p->var;
|
||||
}
|
||||
if ((opt_flags & OPT_LOCAL) && ((int)p->indir & PV_BOTH)) {
|
||||
if ((scope & OPT_LOCAL) && ((int)p->indir & PV_BOTH)) {
|
||||
switch ((int)p->indir) {
|
||||
case PV_FP:
|
||||
return (char *)&(curbuf->b_p_fp);
|
||||
@ -4863,9 +4872,9 @@ void ExpandOldSetting(int *num_file, char ***file)
|
||||
/// NameBuff[]. Must not be called with a hidden option!
|
||||
///
|
||||
/// @param opt_flags OPT_GLOBAL and/or OPT_LOCAL
|
||||
static void option_value2string(vimoption_T *opp, int opt_flags)
|
||||
static void option_value2string(vimoption_T *opp, int scope)
|
||||
{
|
||||
char_u *varp = (char_u *)get_varp_scope(opp, opt_flags);
|
||||
char_u *varp = (char_u *)get_varp_scope(opp, scope);
|
||||
|
||||
if (opp->flags & P_NUM) {
|
||||
long wc = 0;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#define P_NO_MKRC 0x200U ///< don't include in :mkvimrc output
|
||||
|
||||
// when option changed, what to display:
|
||||
#define P_UI_OPTION 0x400U ///< send option to remote UI
|
||||
#define P_RTABL 0x800U ///< redraw tabline
|
||||
#define P_RSTAT 0x1000U ///< redraw status lines
|
||||
#define P_RWIN 0x2000U ///< redraw current window and recompute text
|
||||
@ -50,9 +51,9 @@
|
||||
#define P_NDNAME 0x8000000U ///< only normal dir name chars allowed
|
||||
#define P_RWINONLY 0x10000000U ///< only redraw current window
|
||||
#define P_MLE 0x20000000U ///< under control of 'modelineexpr'
|
||||
#define P_FUNC 0x40000000U ///< accept a function reference or a lambda
|
||||
|
||||
#define P_NO_DEF_EXP 0x40000000U ///< Do not expand default value.
|
||||
#define P_UI_OPTION 0x80000000U ///< send option to remote ui
|
||||
#define P_NO_DEF_EXP 0x80000000U ///< Do not expand default value.
|
||||
|
||||
/// Flags for option-setting functions
|
||||
///
|
||||
|
@ -10,6 +10,7 @@
|
||||
-- secure=nil, gettext=nil, noglob=nil, normal_fname_chars=nil,
|
||||
-- pri_mkrc=nil, deny_in_modelines=nil, normal_dname_chars=nil,
|
||||
-- modelineexpr=nil,
|
||||
-- func=nil,
|
||||
-- expand=nil, nodefault=nil, no_mkrc=nil,
|
||||
-- alloced=nil,
|
||||
-- save_pv_indir=nil,
|
||||
@ -455,6 +456,7 @@ return {
|
||||
type='string', scope={'buffer'},
|
||||
secure=true,
|
||||
alloced=true,
|
||||
func=true,
|
||||
varname='p_cfu',
|
||||
defaults={if_true=""}
|
||||
},
|
||||
@ -1638,6 +1640,7 @@ return {
|
||||
type='string', scope={'buffer'},
|
||||
secure=true,
|
||||
alloced=true,
|
||||
func=true,
|
||||
varname='p_ofu',
|
||||
defaults={if_true=""}
|
||||
},
|
||||
@ -1653,6 +1656,7 @@ return {
|
||||
short_desc=N_("function to be called for |g@| operator"),
|
||||
type='string', scope={'global'},
|
||||
secure=true,
|
||||
func=true,
|
||||
varname='p_opfunc',
|
||||
defaults={if_true=""}
|
||||
},
|
||||
@ -1835,6 +1839,8 @@ return {
|
||||
full_name='quickfixtextfunc', abbreviation='qftf',
|
||||
short_desc=N_("customize the quickfix window"),
|
||||
type='string', scope={'global'},
|
||||
secure=true,
|
||||
func=true,
|
||||
varname='p_qftf',
|
||||
defaults={if_true=""}
|
||||
},
|
||||
@ -2408,6 +2414,8 @@ return {
|
||||
full_name='tagfunc', abbreviation='tfu',
|
||||
short_desc=N_("function used to perform tag searches"),
|
||||
type='string', scope={'buffer'},
|
||||
secure=true,
|
||||
func=true,
|
||||
varname='p_tfu',
|
||||
defaults={if_true=""}
|
||||
},
|
||||
@ -2538,6 +2546,7 @@ return {
|
||||
type='string', scope={'global', 'buffer'},
|
||||
secure=true,
|
||||
alloced=true,
|
||||
func=true,
|
||||
varname='p_tsrfu',
|
||||
defaults={if_true=""}
|
||||
},
|
||||
|
@ -3145,7 +3145,7 @@ void ex_spelldump(exarg_T *eap)
|
||||
}
|
||||
char *spl;
|
||||
long dummy;
|
||||
(void)get_option_value("spl", &dummy, &spl, OPT_LOCAL);
|
||||
(void)get_option_value("spl", &dummy, &spl, NULL, OPT_LOCAL);
|
||||
|
||||
// Create a new empty buffer in a new window.
|
||||
do_cmdline_cmd("new");
|
||||
|
@ -1302,13 +1302,22 @@ func Test_completefunc_callback()
|
||||
|
||||
" Using a funcref variable to set 'completefunc'
|
||||
let Fn = function('MycompleteFunc1')
|
||||
let &completefunc = Fn
|
||||
new | only
|
||||
call setline(1, 'two')
|
||||
let g:MycompleteFunc1_args = []
|
||||
call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'two']], g:MycompleteFunc1_args)
|
||||
bw!
|
||||
|
||||
" Using string(funcref_variable) to set 'completefunc'
|
||||
let Fn = function('MycompleteFunc1')
|
||||
let &completefunc = string(Fn)
|
||||
new | only
|
||||
call setline(1, 'two')
|
||||
let g:MycompleteFunc1_args = []
|
||||
call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'two']], g:MycompleteFunc1_args)
|
||||
call assert_fails('let &completefunc = Fn', 'E729:')
|
||||
bw!
|
||||
|
||||
" Test for using a funcref()
|
||||
@ -1326,13 +1335,22 @@ func Test_completefunc_callback()
|
||||
|
||||
" Using a funcref variable to set 'completefunc'
|
||||
let Fn = funcref('MycompleteFunc2')
|
||||
let &completefunc = Fn
|
||||
new | only
|
||||
call setline(1, 'four')
|
||||
let g:MycompleteFunc2_args = []
|
||||
call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'four']], g:MycompleteFunc2_args)
|
||||
bw!
|
||||
|
||||
" Using a string(funcref_variable) to set 'completefunc'
|
||||
let Fn = funcref('MycompleteFunc2')
|
||||
let &completefunc = string(Fn)
|
||||
new | only
|
||||
call setline(1, 'four')
|
||||
let g:MycompleteFunc2_args = []
|
||||
call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'four']], g:MycompleteFunc2_args)
|
||||
call assert_fails('let &completefunc = Fn', 'E729:')
|
||||
bw!
|
||||
|
||||
" Test for using a lambda function
|
||||
@ -1349,6 +1367,15 @@ func Test_completefunc_callback()
|
||||
bw!
|
||||
|
||||
" Set 'completefunc' to a lambda expression
|
||||
let &completefunc = {a, b -> MycompleteFunc3(a, b)}
|
||||
new | only
|
||||
call setline(1, 'six')
|
||||
let g:MycompleteFunc3_args = []
|
||||
call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'six']], g:MycompleteFunc3_args)
|
||||
bw!
|
||||
|
||||
" Set 'completefunc' to string(lambda_expression)
|
||||
let &completefunc = '{a, b -> MycompleteFunc3(a, b)}'
|
||||
new | only
|
||||
call setline(1, 'six')
|
||||
@ -1359,18 +1386,27 @@ func Test_completefunc_callback()
|
||||
|
||||
" Set 'completefunc' to a variable with a lambda expression
|
||||
let Lambda = {a, b -> MycompleteFunc3(a, b)}
|
||||
let &completefunc = Lambda
|
||||
new | only
|
||||
call setline(1, 'seven')
|
||||
let g:MycompleteFunc3_args = []
|
||||
call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'seven']], g:MycompleteFunc3_args)
|
||||
bw!
|
||||
|
||||
" Set 'completefunc' to a string(variable with a lambda expression)
|
||||
let Lambda = {a, b -> MycompleteFunc3(a, b)}
|
||||
let &completefunc = string(Lambda)
|
||||
new | only
|
||||
call setline(1, 'seven')
|
||||
let g:MycompleteFunc3_args = []
|
||||
call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'seven']], g:MycompleteFunc3_args)
|
||||
call assert_fails('let &completefunc = Lambda', 'E729:')
|
||||
bw!
|
||||
|
||||
" Test for using a lambda function with incorrect return value
|
||||
let Lambda = {s -> strlen(s)}
|
||||
let &completefunc = string(Lambda)
|
||||
let &completefunc = Lambda
|
||||
new | only
|
||||
call setline(1, 'eight')
|
||||
call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
|
||||
@ -1382,7 +1418,7 @@ func Test_completefunc_callback()
|
||||
|
||||
call assert_fails("set completefunc=function('abc')", "E700:")
|
||||
call assert_fails("set completefunc=funcref('abc')", "E700:")
|
||||
let &completefunc = "{a -> 'abc'}"
|
||||
let &completefunc = {a -> 'abc'}
|
||||
call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
|
||||
|
||||
" Vim9 tests
|
||||
@ -1407,6 +1443,15 @@ func Test_completefunc_callback()
|
||||
add(g:LambdaComplete1_args, [findstart, base])
|
||||
return findstart ? 0 : []
|
||||
enddef
|
||||
&completefunc = (a, b) => LambdaComplete1(a, b)
|
||||
new | only
|
||||
setline(1, 'two')
|
||||
g:LambdaComplete1_args = []
|
||||
feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
|
||||
assert_equal([[1, ''], [0, 'two']], g:LambdaComplete1_args)
|
||||
bw!
|
||||
|
||||
# Test for using a string(lambda)
|
||||
&completefunc = '(a, b) => LambdaComplete1(a, b)'
|
||||
new | only
|
||||
setline(1, 'two')
|
||||
@ -1420,6 +1465,15 @@ func Test_completefunc_callback()
|
||||
add(g:LambdaComplete2_args, [findstart, base])
|
||||
return findstart ? 0 : []
|
||||
}
|
||||
&completefunc = Fn
|
||||
new | only
|
||||
setline(1, 'three')
|
||||
g:LambdaComplete2_args = []
|
||||
feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
|
||||
assert_equal([[1, ''], [0, 'three']], g:LambdaComplete2_args)
|
||||
bw!
|
||||
|
||||
# Test for using a string(variable with a lambda expression)
|
||||
&completefunc = string(Fn)
|
||||
new | only
|
||||
setline(1, 'three')
|
||||
@ -1462,13 +1516,22 @@ func Test_omnifunc_callback()
|
||||
|
||||
" Using a funcref variable to set 'omnifunc'
|
||||
let Fn = function('MyomniFunc1')
|
||||
let &omnifunc = Fn
|
||||
new | only
|
||||
call setline(1, 'two')
|
||||
let g:MyomniFunc1_args = []
|
||||
call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'two']], g:MyomniFunc1_args)
|
||||
bw!
|
||||
|
||||
" Using a string(funcref_variable) to set 'omnifunc'
|
||||
let Fn = function('MyomniFunc1')
|
||||
let &omnifunc = string(Fn)
|
||||
new | only
|
||||
call setline(1, 'two')
|
||||
let g:MyomniFunc1_args = []
|
||||
call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'two']], g:MyomniFunc1_args)
|
||||
call assert_fails('let &omnifunc = Fn', 'E729:')
|
||||
bw!
|
||||
|
||||
" Test for using a funcref()
|
||||
@ -1486,13 +1549,22 @@ func Test_omnifunc_callback()
|
||||
|
||||
" Using a funcref variable to set 'omnifunc'
|
||||
let Fn = funcref('MyomniFunc2')
|
||||
let &omnifunc = Fn
|
||||
new | only
|
||||
call setline(1, 'four')
|
||||
let g:MyomniFunc2_args = []
|
||||
call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'four']], g:MyomniFunc2_args)
|
||||
bw!
|
||||
|
||||
" Using a string(funcref_variable) to set 'omnifunc'
|
||||
let Fn = funcref('MyomniFunc2')
|
||||
let &omnifunc = string(Fn)
|
||||
new | only
|
||||
call setline(1, 'four')
|
||||
let g:MyomniFunc2_args = []
|
||||
call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'four']], g:MyomniFunc2_args)
|
||||
call assert_fails('let &omnifunc = Fn', 'E729:')
|
||||
bw!
|
||||
|
||||
" Test for using a lambda function
|
||||
@ -1509,6 +1581,15 @@ func Test_omnifunc_callback()
|
||||
bw!
|
||||
|
||||
" Set 'omnifunc' to a lambda expression
|
||||
let &omnifunc = {a, b -> MyomniFunc3(a, b)}
|
||||
new | only
|
||||
call setline(1, 'six')
|
||||
let g:MyomniFunc3_args = []
|
||||
call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'six']], g:MyomniFunc3_args)
|
||||
bw!
|
||||
|
||||
" Set 'omnifunc' to a string(lambda_expression)
|
||||
let &omnifunc = '{a, b -> MyomniFunc3(a, b)}'
|
||||
new | only
|
||||
call setline(1, 'six')
|
||||
@ -1519,18 +1600,27 @@ func Test_omnifunc_callback()
|
||||
|
||||
" Set 'omnifunc' to a variable with a lambda expression
|
||||
let Lambda = {a, b -> MyomniFunc3(a, b)}
|
||||
let &omnifunc = Lambda
|
||||
new | only
|
||||
call setline(1, 'seven')
|
||||
let g:MyomniFunc3_args = []
|
||||
call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'seven']], g:MyomniFunc3_args)
|
||||
bw!
|
||||
|
||||
" Set 'omnifunc' to a string(variable with a lambda expression)
|
||||
let Lambda = {a, b -> MyomniFunc3(a, b)}
|
||||
let &omnifunc = string(Lambda)
|
||||
new | only
|
||||
call setline(1, 'seven')
|
||||
let g:MyomniFunc3_args = []
|
||||
call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'seven']], g:MyomniFunc3_args)
|
||||
call assert_fails('let &omnifunc = Lambda', 'E729:')
|
||||
bw!
|
||||
|
||||
" Test for using a lambda function with incorrect return value
|
||||
let Lambda = {s -> strlen(s)}
|
||||
let &omnifunc = string(Lambda)
|
||||
let &omnifunc = Lambda
|
||||
new | only
|
||||
call setline(1, 'eight')
|
||||
call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
|
||||
@ -1542,7 +1632,7 @@ func Test_omnifunc_callback()
|
||||
|
||||
call assert_fails("set omnifunc=function('abc')", "E700:")
|
||||
call assert_fails("set omnifunc=funcref('abc')", "E700:")
|
||||
let &omnifunc = "{a -> 'abc'}"
|
||||
let &omnifunc = {a -> 'abc'}
|
||||
call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
|
||||
|
||||
" Vim9 tests
|
||||
@ -1567,6 +1657,15 @@ func Test_omnifunc_callback()
|
||||
add(g:MyomniFunc2_args, [findstart, base])
|
||||
return findstart ? 0 : []
|
||||
enddef
|
||||
&omnifunc = (a, b) => MyomniFunc2(a, b)
|
||||
new | only
|
||||
setline(1, 'two')
|
||||
g:MyomniFunc2_args = []
|
||||
feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
|
||||
assert_equal([[1, ''], [0, 'two']], g:MyomniFunc2_args)
|
||||
bw!
|
||||
|
||||
# Test for using a string(lambda)
|
||||
&omnifunc = '(a, b) => MyomniFunc2(a, b)'
|
||||
new | only
|
||||
setline(1, 'two')
|
||||
@ -1577,6 +1676,15 @@ func Test_omnifunc_callback()
|
||||
|
||||
# Test for using a variable with a lambda expression
|
||||
var Fn: func = (a, b) => MyomniFunc2(a, b)
|
||||
&omnifunc = Fn
|
||||
new | only
|
||||
setline(1, 'three')
|
||||
g:MyomniFunc2_args = []
|
||||
feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
|
||||
assert_equal([[1, ''], [0, 'three']], g:MyomniFunc2_args)
|
||||
bw!
|
||||
|
||||
# Test for using a string(variable with a lambda expression)
|
||||
&omnifunc = string(Fn)
|
||||
new | only
|
||||
setline(1, 'three')
|
||||
@ -1619,13 +1727,22 @@ func Test_thesaurusfunc_callback()
|
||||
|
||||
" Using a funcref variable to set 'thesaurusfunc'
|
||||
let Fn = function('MytsrFunc1')
|
||||
let &thesaurusfunc = Fn
|
||||
new | only
|
||||
call setline(1, 'two')
|
||||
let g:MytsrFunc1_args = []
|
||||
call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'two']], g:MytsrFunc1_args)
|
||||
bw!
|
||||
|
||||
" Using a string(funcref_variable) to set 'thesaurusfunc'
|
||||
let Fn = function('MytsrFunc1')
|
||||
let &thesaurusfunc = string(Fn)
|
||||
new | only
|
||||
call setline(1, 'two')
|
||||
let g:MytsrFunc1_args = []
|
||||
call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'two']], g:MytsrFunc1_args)
|
||||
call assert_fails('let &thesaurusfunc = Fn', 'E729:')
|
||||
bw!
|
||||
|
||||
" Test for using a funcref()
|
||||
@ -1643,13 +1760,22 @@ func Test_thesaurusfunc_callback()
|
||||
|
||||
" Using a funcref variable to set 'thesaurusfunc'
|
||||
let Fn = funcref('MytsrFunc2')
|
||||
let &thesaurusfunc = Fn
|
||||
new | only
|
||||
call setline(1, 'four')
|
||||
let g:MytsrFunc2_args = []
|
||||
call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'four']], g:MytsrFunc2_args)
|
||||
bw!
|
||||
|
||||
" Using a string(funcref_variable) to set 'thesaurusfunc'
|
||||
let Fn = funcref('MytsrFunc2')
|
||||
let &thesaurusfunc = string(Fn)
|
||||
new | only
|
||||
call setline(1, 'four')
|
||||
let g:MytsrFunc2_args = []
|
||||
call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'four']], g:MytsrFunc2_args)
|
||||
call assert_fails('let &thesaurusfunc = Fn', 'E729:')
|
||||
bw!
|
||||
|
||||
" Test for using a lambda function
|
||||
@ -1666,6 +1792,15 @@ func Test_thesaurusfunc_callback()
|
||||
bw!
|
||||
|
||||
" Set 'thesaurusfunc' to a lambda expression
|
||||
let &thesaurusfunc = {a, b -> MytsrFunc3(a, b)}
|
||||
new | only
|
||||
call setline(1, 'six')
|
||||
let g:MytsrFunc3_args = []
|
||||
call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'six']], g:MytsrFunc3_args)
|
||||
bw!
|
||||
|
||||
" Set 'thesaurusfunc' to a string(lambda expression)
|
||||
let &thesaurusfunc = '{a, b -> MytsrFunc3(a, b)}'
|
||||
new | only
|
||||
call setline(1, 'six')
|
||||
@ -1676,18 +1811,27 @@ func Test_thesaurusfunc_callback()
|
||||
|
||||
" Set 'thesaurusfunc' to a variable with a lambda expression
|
||||
let Lambda = {a, b -> MytsrFunc3(a, b)}
|
||||
let &thesaurusfunc = Lambda
|
||||
new | only
|
||||
call setline(1, 'seven')
|
||||
let g:MytsrFunc3_args = []
|
||||
call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'seven']], g:MytsrFunc3_args)
|
||||
bw!
|
||||
|
||||
" Set 'thesaurusfunc' to a string(variable with a lambda expression)
|
||||
let Lambda = {a, b -> MytsrFunc3(a, b)}
|
||||
let &thesaurusfunc = string(Lambda)
|
||||
new | only
|
||||
call setline(1, 'seven')
|
||||
let g:MytsrFunc3_args = []
|
||||
call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'seven']], g:MytsrFunc3_args)
|
||||
call assert_fails('let &thesaurusfunc = Lambda', 'E729:')
|
||||
bw!
|
||||
|
||||
" Test for using a lambda function with incorrect return value
|
||||
let Lambda = {s -> strlen(s)}
|
||||
let &thesaurusfunc = string(Lambda)
|
||||
let &thesaurusfunc = Lambda
|
||||
new | only
|
||||
call setline(1, 'eight')
|
||||
call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
|
||||
@ -1699,7 +1843,7 @@ func Test_thesaurusfunc_callback()
|
||||
|
||||
call assert_fails("set thesaurusfunc=function('abc')", "E700:")
|
||||
call assert_fails("set thesaurusfunc=funcref('abc')", "E700:")
|
||||
let &thesaurusfunc = "{a -> 'abc'}"
|
||||
let &thesaurusfunc = {a -> 'abc'}
|
||||
call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
|
||||
|
||||
" Vim9 tests
|
||||
@ -1724,6 +1868,15 @@ func Test_thesaurusfunc_callback()
|
||||
add(g:MytsrFunc2_args, [findstart, base])
|
||||
return findstart ? 0 : []
|
||||
enddef
|
||||
&thesaurusfunc = (a, b) => MytsrFunc2(a, b)
|
||||
new | only
|
||||
setline(1, 'two')
|
||||
g:MytsrFunc2_args = []
|
||||
feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
|
||||
assert_equal([[1, ''], [0, 'two']], g:MytsrFunc2_args)
|
||||
bw!
|
||||
|
||||
# Test for using a string(lambda)
|
||||
&thesaurusfunc = '(a, b) => MytsrFunc2(a, b)'
|
||||
new | only
|
||||
setline(1, 'two')
|
||||
@ -1734,6 +1887,15 @@ func Test_thesaurusfunc_callback()
|
||||
|
||||
# Test for using a variable with a lambda expression
|
||||
var Fn: func = (a, b) => MytsrFunc2(a, b)
|
||||
&thesaurusfunc = Fn
|
||||
new | only
|
||||
setline(1, 'three')
|
||||
g:MytsrFunc2_args = []
|
||||
feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
|
||||
assert_equal([[1, ''], [0, 'three']], g:MytsrFunc2_args)
|
||||
bw!
|
||||
|
||||
# Test for using a string(variable with a lambda expression)
|
||||
&thesaurusfunc = string(Fn)
|
||||
new | only
|
||||
setline(1, 'three')
|
||||
|
@ -138,12 +138,19 @@ func Test_tagfunc_callback()
|
||||
|
||||
" Using a funcref variable to set 'tagfunc'
|
||||
let Fn = function('MytagFunc1')
|
||||
let &tagfunc = Fn
|
||||
new | only
|
||||
let g:MytagFunc1_args = []
|
||||
call assert_fails('tag a12', 'E433:')
|
||||
call assert_equal(['a12', '', {}], g:MytagFunc1_args)
|
||||
|
||||
" Using a string(funcref_variable) to set 'tagfunc'
|
||||
let Fn = function('MytagFunc1')
|
||||
let &tagfunc = string(Fn)
|
||||
new | only
|
||||
let g:MytagFunc1_args = []
|
||||
call assert_fails('tag a12', 'E433:')
|
||||
call assert_equal(['a12', '', {}], g:MytagFunc1_args)
|
||||
call assert_fails('let &tagfunc = Fn', 'E729:')
|
||||
|
||||
" Test for using a funcref()
|
||||
func MytagFunc2(pat, flags, info)
|
||||
@ -158,12 +165,19 @@ func Test_tagfunc_callback()
|
||||
|
||||
" Using a funcref variable to set 'tagfunc'
|
||||
let Fn = funcref('MytagFunc2')
|
||||
let &tagfunc = Fn
|
||||
new | only
|
||||
let g:MytagFunc2_args = []
|
||||
call assert_fails('tag a14', 'E433:')
|
||||
call assert_equal(['a14', '', {}], g:MytagFunc2_args)
|
||||
|
||||
" Using a string(funcref_variable) to set 'tagfunc'
|
||||
let Fn = funcref('MytagFunc2')
|
||||
let &tagfunc = string(Fn)
|
||||
new | only
|
||||
let g:MytagFunc2_args = []
|
||||
call assert_fails('tag a14', 'E433:')
|
||||
call assert_equal(['a14', '', {}], g:MytagFunc2_args)
|
||||
call assert_fails('let &tagfunc = Fn', 'E729:')
|
||||
|
||||
" Test for using a script local function
|
||||
set tagfunc=<SID>ScriptLocalTagFunc
|
||||
@ -174,6 +188,14 @@ func Test_tagfunc_callback()
|
||||
|
||||
" Test for using a script local funcref variable
|
||||
let Fn = function("s:ScriptLocalTagFunc")
|
||||
let &tagfunc= Fn
|
||||
new | only
|
||||
let g:ScriptLocalFuncArgs = []
|
||||
call assert_fails('tag a16', 'E433:')
|
||||
call assert_equal(['a16', '', {}], g:ScriptLocalFuncArgs)
|
||||
|
||||
" Test for using a string(script local funcref variable)
|
||||
let Fn = function("s:ScriptLocalTagFunc")
|
||||
let &tagfunc= string(Fn)
|
||||
new | only
|
||||
let g:ScriptLocalFuncArgs = []
|
||||
@ -192,6 +214,13 @@ func Test_tagfunc_callback()
|
||||
call assert_equal(['a17', '', {}], g:MytagFunc3_args)
|
||||
|
||||
" Set 'tagfunc' to a lambda expression
|
||||
let &tagfunc = {a, b, c -> MytagFunc3(a, b, c)}
|
||||
new | only
|
||||
let g:MytagFunc3_args = []
|
||||
call assert_fails('tag a18', 'E433:')
|
||||
call assert_equal(['a18', '', {}], g:MytagFunc3_args)
|
||||
|
||||
" Set 'tagfunc' to a string(lambda expression)
|
||||
let &tagfunc = '{a, b, c -> MytagFunc3(a, b, c)}'
|
||||
new | only
|
||||
let g:MytagFunc3_args = []
|
||||
@ -200,12 +229,19 @@ func Test_tagfunc_callback()
|
||||
|
||||
" Set 'tagfunc' to a variable with a lambda expression
|
||||
let Lambda = {a, b, c -> MytagFunc3(a, b, c)}
|
||||
let &tagfunc = Lambda
|
||||
new | only
|
||||
let g:MytagFunc3_args = []
|
||||
call assert_fails("tag a19", "E433:")
|
||||
call assert_equal(['a19', '', {}], g:MytagFunc3_args)
|
||||
|
||||
" Set 'tagfunc' to a string(variable with a lambda expression)
|
||||
let Lambda = {a, b, c -> MytagFunc3(a, b, c)}
|
||||
let &tagfunc = string(Lambda)
|
||||
new | only
|
||||
let g:MytagFunc3_args = []
|
||||
call assert_fails("tag a19", "E433:")
|
||||
call assert_equal(['a19', '', {}], g:MytagFunc3_args)
|
||||
call assert_fails('let &tagfunc = Lambda', 'E729:')
|
||||
|
||||
" Test for using a lambda function with incorrect return value
|
||||
let Lambda = {s -> strlen(s)}
|
||||
@ -242,6 +278,13 @@ func Test_tagfunc_callback()
|
||||
g:MytagFunc2_args = [pat, flags, info]
|
||||
return null
|
||||
enddef
|
||||
&tagfunc = (a, b, c) => MytagFunc2(a, b, c)
|
||||
new | only
|
||||
g:MytagFunc2_args = []
|
||||
assert_fails('tag a20', 'E433:')
|
||||
assert_equal(['a20', '', {}], g:MytagFunc2_args)
|
||||
|
||||
# Test for using a string(lambda)
|
||||
&tagfunc = '(a, b, c) => MytagFunc2(a, b, c)'
|
||||
new | only
|
||||
g:MytagFunc2_args = []
|
||||
@ -250,6 +293,13 @@ func Test_tagfunc_callback()
|
||||
|
||||
# Test for using a variable with a lambda expression
|
||||
var Fn: func = (a, b, c) => MytagFunc2(a, b, c)
|
||||
&tagfunc = Fn
|
||||
new | only
|
||||
g:MytagFunc2_args = []
|
||||
assert_fails('tag a30', 'E433:')
|
||||
assert_equal(['a30', '', {}], g:MytagFunc2_args)
|
||||
|
||||
# Test for using a variable with a lambda expression
|
||||
&tagfunc = string(Fn)
|
||||
new | only
|
||||
g:MytagFunc2_args = []
|
||||
|
Loading…
Reference in New Issue
Block a user