From: Bram Moolenaar Date: Sat, 27 Jun 2020 21:07:36 +0000 (+0200) Subject: patch 8.2.1076: Vim9: no line break allowed in :if expression X-Git-Tag: v8.2.1076 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=faf8626b79e380fe81e7ae2439a535ed7619d27b;p=vim patch 8.2.1076: Vim9: no line break allowed in :if expression Problem: Vim9: no line break allowed in :if expression. Solution: Skip linebreak. --- diff --git a/src/eval.c b/src/eval.c index 736023930..6aaa3a6ef 100644 --- a/src/eval.c +++ b/src/eval.c @@ -166,10 +166,16 @@ eval_to_bool( { typval_T tv; varnumber_T retval = FALSE; + evalarg_T evalarg; + + CLEAR_FIELD(evalarg); + evalarg.eval_flags = skip ? 0 : EVAL_EVALUATE; + evalarg.eval_cookie = eap != NULL && eap->getline == getsourceline + ? eap->cookie : NULL; if (skip) ++emsg_skip; - if (eval0(arg, &tv, eap, skip ? NULL : &EVALARG_EVALUATE) == FAIL) + if (eval0(arg, &tv, eap, &evalarg) == FAIL) *error = TRUE; else { @@ -182,6 +188,7 @@ eval_to_bool( } if (skip) --emsg_skip; + clear_evalarg(&evalarg, eap); return (int)retval; } @@ -1883,6 +1890,24 @@ skipwhite_and_linebreak(char_u *arg, evalarg_T *evalarg) return p; } +/* + * 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. + vim_free(eap->cmdline_tofree); + eap->cmdline_tofree = *eap->cmdlinep; + *eap->cmdlinep = evalarg->eval_tofree; + evalarg->eval_tofree = NULL; + } +} + /* * The "evaluate" argument: When FALSE, the argument is only parsed but not * executed. The function may return OK, but the rettv will be of type @@ -1934,16 +1959,7 @@ eval0( if (eap != NULL) eap->nextcmd = check_nextcmd(p); - 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. - vim_free(eap->cmdline_tofree); - eap->cmdline_tofree = *eap->cmdlinep; - *eap->cmdlinep = evalarg->eval_tofree; - evalarg->eval_tofree = NULL; - } + clear_evalarg(evalarg, eap); return ret; } @@ -5223,6 +5239,7 @@ ex_echo(exarg_T *eap) arg = skipwhite(arg); } eap->nextcmd = check_nextcmd(arg); + clear_evalarg(&evalarg, eap); if (eap->skip) --emsg_skip; diff --git a/src/evalvars.c b/src/evalvars.c index 0acbd7bcf..1d6172ac7 100644 --- a/src/evalvars.c +++ b/src/evalvars.c @@ -804,7 +804,7 @@ ex_let(exarg_T *eap) i = eval0(expr, &rettv, eap, &evalarg); if (eap->skip) --emsg_skip; - vim_free(evalarg.eval_tofree); + clear_evalarg(&evalarg, eap); } if (eap->skip) { diff --git a/src/proto/eval.pro b/src/proto/eval.pro index 917038591..88dd8a753 100644 --- a/src/proto/eval.pro +++ b/src/proto/eval.pro @@ -30,6 +30,7 @@ int pattern_match(char_u *pat, char_u *text, int ic); char_u *eval_next_non_blank(char_u *arg, evalarg_T *evalarg, int *getnext); char_u *eval_next_line(evalarg_T *evalarg); char_u *skipwhite_and_linebreak(char_u *arg, evalarg_T *evalarg); +void clear_evalarg(evalarg_T *evalarg, exarg_T *eap); int eval0(char_u *arg, typval_T *rettv, exarg_T *eap, evalarg_T *evalarg); int eval1(char_u **arg, typval_T *rettv, evalarg_T *evalarg); void eval_addblob(typval_T *tv1, typval_T *tv2); diff --git a/src/testdir/test_vim9_cmd.vim b/src/testdir/test_vim9_cmd.vim index 2d5bf4516..a818d1408 100644 --- a/src/testdir/test_vim9_cmd.vim +++ b/src/testdir/test_vim9_cmd.vim @@ -101,5 +101,46 @@ def Test_echo_linebreak() CheckScriptSuccess(lines) enddef +def Test_if_linebreak() + let lines =<< trim END + vim9script + if 1 && + 2 + || 3 + g:res = 42 + endif + assert_equal(42, g:res) + END + CheckScriptSuccess(lines) + unlet g:res + + lines =<< trim END + vim9script + if 1 && + 0 + g:res = 0 + elseif 0 || + 0 + || 1 + g:res = 12 + endif + assert_equal(12, g:res) + END + CheckScriptSuccess(lines) + unlet g:res +enddef + +def Test_while_linebreak() + " TODO: line break in :while expression doesn't work yet + let lines =<< trim END + vim9script + let nr = 0 + while nr < 10 + 3 + nr = nr + 4 + endwhile + assert_equal(16, nr) + END + CheckScriptSuccess(lines) +enddef " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/version.c b/src/version.c index c304fe5cc..948f561e2 100644 --- a/src/version.c +++ b/src/version.c @@ -754,6 +754,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1076, /**/ 1075, /**/