Patch 8.2.3751

5 views
Skip to first unread message

Bram Moolenaar

unread,
Dec 6, 2021, 6:04:36 AM12/6/21
to vim...@googlegroups.com

Patch 8.2.3751
Problem: Cannot assign a lambda to an option that takes a function.
Solution: Automatically convert the lambda to a string. (Yegappan
Lakshmanan, closes #9286)
Files: runtime/doc/options.txt, src/eval.c, src/proto/eval.pro,
src/evalvars.c, src/if_mzsch.c, src/if_ruby.c, src/if_tcl.c,
src/option.c, src/option.h, src/optiondefs.h,
src/proto/option.pro, src/spell.c, src/typval.c,
src/vim9compile.c, src/testdir/test_iminsert.vim,
src/testdir/test_ins_complete.vim, src/testdir/test_tagfunc.vim


*** ../vim-8.2.3750/runtime/doc/options.txt 2021-12-04 14:02:25.457024636 +0000
--- runtime/doc/options.txt 2021-12-06 10:47:35.320266764 +0000
***************
*** 367,373 ****
*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:
>
set opfunc=MyOpFunc
set opfunc=function('MyOpFunc')
--- 376,383 ----
*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. When using a
! lambda it will be converted to the name, e.g. "<lambda>123". Examples:
>
set opfunc=MyOpFunc
set opfunc=function('MyOpFunc')
***************
*** 377,386 ****
let Fn = function('MyTagFunc')
let &tagfunc = string(Fn)
" set using a lambda expression
! 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)
<

Setting the filetype
--- 387,396 ----
let Fn = function('MyTagFunc')
let &tagfunc = string(Fn)
" set using a lambda expression
! let &tagfunc = {t -> MyTagFunc(t)}
" set using a variable with lambda expression
let L = {a, b, c -> MyTagFunc(a, b , c)}
! let &tagfunc = L
<

Setting the filetype
*** ../vim-8.2.3750/src/eval.c 2021-11-29 13:44:52.452955930 +0000
--- src/eval.c 2021-12-06 10:53:22.995957744 +0000
***************
*** 6281,6303 ****
* after the option name.
*/
char_u *
! find_option_end(char_u **arg, int *opt_flags)
{
char_u *p = *arg;

++p;
if (*p == 'g' && p[1] == ':')
{
! *opt_flags = OPT_GLOBAL;
p += 2;
}
else if (*p == 'l' && p[1] == ':')
{
! *opt_flags = OPT_LOCAL;
p += 2;
}
else
! *opt_flags = 0;

if (!ASCII_ISALPHA(*p))
return NULL;
--- 6281,6303 ----
* after the option name.
*/
char_u *
! find_option_end(char_u **arg, int *scope)
{
char_u *p = *arg;

++p;
if (*p == 'g' && p[1] == ':')
{
! *scope = OPT_GLOBAL;
p += 2;
}
else if (*p == 'l' && p[1] == ':')
{
! *scope = OPT_LOCAL;
p += 2;
}
else
! *scope = 0;

if (!ASCII_ISALPHA(*p))
return NULL;
*** ../vim-8.2.3750/src/proto/eval.pro 2021-10-23 13:32:27.223954845 +0100
--- src/proto/eval.pro 2021-12-06 11:01:27.731173044 +0000
***************
*** 73,79 ****
void ex_echohl(exarg_T *eap);
int get_echo_attr(void);
void ex_execute(exarg_T *eap);
! char_u *find_option_end(char_u **arg, int *opt_flags);
void last_set_msg(sctx_T script_ctx);
char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, typval_T *expr, char_u *flags);
/* vim: set ft=c : */
--- 73,79 ----
void ex_echohl(exarg_T *eap);
int get_echo_attr(void);
void ex_execute(exarg_T *eap);
! char_u *find_option_end(char_u **arg, int *scope);
void last_set_msg(sctx_T script_ctx);
char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, typval_T *expr, char_u *flags);
/* vim: set ft=c : */
*** ../vim-8.2.3750/src/evalvars.c 2021-11-29 16:01:45.384711994 +0000
--- src/evalvars.c 2021-12-06 10:57:31.063589884 +0000
***************
*** 1367,1373 ****
char_u *op)
{
char_u *p;
! int opt_flags;
char_u *arg_end = NULL;

if ((flags & (ASSIGN_CONST | ASSIGN_FINAL))
--- 1367,1373 ----
char_u *op)
{
char_u *p;
! int scope;
char_u *arg_end = NULL;

if ((flags & (ASSIGN_CONST | ASSIGN_FINAL))
***************
*** 1378,1384 ****
}

// Find the end of the name.
! p = find_option_end(&arg, &opt_flags);
if (p == NULL || (endchars != NULL
&& vim_strchr(endchars, *skipwhite(p)) == NULL))
emsg(_(e_unexpected_characters_in_let));
--- 1378,1384 ----
}

// Find the end of the name.
! p = find_option_end(&arg, &scope);
if (p == NULL || (endchars != NULL
&& vim_strchr(endchars, *skipwhite(p)) == NULL))
emsg(_(e_unexpected_characters_in_let));
***************
*** 1391,1401 ****
char_u *stringval = NULL;
char_u *s = NULL;
int failed = FALSE;

c1 = *p;
*p = NUL;

! opt_type = get_option_value(arg, &numval, &stringval, opt_flags);
if ((opt_type == gov_bool
|| opt_type == gov_number
|| opt_type == gov_hidden_bool
--- 1391,1404 ----
char_u *stringval = NULL;
char_u *s = NULL;
int failed = FALSE;
+ int opt_p_flags;
+ char_u *tofree = NULL;

c1 = *p;
*p = NUL;

! 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
***************
*** 1410,1418 ****
n = (long)tv_get_number(tv);
}

// Avoid setting a string option to the text "v:false" or similar.
// In Vim9 script also don't convert a number to string.
! if (tv->v_type != VAR_BOOL && tv->v_type != VAR_SPECIAL
&& (!in_vim9script() || tv->v_type != VAR_NUMBER))
s = tv_get_string_chk(tv);

--- 1413,1432 ----
n = (long)tv_get_number(tv);
}

+ if (opt_p_flags & P_FUNC && (tv->v_type == VAR_PARTIAL
+ || tv->v_type == VAR_FUNC))
+ {
+ char_u numbuf[NUMBUFLEN];
+
+ // 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 = tv2string(tv, &tofree, numbuf, 0);
+ }
// Avoid setting a string option to the text "v:false" or similar.
// In Vim9 script also don't convert a number to string.
! else if (tv->v_type != VAR_BOOL && tv->v_type != VAR_SPECIAL
&& (!in_vim9script() || tv->v_type != VAR_NUMBER))
s = tv_get_string_chk(tv);

***************
*** 1458,1464 ****
{
if (opt_type != gov_string || s != NULL)
{
! set_option_value(arg, n, s, opt_flags);
arg_end = p;
}
else
--- 1472,1478 ----
{
if (opt_type != gov_string || s != NULL)
{
! set_option_value(arg, n, s, scope);
arg_end = p;
}
else
***************
*** 1466,1471 ****
--- 1480,1486 ----
}
*p = c1;
vim_free(stringval);
+ vim_free(tofree);
}
return arg_end;
}
*** ../vim-8.2.3750/src/if_mzsch.c 2021-08-02 17:07:15.186473836 +0100
--- src/if_mzsch.c 2021-12-06 10:56:44.687665026 +0000
***************
*** 1715,1721 ****
getoption_T rc;
Scheme_Object *rval = NULL;
Scheme_Object *name = NULL;
! int opt_flags = 0;
buf_T *save_curb = curbuf;
win_T *save_curw = curwin;

