# HG changeset patch # User Bram Moolenaar # Date 1593292503 -7200 # Node ID 7a9daf73a7243519319de64d080ef118a315fa16 # Parent 4b256059a255fdeb2c61b37565b1366fae983bf3 patch 8.2.1076: Vim9: no line break allowed in :if expression Commit: https://github.com/vim/vim/commit/faf8626b79e380fe81e7ae2439a535ed7619d27b Author: Bram Moolenaar Date: Sat Jun 27 23:07:36 2020 +0200 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 --- 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; } @@ -1884,6 +1891,24 @@ skipwhite_and_linebreak(char_u *arg, eva } /* + * 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 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. @@ -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 --- 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 --- a/src/proto/eval.pro +++ b/src/proto/eval.pro @@ -30,6 +30,7 @@ int pattern_match(char_u *pat, char_u *t 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 --- 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 --- a/src/version.c +++ b/src/version.c @@ -755,6 +755,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1076, +/**/ 1075, /**/ 1074,