diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-04-14 14:24:50 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2023-04-14 16:10:09 +0800 |
commit | cf37630d1b1443427c13e0a35e0a12b39e1415db (patch) | |
tree | ebc8ce38d5153eba2caa4cc83bf65a4f3753ddd6 | |
parent | 9c65a18753404ec0419bac45969be6c9e5a2fbb6 (diff) | |
download | rneovim-cf37630d1b1443427c13e0a35e0a12b39e1415db.tar.gz rneovim-cf37630d1b1443427c13e0a35e0a12b39e1415db.tar.bz2 rneovim-cf37630d1b1443427c13e0a35e0a12b39e1415db.zip |
vim-patch:8.2.1110: Vim9: line continuation does not work in function arguments
Problem: Vim9: line continuation does not work in function arguments.
Solution: Pass "evalarg" to get_func_tv(). Fix seeing double quoted string
as comment.
https://github.com/vim/vim/commit/e6b5324e3a3d354363f3c48e784c42ce3e77453f
Omit skipwhite_and_linebreak_keep_string(): Vim9 script only.
Co-authored-by: Bram Moolenaar <Bram@vim.org>
-rw-r--r-- | src/nvim/eval.c | 37 | ||||
-rw-r--r-- | src/nvim/eval/userfunc.c | 15 | ||||
-rw-r--r-- | src/nvim/ex_eval.c | 10 |
3 files changed, 32 insertions, 30 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index ed1a49f08d..907e380b85 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -692,7 +692,7 @@ void eval_patch(const char *const origfile, const char *const difffile, const ch set_vim_var_string(VV_FNAME_OUT, NULL, -1); } -static void fill_evalarg_from_eap(evalarg_T *evalarg, exarg_T *eap, bool skip) +void fill_evalarg_from_eap(evalarg_T *evalarg, exarg_T *eap, bool skip) { *evalarg = (evalarg_T){ .eval_flags = skip ? 0 : EVAL_EVALUATE }; if (eap != NULL && getline_equal(eap->getline, eap->cookie, getsourceline)) { @@ -2206,9 +2206,10 @@ int pattern_match(const char *pat, const char *text, bool ic) /// @param basetv "expr" for "expr->name(arg)" /// /// @return OK or FAIL. -static int eval_func(char **const arg, char *const name, const int name_len, typval_T *const rettv, - const int flags, typval_T *const basetv) - FUNC_ATTR_NONNULL_ARG(1, 2, 4) +static int eval_func(char **const arg, evalarg_T *const evalarg, char *const name, + const int name_len, typval_T *const rettv, const int flags, + typval_T *const basetv) + FUNC_ATTR_NONNULL_ARG(1, 3, 5) { const bool evaluate = flags & EVAL_EVALUATE; char *s = name; @@ -2234,7 +2235,7 @@ static int eval_func(char **const arg, char *const name, const int name_len, typ funcexe.fe_evaluate = evaluate; funcexe.fe_partial = partial; funcexe.fe_basetv = basetv; - int ret = get_func_tv(s, len, rettv, arg, &funcexe); + int ret = get_func_tv(s, len, rettv, arg, evalarg, &funcexe); xfree(s); @@ -3089,7 +3090,7 @@ static int eval7(char **arg, typval_T *rettv, evalarg_T *const evalarg, bool wan ret = FAIL; } else { if (**arg == '(') { // recursive! - ret = eval_func(arg, s, len, rettv, flags, NULL); + ret = eval_func(arg, evalarg, s, len, rettv, flags, NULL); } else if (evaluate) { ret = get_var_tv(s, len, rettv, NULL, true, false); } else { @@ -3181,10 +3182,10 @@ static int eval7_leader(typval_T *const rettv, const bool numeric_only, /// to the name of the Lua function to call (after the /// "v:lua." prefix). /// @return OK on success, FAIL on failure. -static int call_func_rettv(char **const arg, typval_T *const rettv, const bool evaluate, - dict_T *const selfdict, typval_T *const basetv, +static int call_func_rettv(char **const arg, evalarg_T *const evalarg, typval_T *const rettv, + const bool evaluate, dict_T *const selfdict, typval_T *const basetv, const char *const lua_funcname) - FUNC_ATTR_NONNULL_ARG(1, 2) + FUNC_ATTR_NONNULL_ARG(1, 3) { partial_T *pt = NULL; typval_T functv; @@ -3216,7 +3217,7 @@ static int call_func_rettv(char **const arg, typval_T *const rettv, const bool e funcexe.fe_selfdict = selfdict; funcexe.fe_basetv = basetv; const int ret = get_func_tv(funcname, is_lua ? (int)(*arg - funcname) : -1, rettv, - arg, &funcexe); + arg, evalarg, &funcexe); // Clear the funcref afterwards, so that deleting it while // evaluating the arguments is possible (see test55). @@ -3259,7 +3260,7 @@ static int eval_lambda(char **const arg, typval_T *const rettv, evalarg_T *const tv_clear(rettv); ret = FAIL; } else { - ret = call_func_rettv(arg, rettv, evaluate, NULL, &base, NULL); + ret = call_func_rettv(arg, evalarg, rettv, evaluate, NULL, &base, NULL); } // Clear the funcref afterwards, so that deleting it while @@ -3276,10 +3277,12 @@ static int eval_lambda(char **const arg, typval_T *const rettv, evalarg_T *const /// @param *arg points to the '-'. /// /// @return FAIL or OK. "*arg" is advanced to after the ')'. -static int eval_method(char **const arg, typval_T *const rettv, const bool evaluate, +static int eval_method(char **const arg, typval_T *const rettv, evalarg_T *const evalarg, const bool verbose) - FUNC_ATTR_NONNULL_ALL + FUNC_ATTR_NONNULL_ARG(1, 2) { + const bool evaluate = evalarg != NULL && (evalarg->eval_flags & EVAL_EVALUATE); + // Skip over the ->. *arg += 2; typval_T base = *rettv; @@ -3329,9 +3332,9 @@ static int eval_method(char **const arg, typval_T *const rettv, const bool evalu rettv->vval.v_partial = vvlua_partial; rettv->vval.v_partial->pt_refcount++; } - ret = call_func_rettv(arg, rettv, evaluate, NULL, &base, lua_funcname); + ret = call_func_rettv(arg, evalarg, rettv, evaluate, NULL, &base, lua_funcname); } else { - ret = eval_func(arg, name, len, rettv, evaluate ? EVAL_EVALUATE : 0, &base); + ret = eval_func(arg, evalarg, name, len, rettv, evaluate ? EVAL_EVALUATE : 0, &base); } } @@ -7081,7 +7084,7 @@ int handle_subscript(const char **const arg, typval_T *rettv, evalarg_T *const e && !ascii_iswhite(*(*arg - 1))) || (**arg == '-' && (*arg)[1] == '>'))) { if (**arg == '(') { - ret = call_func_rettv((char **)arg, rettv, evaluate, selfdict, NULL, lua_funcname); + ret = call_func_rettv((char **)arg, evalarg, rettv, evaluate, selfdict, NULL, lua_funcname); // Stop the expression evaluation when immediately aborting on // error, or when an interrupt occurred or an exception was thrown @@ -7100,7 +7103,7 @@ int handle_subscript(const char **const arg, typval_T *rettv, evalarg_T *const e ret = eval_lambda((char **)arg, rettv, evalarg, verbose); } else { // expr->name() - ret = eval_method((char **)arg, rettv, evaluate, verbose); + ret = eval_method((char **)arg, rettv, evalarg, verbose); } } else { // **arg == '[' || **arg == '.' tv_dict_unref(selfdict); diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index 1f25b7fb36..3fc34471bf 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -458,15 +458,14 @@ void emsg_funcname(const char *errmsg, const char *name) /// @param funcexe various values /// /// @return OK or FAIL. -int get_func_tv(const char *name, int len, typval_T *rettv, char **arg, funcexe_T *funcexe) +int get_func_tv(const char *name, int len, typval_T *rettv, char **arg, evalarg_T *const evalarg, + funcexe_T *funcexe) { char *argp; int ret = OK; typval_T argvars[MAX_FUNC_ARGS + 1]; // vars for arguments int argcount = 0; // number of arguments found - evalarg_T evalarg = { .eval_flags = funcexe->fe_evaluate ? EVAL_EVALUATE : 0 }; - // Get the arguments. argp = *arg; while (argcount < MAX_FUNC_ARGS @@ -475,7 +474,7 @@ int get_func_tv(const char *name, int len, typval_T *rettv, char **arg, funcexe_ if (*argp == ')' || *argp == ',' || *argp == NUL) { break; } - if (eval1(&argp, &argvars[argcount], &evalarg) == FAIL) { + if (eval1(&argp, &argvars[argcount], evalarg) == FAIL) { ret = FAIL; break; } @@ -3013,16 +3012,19 @@ void ex_call(exarg_T *eap) bool failed = false; funcdict_T fudi; partial_T *partial = NULL; + evalarg_T evalarg; + fill_evalarg_from_eap(&evalarg, eap, eap->skip); if (eap->skip) { // trans_function_name() doesn't work well when skipping, use eval0() // instead to skip to any following command, e.g. for: // :if 0 | call dict.foo().bar() | endif. emsg_skip++; - if (eval0(eap->arg, &rettv, eap, NULL) != FAIL) { + if (eval0(eap->arg, &rettv, eap, &evalarg) != FAIL) { tv_clear(&rettv); } emsg_skip--; + clear_evalarg(&evalarg, eap); return; } @@ -3080,7 +3082,7 @@ void ex_call(exarg_T *eap) funcexe.fe_evaluate = true; funcexe.fe_partial = partial; funcexe.fe_selfdict = fudi.fd_dict; - if (get_func_tv(name, -1, &rettv, &arg, &funcexe) == FAIL) { + if (get_func_tv(name, -1, &rettv, &arg, &evalarg, &funcexe) == FAIL) { failed = true; break; } @@ -3118,6 +3120,7 @@ void ex_call(exarg_T *eap) eap->nextcmd = check_nextcmd(arg); } } + clear_evalarg(&evalarg, eap); end: tv_dict_unref(fudi.fd_dict); diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c index 34015728b0..63ead3550f 100644 --- a/src/nvim/ex_eval.c +++ b/src/nvim/ex_eval.c @@ -792,13 +792,9 @@ void report_discard_pending(int pending, void *value) void ex_eval(exarg_T *eap) { typval_T tv; - evalarg_T evalarg = { - .eval_flags = eap->skip ? 0 : EVAL_EVALUATE, - }; - if (getline_equal(eap->getline, eap->cookie, getsourceline)) { - evalarg.eval_getline = eap->getline; - evalarg.eval_cookie = eap->cookie; - } + evalarg_T evalarg; + + fill_evalarg_from_eap(&evalarg, eap, eap->skip); if (eval0(eap->arg, &tv, eap, &evalarg) == OK) { tv_clear(&tv); |