--- 1715,1721 ----
getoption_T rc;
Scheme_Object *rval = NULL;
Scheme_Object *name = NULL;
! int scope = 0;
buf_T *save_curb = curbuf;
win_T *save_curw = curwin;

***************
*** 1736,1746 ****
}

if (argv[1] == M_global)
! opt_flags = OPT_GLOBAL;
else if (SCHEME_VIMBUFFERP(argv[1]))
{
curbuf = get_valid_buffer(argv[1]);
! opt_flags = OPT_LOCAL;
}
else if (SCHEME_VIMWINDOWP(argv[1]))
{
--- 1736,1746 ----
}

if (argv[1] == M_global)
! scope = OPT_GLOBAL;
else if (SCHEME_VIMBUFFERP(argv[1]))
{
curbuf = get_valid_buffer(argv[1]);
! scope = OPT_LOCAL;
}
else if (SCHEME_VIMWINDOWP(argv[1]))
{
***************
*** 1748,1761 ****

curwin = win;
curbuf = win->w_buffer;
! opt_flags = OPT_LOCAL;
}
else
scheme_wrong_type(prim->name, "vim-buffer/window", 1, argc, argv);
}

rc = get_option_value(BYTE_STRING_VALUE(name), &value, (char_u **)&strval,
! opt_flags);
curbuf = save_curb;
curwin = save_curw;

--- 1748,1761 ----

curwin = win;
curbuf = win->w_buffer;
! scope = OPT_LOCAL;
}
else
scheme_wrong_type(prim->name, "vim-buffer/window", 1, argc, argv);
}

rc = get_option_value(BYTE_STRING_VALUE(name), &value, (char_u **)&strval,
! NULL, scope);
curbuf = save_curb;
curwin = save_curw;

***************
*** 1793,1799 ****
set_option(void *data, int argc, Scheme_Object **argv)
{
char_u *command = NULL;
! int opt_flags = 0;
buf_T *save_curb = curbuf;
win_T *save_curw = curwin;
Vim_Prim *prim = (Vim_Prim *)data;
--- 1793,1799 ----
set_option(void *data, int argc, Scheme_Object **argv)
{
char_u *command = NULL;
! int scope = 0;
buf_T *save_curb = curbuf;
win_T *save_curw = curwin;
Vim_Prim *prim = (Vim_Prim *)data;
***************
*** 1814,1831 ****
}

if (argv[1] == M_global)
! opt_flags = OPT_GLOBAL;
else if (SCHEME_VIMBUFFERP(argv[1]))
{
curbuf = get_valid_buffer(argv[1]);
! opt_flags = OPT_LOCAL;
}
else if (SCHEME_VIMWINDOWP(argv[1]))
{
win_T *win = get_valid_window(argv[1]);
curwin = win;
curbuf = win->w_buffer;
! opt_flags = OPT_LOCAL;
}
else
scheme_wrong_type(prim->name, "vim-buffer/window", 1, argc, argv);
--- 1814,1831 ----
}

