To: vim_dev@googlegroups.com Subject: Patch 8.2.3751 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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. "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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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\\\", '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=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=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 -- Bram@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 ///