diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-04-14 13:49:28 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2023-04-14 16:10:09 +0800 |
commit | 8729c41f44de3b164ad8d01bb3558c6400e27952 (patch) | |
tree | 9c611cef6c60a7522e9cbaf47d90a8c937f9a385 | |
parent | 4b84b2e2aa3d7ab6a4e346c7439826700682f5f1 (diff) | |
download | rneovim-8729c41f44de3b164ad8d01bb3558c6400e27952.tar.gz rneovim-8729c41f44de3b164ad8d01bb3558c6400e27952.tar.bz2 rneovim-8729c41f44de3b164ad8d01bb3558c6400e27952.zip |
vim-patch:8.2.1080: Vim9: no line break allowed in a for loop
Problem: Vim9: no line break allowed in a for loop.
Solution: Skip line breaks in for command.
https://github.com/vim/vim/commit/b7a78f7a6713f07d2fcad0b27dea22925c7b1cdf
Omit *_break_count and skip_for_lines(): Vim9 script only.
Co-authored-by: Bram Moolenaar <Bram@vim.org>
-rw-r--r-- | src/nvim/api/vimscript.c | 2 | ||||
-rw-r--r-- | src/nvim/debugger.c | 2 | ||||
-rw-r--r-- | src/nvim/eval.c | 38 | ||||
-rw-r--r-- | src/nvim/eval/userfunc.c | 1 | ||||
-rw-r--r-- | src/nvim/ex_eval.c | 19 | ||||
-rw-r--r-- | src/nvim/option.c | 2 | ||||
-rw-r--r-- | src/nvim/quickfix.c | 12 |
7 files changed, 51 insertions, 25 deletions
diff --git a/src/nvim/api/vimscript.c b/src/nvim/api/vimscript.c index d2e18f08f3..208aa165c9 100644 --- a/src/nvim/api/vimscript.c +++ b/src/nvim/api/vimscript.c @@ -173,6 +173,7 @@ Object nvim_eval(String expr, Error *err) TRY_WRAP(err, { ok = eval0(expr.data, &rettv, NULL, &EVALARG_EVALUATE); + clear_evalarg(&EVALARG_EVALUATE, NULL); }); if (!ERROR_SET(err)) { @@ -294,6 +295,7 @@ Object nvim_call_dict_function(Object dict, String fn, Array args, Error *err) api_set_error(err, kErrorTypeException, "Failed to evaluate dict expression"); } + clear_evalarg(&EVALARG_EVALUATE, NULL); if (try_end(err)) { return rv; } diff --git a/src/nvim/debugger.c b/src/nvim/debugger.c index 3c9a63f5a3..90723372a9 100644 --- a/src/nvim/debugger.c +++ b/src/nvim/debugger.c @@ -494,7 +494,7 @@ static typval_T *eval_expr_no_emsg(struct debuggy *const bp) { // Disable error messages, a bad expression would make Vim unusable. emsg_off++; - typval_T *const tv = eval_expr(bp->dbg_name); + typval_T *const tv = eval_expr(bp->dbg_name, NULL); emsg_off--; return tv; } diff --git a/src/nvim/eval.c b/src/nvim/eval.c index e5193cdfb8..0880fed71e 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -849,6 +849,7 @@ char *eval_to_string_skip(char *arg, exarg_T *eap, const bool skip) if (skip) { emsg_skip--; } + clear_evalarg(&EVALARG_EVALUATE, eap); return retval; } @@ -910,6 +911,7 @@ char *eval_to_string(char *arg, bool convert) } tv_clear(&tv); } + clear_evalarg(&EVALARG_EVALUATE, NULL); return retval; } @@ -964,12 +966,13 @@ varnumber_T eval_to_number(char *expr) /// /// @return an allocated typval_T with the result or /// NULL when there is an error. -typval_T *eval_expr(char *arg) +typval_T *eval_expr(char *arg, exarg_T *eap) { typval_T *tv = xmalloc(sizeof(*tv)); - if (eval0(arg, tv, NULL, &EVALARG_EVALUATE) == FAIL) { + if (eval0(arg, tv, eap, &EVALARG_EVALUATE) == FAIL) { XFREE_CLEAR(tv); } + clear_evalarg(&EVALARG_EVALUATE, eap); return tv; } @@ -1215,6 +1218,7 @@ int eval_foldexpr(char *arg, int *cp) sandbox--; } textlock--; + clear_evalarg(&EVALARG_EVALUATE, NULL); return (int)retval; } @@ -1797,14 +1801,14 @@ notify: /// @param[out] *errp set to true for an error, false otherwise; /// /// @return a pointer that holds the info. Null when there is an error. -void *eval_for_line(const char *arg, bool *errp, exarg_T *eap, int skip) +void *eval_for_line(const char *arg, bool *errp, exarg_T *eap, evalarg_T *const evalarg) { forinfo_T *fi = xcalloc(1, sizeof(forinfo_T)); const char *expr; typval_T tv; list_T *l; + const bool skip = !(evalarg->eval_flags & EVAL_EVALUATE); - evalarg_T evalarg = { .eval_flags = skip ? 0 : EVAL_EVALUATE }; *errp = true; // Default: there is an error. expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); @@ -1813,7 +1817,8 @@ void *eval_for_line(const char *arg, bool *errp, exarg_T *eap, int skip) } expr = skipwhite(expr); - if (expr[0] != 'i' || expr[1] != 'n' || !ascii_iswhite(expr[2])) { + if (expr[0] != 'i' || expr[1] != 'n' + || !(expr[2] == NUL || ascii_iswhite(expr[2]))) { emsg(_("E690: Missing \"in\" after :for")); return fi; } @@ -1821,7 +1826,8 @@ void *eval_for_line(const char *arg, bool *errp, exarg_T *eap, int skip) if (skip) { emsg_skip++; } - if (eval0(skipwhite(expr + 2), &tv, eap, &evalarg) == OK) { + expr = skipwhite(expr + 2); + if (eval0((char *)expr, &tv, eap, evalarg) == OK) { *errp = false; if (!skip) { if (tv.v_type == VAR_LIST) { @@ -2240,13 +2246,17 @@ static int eval_func(char **const arg, char *const name, const int name_len, typ /// After using "evalarg" filled from "eap" free the memory. void clear_evalarg(evalarg_T *evalarg, exarg_T *eap) { - if (evalarg != NULL && eap != NULL && evalarg->eval_tofree != NULL) { - // We may need to keep the original command line, e.g. for - // ":let" it has the variable names. But we may also need the - // new one, "nextcmd" points into it. Keep both. - xfree(eap->cmdline_tofree); - eap->cmdline_tofree = *eap->cmdlinep; - *eap->cmdlinep = evalarg->eval_tofree; + if (evalarg != NULL && evalarg->eval_tofree != NULL) { + if (eap != NULL) { + // We may need to keep the original command line, e.g. for + // ":let" it has the variable names. But we may also need the + // new one, "nextcmd" points into it. Keep both. + xfree(eap->cmdline_tofree); + eap->cmdline_tofree = *eap->cmdlinep; + *eap->cmdlinep = evalarg->eval_tofree; + } else { + xfree(evalarg->eval_tofree); + } evalarg->eval_tofree = NULL; } } @@ -2301,8 +2311,6 @@ int eval0(char *arg, typval_T *rettv, exarg_T *eap, evalarg_T *const evalarg) eap->nextcmd = check_nextcmd(p); } - clear_evalarg(evalarg, eap); - return ret; } diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index b1cb53fec2..1f25b7fb36 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -2996,6 +2996,7 @@ void ex_return(exarg_T *eap) if (eap->skip) { emsg_skip--; } + clear_evalarg(&evalarg, eap); } /// ":1,25call func(arg1, arg2)" function call. diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c index 27f012a4ab..34015728b0 100644 --- a/src/nvim/ex_eval.c +++ b/src/nvim/ex_eval.c @@ -794,11 +794,17 @@ void ex_eval(exarg_T *eap) typval_T tv; evalarg_T evalarg = { .eval_flags = eap->skip ? 0 : EVAL_EVALUATE, - .eval_cookie = eap->getline == getsourceline ? eap->cookie : NULL, }; + if (getline_equal(eap->getline, eap->cookie, getsourceline)) { + evalarg.eval_getline = eap->getline; + evalarg.eval_cookie = eap->cookie; + } + if (eval0(eap->arg, &tv, eap, &evalarg) == OK) { tv_clear(&tv); } + + clear_evalarg(&evalarg, eap); } /// Handle ":if". @@ -961,6 +967,14 @@ void ex_while(exarg_T *eap) } else { void *fi; + 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; + } + // ":for var in list-expr" if ((cstack->cs_lflags & CSL_HAD_LOOP) != 0) { // Jumping here from a ":continue" or ":endfor": use the @@ -969,7 +983,7 @@ void ex_while(exarg_T *eap) error = false; } else { // Evaluate the argument and get the info in a structure. - fi = eval_for_line(eap->arg, &error, eap, skip); + fi = eval_for_line(eap->arg, &error, eap, &evalarg); cstack->cs_forinfo[cstack->cs_idx] = fi; } @@ -984,6 +998,7 @@ void ex_while(exarg_T *eap) free_for_info(fi); cstack->cs_forinfo[cstack->cs_idx] = NULL; } + clear_evalarg(&evalarg, eap); } // If this cstack entry was just initialised and is active, set the diff --git a/src/nvim/option.c b/src/nvim/option.c index 386c6d88d9..6d4e7de1a3 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -5266,7 +5266,7 @@ int option_set_callback_func(char *optval, Callback *optcb) || (strncmp(optval, "function(", 9) == 0) || (strncmp(optval, "funcref(", 8) == 0)) { // Lambda expression or a funcref - tv = eval_expr(optval); + tv = eval_expr(optval, NULL); if (tv == NULL) { return FAIL; } diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index fdcdd71ceb..62eb14342c 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -6957,15 +6957,15 @@ void ex_cexpr(exarg_T *eap) // Evaluate the expression. When the result is a string or a list we can // use it to fill the errorlist. - typval_T tv; - if (eval0(eap->arg, &tv, eap, &EVALARG_EVALUATE) == FAIL) { + typval_T *tv = eval_expr(eap->arg, eap); + if (tv == NULL) { return; } - if ((tv.v_type == VAR_STRING && tv.vval.v_string != NULL) - || tv.v_type == VAR_LIST) { + if ((tv->v_type == VAR_STRING && tv->vval.v_string != NULL) + || tv->v_type == VAR_LIST) { incr_quickfix_busy(); - int res = qf_init_ext(qi, qi->qf_curlist, NULL, NULL, &tv, p_efm, + int res = qf_init_ext(qi, qi->qf_curlist, NULL, NULL, tv, p_efm, (eap->cmdidx != CMD_caddexpr && eap->cmdidx != CMD_laddexpr), (linenr_T)0, (linenr_T)0, @@ -6996,7 +6996,7 @@ void ex_cexpr(exarg_T *eap) emsg(_("E777: String or List expected")); } cleanup: - tv_clear(&tv); + tv_free(tv); } // Get the location list for ":lhelpgrep" |