if (argv[1] == M_global)
! scope = OPT_GLOBAL;
else if (SCHEME_VIMBUFFERP(argv[1]))
{
curbuf = get_valid_buffer(argv[1]);
! scope = OPT_LOCAL;
}
else if (SCHEME_VIMWINDOWP(argv[1]))
{
win_T *win = get_valid_window(argv[1]);
curwin = win;
curbuf = win->w_buffer;
! scope = OPT_LOCAL;
}
else
scheme_wrong_type(prim->name, "vim-buffer/window", 1, argc, argv);
***************
*** 1834,1840 ****
// do_set can modify cmd, make copy
command = vim_strsave(BYTE_STRING_VALUE(cmd));
MZ_GC_UNREG();
! do_set(command, opt_flags);
vim_free(command);
update_screen(NOT_VALID);
curbuf = save_curb;
--- 1834,1840 ----
// do_set can modify cmd, make copy
command = vim_strsave(BYTE_STRING_VALUE(cmd));
MZ_GC_UNREG();
! do_set(command, scope);
vim_free(command);
update_screen(NOT_VALID);
curbuf = save_curb;
*** ../vim-8.2.3750/src/if_ruby.c 2021-07-24 12:57:25.481296527 +0100
--- src/if_ruby.c 2021-12-06 10:41:05.780060960 +0000
***************
*** 875,881 ****
char_u *sval;
rb_encoding *enc;

! if (get_option_value((char_u *)"enc", &lval, &sval, 0) == gov_string)
{
enc = rb_enc_find((char *)sval);
vim_free(sval);
--- 875,881 ----
char_u *sval;
rb_encoding *enc;

! if (get_option_value((char_u *)"enc", &lval, &sval, NULL, 0) == gov_string)
{
enc = rb_enc_find((char *)sval);
vim_free(sval);
***************
*** 895,901 ****
rb_encoding *enc;
VALUE v;

! if (get_option_value((char_u *)"enc", &lval, &sval, 0) == gov_string)
{
enc = rb_enc_find((char *)sval);
vim_free(sval);
--- 895,901 ----
rb_encoding *enc;
VALUE v;

! if (get_option_value((char_u *)"enc", &lval, &sval, NULL, 0) == gov_string)
{
enc = rb_enc_find((char *)sval);
vim_free(sval);
*** ../vim-8.2.3750/src/if_tcl.c 2021-12-05 11:36:20.187448497 +0000
--- src/if_tcl.c 2021-12-06 10:41:05.780060960 +0000
***************
*** 1308,1314 ****

option = (char_u *)Tcl_GetStringFromObj(objv[objn], NULL);
++objn;
! gov = get_option_value(option, &lval, &sval, 0);
err = TCL_OK;
switch (gov)
{
--- 1308,1314 ----

option = (char_u *)Tcl_GetStringFromObj(objv[objn], NULL);
++objn;
! gov = get_option_value(option, &lval, &sval, NULL, 0);
err = TCL_OK;
switch (gov)
{
*** ../vim-8.2.3750/src/option.c 2021-12-03 20:43:20.088234242 +0000
--- src/option.c 2021-12-06 10:58:40.807472391 +0000
***************
*** 56,65 ****
static int put_setnum(FILE *fd, char *cmd, char *name, long *valuep);
static int put_setbool(FILE *fd, char *cmd, char *name, int value);
static int istermoption(struct vimoption *p);
! static char_u *get_varp_scope(struct vimoption *p, int opt_flags);
static char_u *get_varp(struct vimoption *);
static void check_win_options(win_T *win);
! static void option_value2string(struct vimoption *, int opt_flags);
static void check_winopt(winopt_T *wop);
static int wc_use_keyname(char_u *varp, long *wcp);
static void paste_option_changed(void);
--- 56,65 ----
static int put_setnum(FILE *fd, char *cmd, char *name, long *valuep);
static int put_setbool(FILE *fd, char *cmd, char *name, int value);
static int istermoption(struct vimoption *p);
! static char_u *get_varp_scope(struct vimoption *p, int scope);
static char_u *get_varp(struct vimoption *);
static void check_win_options(win_T *win);
! static void option_value2string(struct vimoption *, int scope);
static void check_winopt(winopt_T *wop);
static int wc_use_keyname(char_u *varp, long *wcp);
static void paste_option_changed(void);
***************
*** 3937,3949 ****
* Hidden Toggle option: gov_hidden_bool.
* Hidden String option: gov_hidden_string.
* Unknown option: gov_unknown.
*/
getoption_T
get_option_value(
char_u *name,
long *numval,
char_u **stringval, // NULL when only checking existence
! int opt_flags)
{
int opt_idx;
char_u *varp;
--- 3937,3952 ----
* Hidden Toggle option: gov_hidden_bool.
* Hidden String option: gov_hidden_string.
* Unknown option: gov_unknown.
+ *
+ * "flagsp" (if not NULL) is set to the option flags (P_xxxx).
*/
getoption_T
get_option_value(
char_u *name,
long *numval,
char_u **stringval, // NULL when only checking existence
! int *flagsp,
! int scope)
{
int opt_idx;
char_u *varp;
***************
*** 3981,3987 ****
return gov_unknown;
}

! varp = get_varp_scope(&(options[opt_idx]), opt_flags);

if (options[opt_idx].flags & P_STRING)
{
--- 3984,3994 ----
return gov_unknown;
}

! varp = 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)
{
***************
*** 5179,5195 ****

/*
* Get pointer to option variable, depending on local or global scope.
*/
static char_u *
! get_varp_scope(struct vimoption *p, int opt_flags)
{
! if ((opt_flags & OPT_GLOBAL) && p->indir != PV_NONE)
{
if (p->var == VAR_WIN)
return (char_u *)GLOBAL_WO(get_varp(p));
return p->var;
}
! if ((opt_flags & OPT_LOCAL) && ((int)p->indir & PV_BOTH))
{
switch ((int)p->indir)
{
--- 5186,5203 ----

/*
* Get pointer to option variable, depending on local or global scope.
+ * "scope" can be OPT_LOCAL, OPT_GLOBAL or a combination.
*/
static char_u *
! get_varp_scope(struct vimoption *p, int scope)
{
! if ((scope & OPT_GLOBAL) && p->indir != PV_NONE)
{
if (p->var == VAR_WIN)
return (char_u *)GLOBAL_WO(get_varp(p));
return p->var;
}
! if ((scope & OPT_LOCAL) && ((int)p->indir & PV_BOTH))
{
switch ((int)p->indir)
{
***************
*** 5248,5256 ****
* scope.
*/
char_u *
! get_option_varp_scope(int opt_idx, int opt_flags)
{
! return get_varp_scope(&(options[opt_idx]), opt_flags);
}

/*
--- 5256,5264 ----
* scope.
*/
char_u *
! get_option_varp_scope(int opt_idx, int scope)
{
! return get_varp_scope(&(options[opt_idx]), scope);
}

/*
***************
*** 6618,6628 ****
static void
option_value2string(
struct vimoption *opp,
! int opt_flags) // OPT_GLOBAL and/or OPT_LOCAL
{
char_u *varp;

! varp = get_varp_scope(opp, opt_flags);

if (opp->flags & P_NUM)
{
--- 6626,6636 ----
static void
option_value2string(
struct vimoption *opp,
! int scope) // OPT_GLOBAL and/or OPT_LOCAL
{
char_u *varp;

! varp = get_varp_scope(opp, scope);

if (opp->flags & P_NUM)
{
*** ../vim-8.2.3750/src/option.h 2021-11-29 20:39:06.682101619 +0000
--- src/option.h 2021-12-06 10:41:05.784060967 +0000
***************
*** 59,64 ****
--- 59,65 ----
#define P_NDNAME 0x8000000L // only normal dir name chars allowed
#define P_RWINONLY 0x10000000L // only redraw current window
#define P_MLE 0x20000000L // under control of 'modelineexpr'
+ #define P_FUNC 0x40000000L // accept a function reference or a lambda

// Returned by get_option_value().
typedef enum {
*** ../vim-8.2.3750/src/optiondefs.h 2021-11-29 20:39:06.682101619 +0000
--- src/optiondefs.h 2021-12-06 10:41:05.784060967 +0000
***************
*** 684,690 ****
#endif
{(char_u *)0L, (char_u *)0L}
SCTX_INIT},
! {"completefunc", "cfu", P_STRING|P_ALLOCED|P_VI_DEF|P_SECURE,
#ifdef FEAT_COMPL_FUNC
(char_u *)&p_cfu, PV_CFU,
{(char_u *)"", (char_u *)0L}
--- 684,690 ----
#endif
{(char_u *)0L, (char_u *)0L}
SCTX_INIT},
! {"completefunc", "cfu", P_STRING|P_ALLOCED|P_VI_DEF|P_SECURE|P_FUNC,
#ifdef FEAT_COMPL_FUNC
(char_u *)&p_cfu, PV_CFU,
{(char_u *)"", (char_u *)0L}
***************
*** 1321,1327 ****
{"ignorecase", "ic", P_BOOL|P_VI_DEF,
(char_u *)&p_ic, PV_NONE,
{(char_u *)FALSE, (char_u *)0L} SCTX_INIT},
! {"imactivatefunc","imaf",P_STRING|P_VI_DEF|P_SECURE,
#if defined(FEAT_EVAL)
(char_u *)&p_imaf, PV_NONE,
{(char_u *)"", (char_u *)NULL}
--- 1321,1327 ----
{"ignorecase", "ic", P_BOOL|P_VI_DEF,
(char_u *)&p_ic, PV_NONE,
{(char_u *)FALSE, (char_u *)0L} SCTX_INIT},
! {"imactivatefunc","imaf",P_STRING|P_VI_DEF|P_SECURE|P_FUNC,
#if defined(FEAT_EVAL)
(char_u *)&p_imaf, PV_NONE,
{(char_u *)"", (char_u *)NULL}
***************
*** 1356,1362 ****
(char_u *)&p_imsearch, PV_IMS,
{(char_u *)B_IMODE_USE_INSERT, (char_u *)0L}
SCTX_INIT},
! {"imstatusfunc","imsf",P_STRING|P_VI_DEF|P_SECURE,
#if defined(FEAT_EVAL)
(char_u *)&p_imsf, PV_NONE,
{(char_u *)"", (char_u *)NULL}
--- 1356,1362 ----
(char_u *)&p_imsearch, PV_IMS,
{(char_u *)B_IMODE_USE_INSERT, (char_u *)0L}
SCTX_INIT},
! {"imstatusfunc","imsf",P_STRING|P_VI_DEF|P_SECURE|P_FUNC,
#if defined(FEAT_EVAL)
(char_u *)&p_imsf, PV_NONE,
{(char_u *)"", (char_u *)NULL}
***************
*** 1822,1828 ****
(char_u *)NULL, PV_NONE,
#endif
{(char_u *)8L, (char_u *)4L} SCTX_INIT},
! {"omnifunc", "ofu", P_STRING|P_ALLOCED|P_VI_DEF|P_SECURE,
#ifdef FEAT_COMPL_FUNC
(char_u *)&p_ofu, PV_OFU,
{(char_u *)"", (char_u *)0L}
--- 1822,1828 ----
(char_u *)NULL, PV_NONE,
#endif
{(char_u *)8L, (char_u *)4L} SCTX_INIT},
! {"omnifunc", "ofu", P_STRING|P_ALLOCED|P_VI_DEF|P_SECURE|P_FUNC,
#ifdef FEAT_COMPL_FUNC
(char_u *)&p_ofu, PV_OFU,
{(char_u *)"", (char_u *)0L}
***************
*** 1842,1848 ****
#endif
{(char_u *)FALSE, (char_u *)FALSE}
SCTX_INIT},
! {"operatorfunc", "opfunc", P_STRING|P_VI_DEF|P_SECURE,
(char_u *)&p_opfunc, PV_NONE,
{(char_u *)"", (char_u *)0L} SCTX_INIT},
{"optimize", "opt", P_BOOL|P_VI_DEF,
--- 1842,1848 ----
#endif
{(char_u *)FALSE, (char_u *)FALSE}
SCTX_INIT},
! {"operatorfunc", "opfunc", P_STRING|P_VI_DEF|P_SECURE|P_FUNC,
(char_u *)&p_opfunc, PV_NONE,
{(char_u *)"", (char_u *)0L} SCTX_INIT},
{"optimize", "opt", P_BOOL|P_VI_DEF,
***************
*** 2055,2061 ****
#endif
{(char_u *)DEFAULT_PYTHON_VER, (char_u *)0L}
SCTX_INIT},
! {"quickfixtextfunc", "qftf", P_STRING|P_ALLOCED|P_VI_DEF|P_VIM|P_SECURE,
#if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL)
(char_u *)&p_qftf, PV_NONE,
{(char_u *)"", (char_u *)0L}
--- 2055,2061 ----
#endif
{(char_u *)DEFAULT_PYTHON_VER, (char_u *)0L}
SCTX_INIT},
! {"quickfixtextfunc", "qftf", P_STRING|P_ALLOCED|P_VI_DEF|P_VIM|P_SECURE|P_FUNC,
#if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL)
(char_u *)&p_qftf, PV_NONE,
{(char_u *)"", (char_u *)0L}
***************
*** 2507,2513 ****
{"tagcase", "tc", P_STRING|P_VIM,
(char_u *)&p_tc, PV_TC,
{(char_u *)"followic", (char_u *)"followic"} SCTX_INIT},
! {"tagfunc", "tfu", P_STRING|P_ALLOCED|P_VI_DEF|P_SECURE,
#ifdef FEAT_EVAL
(char_u *)&p_tfu, PV_TFU,
{(char_u *)"", (char_u *)0L}
--- 2507,2513 ----
{"tagcase", "tc", P_STRING|P_VIM,
(char_u *)&p_tc, PV_TC,
{(char_u *)"followic", (char_u *)"followic"} SCTX_INIT},
! {"tagfunc", "tfu", P_STRING|P_ALLOCED|P_VI_DEF|P_SECURE|P_FUNC,
#ifdef FEAT_EVAL
(char_u *)&p_tfu, PV_TFU,
{(char_u *)"", (char_u *)0L}
***************
*** 2624,2630 ****
{"thesaurus", "tsr", P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA|P_NODUP|P_NDNAME,
(char_u *)&p_tsr, PV_TSR,
{(char_u *)"", (char_u *)0L} SCTX_INIT},
! {"thesaurusfunc", "tsrfu", P_STRING|P_ALLOCED|P_VI_DEF|P_SECURE,
#ifdef FEAT_COMPL_FUNC
(char_u *)&p_tsrfu, PV_TSRFU,
{(char_u *)"", (char_u *)0L}
--- 2624,2630 ----
{"thesaurus", "tsr", P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA|P_NODUP|P_NDNAME,
(char_u *)&p_tsr, PV_TSR,
{(char_u *)"", (char_u *)0L} SCTX_INIT},
! {"thesaurusfunc", "tsrfu", P_STRING|P_ALLOCED|P_VI_DEF|P_SECURE|P_FUNC,
#ifdef FEAT_COMPL_FUNC
(char_u *)&p_tsrfu, PV_TSRFU,
{(char_u *)"", (char_u *)0L}
*** ../vim-8.2.3750/src/proto/option.pro 2021-11-18 22:08:52.007682711 +0000
--- src/proto/option.pro 2021-12-06 11:01:31.739165582 +0000
***************
*** 25,31 ****
void set_term_option_sctx_idx(char *name, int opt_idx);
void check_redraw(long_u flags);
int findoption(char_u *arg);
! getoption_T get_option_value(char_u *name, long *numval, char_u **stringval, int opt_flags);
int get_option_value_strict(char_u *name, long *numval, char_u **stringval, int opt_type, void *from);
char_u *option_iter_next(void **option, int opt_type);
long_u get_option_flags(int opt_idx);
--- 25,31 ----
void set_term_option_sctx_idx(char *name, int opt_idx);
void check_redraw(long_u flags);
int findoption(char_u *arg);
! getoption_T get_option_value(char_u *name, long *numval, char_u **stringval, int *flagsp, int scope);
int get_option_value_strict(char_u *name, long *numval, char_u **stringval, int opt_type, void *from);
char_u *option_iter_next(void **option, int opt_type);
long_u get_option_flags(int opt_idx);
***************
*** 48,54 ****
void set_term_defaults(void);
int istermoption_idx(int opt_idx);
void unset_global_local_option(char_u *name, void *from);
! char_u *get_option_varp_scope(int opt_idx, int opt_flags);
char_u *get_option_var(int opt_idx);
char_u *get_option_fullname(int opt_idx);
char_u *get_equalprg(void);
--- 48,54 ----
void set_term_defaults(void);
int istermoption_idx(int opt_idx);
void unset_global_local_option(char_u *name, void *from);
! char_u *get_option_varp_scope(int opt_idx, int scope);
char_u *get_option_var(int opt_idx);
char_u *get_option_fullname(int opt_idx);
char_u *get_equalprg(void);
*** ../vim-8.2.3750/src/spell.c 2021-08-09 18:59:01.442811242 +0100
--- src/spell.c 2021-12-06 10:41:05.784060967 +0000
***************
*** 3830,3836 ****

if (no_spell_checking(curwin))
return;
! (void)get_option_value((char_u*)"spl", &dummy, &spl, OPT_LOCAL);

// Create a new empty buffer in a new window.
do_cmdline_cmd((char_u *)"new");
--- 3830,3836 ----

if (no_spell_checking(curwin))
return;
! (void)get_option_value((char_u*)"spl", &dummy, &spl, NULL, OPT_LOCAL);

// Create a new empty buffer in a new window.
do_cmdline_cmd((char_u *)"new");
*** ../vim-8.2.3750/src/typval.c 2021-11-30 11:56:19.030972202 +0000
--- src/typval.c 2021-12-06 10:54:14.087889527 +0000
***************
*** 1639,1648 ****
int c;
int working = (**arg == '+'); // has("+option")
int ret = OK;
! int opt_flags;

// Isolate the option name and find its value.
! option_end = find_option_end(arg, &opt_flags);
if (option_end == NULL)
{
if (rettv != NULL)
--- 1639,1648 ----
int c;
int working = (**arg == '+'); // has("+option")
int ret = OK;
! int scope;

// Isolate the option name and find its value.
! option_end = find_option_end(arg, &scope);
if (option_end == NULL)
{
if (rettv != NULL)
***************
*** 1659,1665 ****
c = *option_end;
*option_end = NUL;
opt_type = get_option_value(*arg, &numval,
! rettv == NULL ? NULL : &stringval, opt_flags);

if (opt_type == gov_unknown)
{
--- 1659,1665 ----
c = *option_end;
*option_end = NUL;
opt_type = get_option_value(*arg, &numval,
! rettv == NULL ? NULL : &stringval, NULL, scope);

if (opt_type == gov_unknown)
{
*** ../vim-8.2.3750/src/vim9compile.c 2021-12-04 11:56:30.352101259 +0000
--- src/vim9compile.c 2021-12-06 10:55:29.979780418 +0000
***************
*** 6072,6078 ****
/*
* For one assignment figure out the type of destination. Return it in "dest".
* When not recognized "dest" is not set.
! * For an option "opt_flags" is set.
* For a v:var "vimvaridx" is set.
* "type" is set to the destination type if known, unchanted otherwise.
* Return FAIL if an error message was given.
--- 6072,6078 ----
/*
* For one assignment figure out the type of destination. Return it in "dest".
* When not recognized "dest" is not set.
! * For an option "option_scope" is set.
* For a v:var "vimvaridx" is set.
* "type" is set to the destination type if known, unchanted otherwise.
* Return FAIL if an error message was given.
***************
*** 6082,6088 ****
char_u *name,
assign_dest_T *dest,
int cmdidx,
! int *opt_flags,
int *vimvaridx,
type_T **type,
cctx_T *cctx)
--- 6082,6088 ----
char_u *name,
assign_dest_T *dest,
int cmdidx,
! int *option_scope,
int *vimvaridx,
type_T **type,
cctx_T *cctx)
***************
*** 6102,6108 ****
return FAIL;
}
p = name;
! p = find_option_end(&p, opt_flags);
if (p == NULL)
{
// cannot happen?
--- 6102,6108 ----
return FAIL;
}
p = name;
! p = find_option_end(&p, option_scope);
if (p == NULL)
{
// cannot happen?
***************
*** 6112,6118 ****
cc = *p;
*p = NUL;
opt_type = get_option_value(skip_option_env_lead(name),
! &numval, NULL, *opt_flags);
*p = cc;
switch (opt_type)
{
--- 6112,6118 ----
cc = *p;
*p = NUL;
opt_type = get_option_value(skip_option_env_lead(name),
! &numval, NULL, NULL, *option_scope);
*p = cc;
switch (opt_type)
{
*** ../vim-8.2.3750/src/testdir/test_iminsert.vim 2021-12-04 14:02:25.457024636 +0000
--- src/testdir/test_iminsert.vim 2021-12-06 10:41:05.784060967 +0000
***************
*** 130,141 ****

" Using a funcref variable to set 'completefunc'
let Fn1 = function('IMactivatefunc1')
! let &imactivatefunc = string(Fn1)
let Fn2 = function('IMstatusfunc1')
let &imstatusfunc = string(Fn2)
normal! i
- call assert_fails('let &imactivatefunc = Fn1', 'E729:')
- call assert_fails('let &imstatusfunc = Fn2', 'E729:')

" Test for using a funcref()
set imactivatefunc=funcref('IMactivatefunc1')
--- 130,144 ----

" Using a funcref variable to set 'completefunc'
let Fn1 = function('IMactivatefunc1')
! let &imactivatefunc = Fn1
let Fn2 = function('IMstatusfunc1')
+ let &imstatusfunc = Fn2
+ normal! i
+
+ " Using a string(funcref variable) to set 'completefunc'
+ let &imactivatefunc = string(Fn1)
let &imstatusfunc = string(Fn2)
normal! i

" Test for using a funcref()
set imactivatefunc=funcref('IMactivatefunc1')
***************
*** 144,155 ****

" Using a funcref variable to set 'imactivatefunc'
let Fn1 = funcref('IMactivatefunc1')
! let &imactivatefunc = string(Fn1)
let Fn2 = funcref('IMstatusfunc1')
let &imstatusfunc = string(Fn2)
normal! i
- call assert_fails('let &imactivatefunc = Fn1', 'E729:')
- call assert_fails('let &imstatusfunc = Fn2', 'E729:')

" Test for using a lambda function
set imactivatefunc={a\ ->\ IMactivatefunc1(a)}
--- 147,161 ----

" Using a funcref variable to set 'imactivatefunc'
let Fn1 = funcref('IMactivatefunc1')
! let &imactivatefunc = Fn1
let Fn2 = funcref('IMstatusfunc1')
+ let &imstatusfunc = Fn2
+ normal! i
+
+ " Using a string(funcref variable) to set 'imactivatefunc'
+ let &imactivatefunc = string(Fn1)
let &imstatusfunc = string(Fn2)
normal! i

" Test for using a lambda function
set imactivatefunc={a\ ->\ IMactivatefunc1(a)}
***************
*** 157,162 ****
--- 163,173 ----
normal! i

" Set 'imactivatefunc' and 'imstatusfunc' to a lambda expression
+ let &imactivatefunc = {a -> IMactivatefunc1(a)}
+ let &imstatusfunc = { -> IMstatusfunc1()}
+ normal! i
+
+ " Set 'imactivatefunc' and 'imstatusfunc' to a string(lambda expression)
let &imactivatefunc = '{a -> IMactivatefunc1(a)}'
let &imstatusfunc = '{ -> IMstatusfunc1()}'
normal! i
***************
*** 164,174 ****
" Set 'imactivatefunc' 'imstatusfunc' to a variable with a lambda expression
let Lambda1 = {a -> IMactivatefunc1(a)}
let Lambda2 = { -> IMstatusfunc1()}
let &imactivatefunc = string(Lambda1)
let &imstatusfunc = string(Lambda2)
normal! i
- call assert_fails('let &imactivatefunc = Lambda1', 'E729:')
- call assert_fails('let &imstatusfunc = Lambda2', 'E729:')

" Test for clearing the 'completefunc' option
set imactivatefunc='' imstatusfunc=''
--- 175,189 ----
" Set 'imactivatefunc' 'imstatusfunc' to a variable with a lambda expression
let Lambda1 = {a -> IMactivatefunc1(a)}
let Lambda2 = { -> IMstatusfunc1()}
+ let &imactivatefunc = Lambda1
+ let &imstatusfunc = Lambda2
+ normal! i
+
+ " Set 'imactivatefunc' 'imstatusfunc' to a string(variable with a lambda
+ " expression)
let &imactivatefunc = string(Lambda1)
let &imstatusfunc = string(Lambda2)
normal! i

" Test for clearing the 'completefunc' option
set imactivatefunc='' imstatusfunc=''
***************
*** 179,186 ****
call assert_fails("set imactivatefunc=funcref('abc')", "E700:")
call assert_fails("set imstatusfunc=funcref('abc')", "E700:")

! call assert_equal(7, g:IMactivatefunc_called)
! call assert_equal(14, g:IMstatusfunc_called)

" Vim9 tests
let lines =<< trim END
--- 194,201 ----
call assert_fails("set imactivatefunc=funcref('abc')", "E700:")
call assert_fails("set imstatusfunc=funcref('abc')", "E700:")

! call assert_equal(11, g:IMactivatefunc_called)
! call assert_equal(22, g:IMstatusfunc_called)

" Vim9 tests
let lines =<< trim END
***************
*** 216,227 ****
g:IMstatusfunc_called += 1
return 1
}
&imactivatefunc = string(Fn1)
&imstatusfunc = string(Fn2)
normal! i

! assert_equal(3, g:IMactivatefunc_called)
! assert_equal(6, g:IMstatusfunc_called)

set iminsert=0
set imactivatefunc=
--- 231,247 ----
g:IMstatusfunc_called += 1
return 1
}
+ &imactivatefunc = Fn1
+ &imstatusfunc = Fn2
+ normal! i
+
+ # Test for using a string(variable with a lambda expression)
&imactivatefunc = string(Fn1)
&imstatusfunc = string(Fn2)
normal! i

! assert_equal(4, g:IMactivatefunc_called)
! assert_equal(8, g:IMstatusfunc_called)

set iminsert=0
set imactivatefunc=
*** ../vim-8.2.3750/src/testdir/test_ins_complete.vim 2021-12-04 14:02:25.457024636 +0000
--- src/testdir/test_ins_complete.vim 2021-12-06 10:41:05.784060967 +0000
***************
*** 885,897 ****

" Using a 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()
--- 885,906 ----

" 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)
bw!

" Test for using a funcref()
***************
*** 909,921 ****

" Using a 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
--- 918,939 ----

" 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)
bw!

" Test for using a lambda function
***************
*** 932,937 ****
--- 950,964 ----
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')
***************
*** 942,959 ****

" Set 'completefunc' to a 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)
new | only
call setline(1, 'eight')
call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
--- 969,995 ----

" 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)
bw!

" Test for using a lambda function with incorrect return value
let Lambda = {s -> strlen(s)}
! let &completefunc = Lambda
new | only
call setline(1, 'eight')
call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
***************
*** 965,971 ****

call assert_fails("set completefunc=function('abc')", "E700:")
call assert_fails("set completefunc=funcref('abc')", "E700:")
! let &completefunc = "{a -> 'abc'}"
call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')

" Vim9 tests
--- 1001,1007 ----

call assert_fails("set completefunc=function('abc')", "E700:")
call assert_fails("set completefunc=funcref('abc')", "E700:")
! let &completefunc = {a -> 'abc'}
call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')

" Vim9 tests
***************
*** 990,995 ****
--- 1026,1040 ----
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')
***************
*** 1003,1008 ****
--- 1048,1062 ----
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')
***************
*** 1045,1057 ****

" Using a 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()
--- 1099,1120 ----

" 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)
bw!

" Test for using a funcref()
***************
*** 1069,1081 ****

" Using a 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
--- 1132,1153 ----

" 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)
bw!

" Test for using a lambda function
***************
*** 1092,1097 ****
--- 1164,1178 ----
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')
***************
*** 1102,1119 ****

" Set 'omnifunc' to a 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)
new | only
call setline(1, 'eight')
call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
--- 1183,1209 ----

" 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)
bw!

" Test for using a lambda function with incorrect return value
let Lambda = {s -> strlen(s)}
! let &omnifunc = Lambda
new | only
call setline(1, 'eight')
call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
***************
*** 1125,1131 ****

call assert_fails("set omnifunc=function('abc')", "E700:")
call assert_fails("set omnifunc=funcref('abc')", "E700:")
! let &omnifunc = "{a -> 'abc'}"
call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')

" Vim9 tests
--- 1215,1221 ----

call assert_fails("set omnifunc=function('abc')", "E700:")
call assert_fails("set omnifunc=funcref('abc')", "E700:")
! let &omnifunc = {a -> 'abc'}
call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')

" Vim9 tests
***************
*** 1150,1155 ****
--- 1240,1254 ----
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')
***************
*** 1160,1165 ****
--- 1259,1273 ----

# 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')
***************
*** 1202,1214 ****

" Using a 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()
--- 1310,1331 ----

" 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)
bw!

" Test for using a funcref()
***************
*** 1226,1238 ****

" Using a 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
--- 1343,1364 ----

" 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)
bw!

" Test for using a lambda function
***************
*** 1249,1254 ****
--- 1375,1389 ----
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')
***************
*** 1259,1276 ****

" Set 'thesaurusfunc' to a 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)
new | only
call setline(1, 'eight')
call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
--- 1394,1420 ----

" 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)
bw!

" Test for using a lambda function with incorrect return value
let Lambda = {s -> strlen(s)}
! let &thesaurusfunc = Lambda
new | only
call setline(1, 'eight')
call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
***************
*** 1282,1288 ****

call assert_fails("set thesaurusfunc=function('abc')", "E700:")
call assert_fails("set thesaurusfunc=funcref('abc')", "E700:")
! let &thesaurusfunc = "{a -> 'abc'}"
call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')

" Vim9 tests
--- 1426,1432 ----

call assert_fails("set thesaurusfunc=function('abc')", "E700:")
call assert_fails("set thesaurusfunc=funcref('abc')", "E700:")
! let &thesaurusfunc = {a -> 'abc'}
call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')

" Vim9 tests
***************
*** 1307,1312 ****
--- 1451,1465 ----
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')
***************
*** 1317,1322 ****
--- 1470,1484 ----

# 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')
*** ../vim-8.2.3750/src/testdir/test_tagfunc.vim 2021-12-03 11:08:34.260842706 +0000
--- src/testdir/test_tagfunc.vim 2021-12-06 10:41:05.784060967 +0000
***************
*** 140,151 ****

" Using a 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)
--- 140,158 ----

" 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)

" Test for using a funcref()
func MytagFunc2(pat, flags, info)
***************
*** 160,171 ****

" Using a 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
--- 167,185 ----

" 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)

" Test for using a script local function
set tagfunc=<SID>ScriptLocalTagFunc
***************
*** 176,181 ****
--- 190,203 ----

" 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 = []
***************
*** 194,199 ****
--- 216,228 ----
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 = []
***************
*** 202,213 ****

" Set 'tagfunc' to a 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)}
--- 231,249 ----

" 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)

" Test for using a lambda function with incorrect return value
let Lambda = {s -> strlen(s)}
***************
*** 244,249 ****
--- 280,292 ----
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 = []
***************
*** 252,257 ****
--- 295,307 ----

# 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 = []
*** ../vim-8.2.3750/src/version.c 2021-12-05 22:19:22.840153470 +0000
--- src/version.c 2021-12-06 10:45:32.884284965 +0000
***************
*** 755,756 ****
--- 755,758 ----
{ /* Add new patch number below this line */
+ /**/
+ 3751,
/**/

--
I used to be indecisive, now I'm not sure.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages