Patch 8.2.0562
Problem:    Vim9: cannot split an expression into multiple lines.
Solution:   Continue in next line after an operator.
Files:      runtime/doc/vim9.txt, src/macros.h, src/vim9compile.c,
            src/testdir/test_vim9_expr.vim


*** ../vim-8.2.0561/runtime/doc/vim9.txt        2020-04-12 20:19:12.639818982 
+0200
--- runtime/doc/vim9.txt        2020-04-12 20:51:16.927419654 +0200
***************
*** 195,200 ****
--- 195,212 ----
                        arg2
                        )
  
+ For binary operators iin expressions not in [], {} or () a line break is
+ possible AFTER the operators.  For example: >
+       let text = lead ..
+                  middle ..
+                  end
+       let total = start +
+                   end -
+                   correction
+       let result = positive ?
+                       PosFunc(arg) :
+                       NegFunc(arg)
+ 
  Note that "enddef" cannot be used at the start of a continuation line, it ends
  the current function.
  
*** ../vim-8.2.0561/src/macros.h        2020-03-11 14:19:53.480369957 +0100
--- src/macros.h        2020-04-12 20:24:15.323191994 +0200
***************
*** 37,46 ****
  #define LTOREQ_POS(a, b) (LT_POS(a, b) || EQUAL_POS(a, b))
  
  /*
!  * VIM_ISWHITE() is used for "^" and the like. It differs from isspace()
!  * because it doesn't include <CR> and <LF> and the like.
   */
! #define VIM_ISWHITE(x)        ((x) == ' ' || (x) == '\t')
  
  /*
   * LINEEMPTY() - return TRUE if the line is empty
--- 37,47 ----
  #define LTOREQ_POS(a, b) (LT_POS(a, b) || EQUAL_POS(a, b))
  
  /*
!  * VIM_ISWHITE() differs from isspace() because it doesn't include <CR> and
!  * <LF> and the like.
   */
! #define VIM_ISWHITE(x)                ((x) == ' ' || (x) == '\t')
! #define IS_WHITE_OR_NUL(x)    ((x) == ' ' || (x) == '\t' || (x) == NUL)
  
  /*
   * LINEEMPTY() - return TRUE if the line is empty
*** ../vim-8.2.0561/src/vim9compile.c   2020-04-12 20:19:12.639818982 +0200
--- src/vim9compile.c   2020-04-12 20:49:04.883743936 +0200
***************
*** 2070,2075 ****
--- 2070,2093 ----
  }
  
  /*
+  * If "*arg" is at the end of the line, advance to the next line.
+  * Return FAIL if beyond the last line, "*arg" is unmodified then.
+  */
+     static int
+ may_get_next_line(char_u **arg, cctx_T *cctx)
+ {
+     if (**arg == NUL)
+     {
+       char_u *next = next_line_from_context(cctx);
+ 
+       if (next == NULL)
+           return FAIL;
+       *arg = skipwhite(next);
+     }
+     return OK;
+ }
+ 
+ /*
   * Generate an instruction to load script-local variable "name", without the
   * leading "s:".
   * Also finds imported variables.
***************
*** 3394,3407 ****
        op = skipwhite(*arg);
        if (*op != '*' && *op != '/' && *op != '%')
            break;
!       if (!VIM_ISWHITE(**arg) || !VIM_ISWHITE(op[1]))
        {
            char_u buf[3];
  
            vim_strncpy(buf, op, 1);
            semsg(_(e_white_both), buf);
        }
        *arg = skipwhite(op + 1);
  
        // get the second variable
        if (compile_expr7(arg, cctx) == FAIL)
--- 3412,3428 ----
        op = skipwhite(*arg);
        if (*op != '*' && *op != '/' && *op != '%')
            break;
!       if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(op[1]))
        {
            char_u buf[3];
  
            vim_strncpy(buf, op, 1);
            semsg(_(e_white_both), buf);
+           return FAIL;
        }
        *arg = skipwhite(op + 1);
+       if (may_get_next_line(arg, cctx) == FAIL)
+           return FAIL;
  
        // get the second variable
        if (compile_expr7(arg, cctx) == FAIL)
***************
*** 3438,3452 ****
            break;
        oplen = (*op == '.' ? 2 : 1);
  
!       if (!VIM_ISWHITE(**arg) || !VIM_ISWHITE(op[oplen]))
        {
            char_u buf[3];
  
            vim_strncpy(buf, op, oplen);
            semsg(_(e_white_both), buf);
        }
  
        *arg = skipwhite(op + oplen);
  
        // get the second variable
        if (compile_expr6(arg, cctx) == FAIL)
--- 3459,3476 ----
            break;
        oplen = (*op == '.' ? 2 : 1);
  
!       if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(op[oplen]))
        {
            char_u buf[3];
  
            vim_strncpy(buf, op, oplen);
            semsg(_(e_white_both), buf);
+           return FAIL;
        }
  
        *arg = skipwhite(op + oplen);
+       if (may_get_next_line(arg, cctx) == FAIL)
+           return FAIL;
  
        // get the second variable
        if (compile_expr6(arg, cctx) == FAIL)
***************
*** 3572,3587 ****
            ++len;
        // nothing appended: match case
  
!       if (!VIM_ISWHITE(**arg) || !VIM_ISWHITE(p[len]))
        {
            char_u buf[7];
  
            vim_strncpy(buf, p, len);
            semsg(_(e_white_both), buf);
        }
  
        // get the second variable
        *arg = skipwhite(p + len);
        if (compile_expr5(arg, cctx) == FAIL)
            return FAIL;
  
--- 3596,3615 ----
            ++len;
        // nothing appended: match case
  
!       if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[len]))
        {
            char_u buf[7];
  
            vim_strncpy(buf, p, len);
            semsg(_(e_white_both), buf);
+           return FAIL;
        }
  
        // get the second variable
        *arg = skipwhite(p + len);
+       if (may_get_next_line(arg, cctx) == FAIL)
+           return FAIL;
+ 
        if (compile_expr5(arg, cctx) == FAIL)
            return FAIL;
  
***************
*** 3611,3618 ****
        ga_init2(&end_ga, sizeof(int), 10);
        while (p[0] == opchar && p[1] == opchar)
        {
!           if (!VIM_ISWHITE(**arg) || !VIM_ISWHITE(p[2]))
                semsg(_(e_white_both), op);
  
            if (ga_grow(&end_ga, 1) == FAIL)
            {
--- 3639,3649 ----
        ga_init2(&end_ga, sizeof(int), 10);
        while (p[0] == opchar && p[1] == opchar)
        {
!           if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[2]))
!           {
                semsg(_(e_white_both), op);
+               return FAIL;
+           }
  
            if (ga_grow(&end_ga, 1) == FAIL)
            {
***************
*** 3626,3631 ****
--- 3657,3665 ----
  
            // eval the next expression
            *arg = skipwhite(p + 2);
+           if (may_get_next_line(arg, cctx) == FAIL)
+               return FAIL;
+ 
            if ((opchar == '|' ? compile_expr3(arg, cctx)
                                           : compile_expr4(arg, cctx)) == FAIL)
            {
***************
*** 3726,3738 ****
        type_T          *type1;
        type_T          *type2;
  
!       if (!VIM_ISWHITE(**arg) || !VIM_ISWHITE(p[1]))
            semsg(_(e_white_both), "?");
  
        generate_JUMP(cctx, JUMP_IF_FALSE, 0);
  
        // evaluate the second expression; any type is accepted
        *arg = skipwhite(p + 1);
        if (compile_expr1(arg, cctx) == FAIL)
            return FAIL;
  
--- 3760,3778 ----
        type_T          *type1;
        type_T          *type2;
  
!       if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[1]))
!       {
            semsg(_(e_white_both), "?");
+           return FAIL;
+       }
  
        generate_JUMP(cctx, JUMP_IF_FALSE, 0);
  
        // evaluate the second expression; any type is accepted
        *arg = skipwhite(p + 1);
+       if (may_get_next_line(arg, cctx) == FAIL)
+           return FAIL;
+ 
        if (compile_expr1(arg, cctx) == FAIL)
            return FAIL;
  
***************
*** 3754,3764 ****
            emsg(_(e_missing_colon));
            return FAIL;
        }
!       if (!VIM_ISWHITE(**arg) || !VIM_ISWHITE(p[1]))
            semsg(_(e_white_both), ":");
  
        // evaluate the third expression
        *arg = skipwhite(p + 1);
        if (compile_expr1(arg, cctx) == FAIL)
            return FAIL;
  
--- 3794,3810 ----
            emsg(_(e_missing_colon));
            return FAIL;
        }
!       if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[1]))
!       {
            semsg(_(e_white_both), ":");
+           return FAIL;
+       }
  
        // evaluate the third expression
        *arg = skipwhite(p + 1);
+       if (may_get_next_line(arg, cctx) == FAIL)
+           return FAIL;
+ 
        if (compile_expr1(arg, cctx) == FAIL)
            return FAIL;
  
*** ../vim-8.2.0561/src/testdir/test_vim9_expr.vim      2020-04-12 
18:02:02.031541127 +0200
--- src/testdir/test_vim9_expr.vim      2020-04-12 20:50:01.479605043 +0200
***************
*** 32,38 ****
  " test cond ? expr : expr
  def Test_expr1()
    assert_equal('one', true ? 'one' : 'two')
!   assert_equal('one', 1 ? 'one' : 'two')
    if has('float')
      assert_equal('one', 0.1 ? 'one' : 'two')
    endif
--- 32,40 ----
  " test cond ? expr : expr
  def Test_expr1()
    assert_equal('one', true ? 'one' : 'two')
!   assert_equal('one', 1 ?
!                       'one' :
!                       'two')
    if has('float')
      assert_equal('one', 0.1 ? 'one' : 'two')
    endif
***************
*** 80,86 ****
  " test ||
  def Test_expr2()
    assert_equal(2, 2 || 0)
!   assert_equal(7, 0 || 0 || 7)
    assert_equal(0, 0 || 0)
    assert_equal('', 0 || '')
  
--- 82,90 ----
  " test ||
  def Test_expr2()
    assert_equal(2, 2 || 0)
!   assert_equal(7, 0 ||
!                   0 ||
!                   7)
    assert_equal(0, 0 || 0)
    assert_equal('', 0 || '')
  
***************
*** 113,119 ****
  " test &&
  def Test_expr3()
    assert_equal(0, 2 && 0)
!   assert_equal(0, 0 && 0 && 7)
    assert_equal(7, 2 && 3 && 7)
    assert_equal(0, 0 && 0)
    assert_equal(0, 0 && '')
--- 117,125 ----
  " test &&
  def Test_expr3()
    assert_equal(0, 2 && 0)
!   assert_equal(0, 0 &&
!               0 &&
!               7)
    assert_equal(7, 2 && 3 && 7)
    assert_equal(0, 0 && 0)
    assert_equal(0, 0 && '')
***************
*** 164,170 ****
  " test == comperator
  def Test_expr4_equal()
    assert_equal(true, true == true)
!   assert_equal(false, true == false)
    assert_equal(true, true == g:atrue)
    assert_equal(false, g:atrue == false)
  
--- 170,177 ----
  " test == comperator
  def Test_expr4_equal()
    assert_equal(true, true == true)
!   assert_equal(false, true ==
!                       false)
    assert_equal(true, true == g:atrue)
    assert_equal(false, g:atrue == false)
  
***************
*** 237,243 ****
  " test != comperator
  def Test_expr4_notequal()
    assert_equal(false, true != true)
!   assert_equal(true, true != false)
    assert_equal(false, true != g:atrue)
    assert_equal(true, g:atrue != false)
  
--- 244,251 ----
  " test != comperator
  def Test_expr4_notequal()
    assert_equal(false, true != true)
!   assert_equal(true, true !=
!                       false)
    assert_equal(false, true != g:atrue)
    assert_equal(true, g:atrue != false)
  
***************
*** 303,309 ****
  " test > comperator
  def Test_expr4_greater()
    assert_true(2 > 0)
!   assert_true(2 > 1)
    assert_false(2 > 2)
    assert_false(2 > 3)
    if has('float')
--- 311,318 ----
  " test > comperator
  def Test_expr4_greater()
    assert_true(2 > 0)
!   assert_true(2 >
!               1)
    assert_false(2 > 2)
    assert_false(2 > 3)
    if has('float')
***************
*** 317,323 ****
  " test >= comperator
  def Test_expr4_greaterequal()
    assert_true(2 >= 0)
!   assert_true(2 >= 2)
    assert_false(2 >= 3)
    if has('float')
      assert_true(2.0 >= 0.0)
--- 326,333 ----
  " test >= comperator
  def Test_expr4_greaterequal()
    assert_true(2 >= 0)
!   assert_true(2 >=
!                       2)
    assert_false(2 >= 3)
    if has('float')
      assert_true(2.0 >= 0.0)
***************
*** 329,335 ****
  " test < comperator
  def Test_expr4_smaller()
    assert_false(2 < 0)
!   assert_false(2 < 2)
    assert_true(2 < 3)
    if has('float')
      assert_false(2.0 < 0.0)
--- 339,346 ----
  " test < comperator
  def Test_expr4_smaller()
    assert_false(2 < 0)
!   assert_false(2 <
!                       2)
    assert_true(2 < 3)
    if has('float')
      assert_false(2.0 < 0.0)
***************
*** 341,347 ****
  " test <= comperator
  def Test_expr4_smallerequal()
    assert_false(2 <= 0)
!   assert_false(2 <= 1)
    assert_true(2 <= 2)
    assert_true(2 <= 3)
    if has('float')
--- 352,359 ----
  " test <= comperator
  def Test_expr4_smallerequal()
    assert_false(2 <= 0)
!   assert_false(2 <=
!                       1)
    assert_true(2 <= 2)
    assert_true(2 <= 3)
    if has('float')
***************
*** 355,367 ****
  " test =~ comperator
  def Test_expr4_match()
    assert_equal(false, '2' =~ '0')
!   assert_equal(true, '2' =~ '[0-9]')
  enddef
  
  " test !~ comperator
  def Test_expr4_nomatch()
    assert_equal(true, '2' !~ '0')
!   assert_equal(false, '2' !~ '[0-9]')
  enddef
  
  " test is comperator
--- 367,381 ----
  " test =~ comperator
  def Test_expr4_match()
    assert_equal(false, '2' =~ '0')
!   assert_equal(true, '2' =~
!                       '[0-9]')
  enddef
  
  " test !~ comperator
  def Test_expr4_nomatch()
    assert_equal(true, '2' !~ '0')
!   assert_equal(false, '2' !~
!                       '[0-9]')
  enddef
  
  " test is comperator
***************
*** 369,375 ****
    let mylist = [2]
    assert_false(mylist is [2])
    let other = mylist
!   assert_true(mylist is other)
  
    let myblob = 0z1234
    assert_false(myblob is 0z1234)
--- 383,390 ----
    let mylist = [2]
    assert_false(mylist is [2])
    let other = mylist
!   assert_true(mylist is
!               other)
  
    let myblob = 0z1234
    assert_false(myblob is 0z1234)
***************
*** 383,389 ****
    assert_true('2' isnot '0')
    assert_true(mylist isnot [2])
    let other = mylist
!   assert_false(mylist isnot other)
  
    let myblob = 0z1234
    assert_true(myblob isnot 0z1234)
--- 398,405 ----
    assert_true('2' isnot '0')
    assert_true(mylist isnot [2])
    let other = mylist
!   assert_false(mylist isnot
!                       other)
  
    let myblob = 0z1234
    assert_true(myblob isnot 0z1234)
***************
*** 467,483 ****
  " test addition, subtraction, concatenation
  def Test_expr5()
    assert_equal(66, 60 + 6)
!   assert_equal(70, 60 + g:anint)
    assert_equal(9, g:alsoint + 5)
    assert_equal(14, g:alsoint + g:anint)
  
    assert_equal(54, 60 - 6)
!   assert_equal(50, 60 - g:anint)
    assert_equal(-1, g:alsoint - 5)
    assert_equal(-6, g:alsoint - g:anint)
  
    assert_equal('hello', 'hel' .. 'lo')
!   assert_equal('hello 123', 'hello ' .. 123)
    assert_equal('123 hello', 123 .. ' hello')
    assert_equal('123456', 123 .. 456)
  
--- 483,502 ----
  " test addition, subtraction, concatenation
  def Test_expr5()
    assert_equal(66, 60 + 6)
!   assert_equal(70, 60 +
!                       g:anint)
    assert_equal(9, g:alsoint + 5)
    assert_equal(14, g:alsoint + g:anint)
  
    assert_equal(54, 60 - 6)
!   assert_equal(50, 60 -
!                   g:anint)
    assert_equal(-1, g:alsoint - 5)
    assert_equal(-6, g:alsoint - g:anint)
  
    assert_equal('hello', 'hel' .. 'lo')
!   assert_equal('hello 123', 'hello ' ..
!                                       123)
    assert_equal('123 hello', 123 .. ' hello')
    assert_equal('123456', 123 .. 456)
  
***************
*** 494,500 ****
    else
      assert_equal(66.0, 60.0 + 6.0)
      assert_equal(66.0, 60.0 + 6)
!     assert_equal(66.0, 60 + 6.0)
      assert_equal(5.1, g:afloat + 5)
      assert_equal(8.1, 8 + g:afloat)
      assert_equal(10.1, g:anint + g:afloat)
--- 513,520 ----
    else
      assert_equal(66.0, 60.0 + 6.0)
      assert_equal(66.0, 60.0 + 6)
!     assert_equal(66.0, 60 +
!                        6.0)
      assert_equal(5.1, g:afloat + 5)
      assert_equal(8.1, 8 + g:afloat)
      assert_equal(10.1, g:anint + g:afloat)
***************
*** 538,555 ****
  " test multiply, divide, modulo
  def Test_expr6()
    assert_equal(36, 6 * 6)
!   assert_equal(24, 6 * g:alsoint)
    assert_equal(24, g:alsoint * 6)
    assert_equal(40, g:anint * g:alsoint)
  
    assert_equal(10, 60 / 6)
!   assert_equal(6, 60 / g:anint)
    assert_equal(1, g:anint / 6)
    assert_equal(2, g:anint / g:alsoint)
  
    assert_equal(5, 11 % 6)
    assert_equal(4, g:anint % 6)
!   assert_equal(3, 13 % g:anint)
    assert_equal(2, g:anint % g:alsoint)
  
    assert_equal(4, 6 * 4 / 6)
--- 558,578 ----
  " test multiply, divide, modulo
  def Test_expr6()
    assert_equal(36, 6 * 6)
!   assert_equal(24, 6 *
!                       g:alsoint)
    assert_equal(24, g:alsoint * 6)
    assert_equal(40, g:anint * g:alsoint)
  
    assert_equal(10, 60 / 6)
!   assert_equal(6, 60 /
!                       g:anint)
    assert_equal(1, g:anint / 6)
    assert_equal(2, g:anint / g:alsoint)
  
    assert_equal(5, 11 % 6)
    assert_equal(4, g:anint % 6)
!   assert_equal(3, 13 %
!                       g:anint)
    assert_equal(2, g:anint % g:alsoint)
  
    assert_equal(4, 6 * 4 / 6)
***************
*** 573,589 ****
      MissingFeature 'float'
    else
      assert_equal(36.0, 6.0 * 6)
!     assert_equal(36.0, 6 * 6.0)
      assert_equal(36.0, 6.0 * 6.0)
      assert_equal(1.0, g:afloat * g:anint)
  
      assert_equal(10.0, 60 / 6.0)
!     assert_equal(10.0, 60.0 / 6)
      assert_equal(10.0, 60.0 / 6.0)
      assert_equal(0.01, g:afloat / g:anint)
  
      assert_equal(4.0, 6.0 * 4 / 6)
!     assert_equal(4.0, 6 * 4.0 / 6)
      assert_equal(4.0, 6 * 4 / 6.0)
      assert_equal(4.0, 6.0 * 4.0 / 6)
      assert_equal(4.0, 6 * 4.0 / 6.0)
--- 596,616 ----
      MissingFeature 'float'
    else
      assert_equal(36.0, 6.0 * 6)
!     assert_equal(36.0, 6 *
!                          6.0)
      assert_equal(36.0, 6.0 * 6.0)
      assert_equal(1.0, g:afloat * g:anint)
  
      assert_equal(10.0, 60 / 6.0)
!     assert_equal(10.0, 60.0 /
!                       6)
      assert_equal(10.0, 60.0 / 6.0)
      assert_equal(0.01, g:afloat / g:anint)
  
      assert_equal(4.0, 6.0 * 4 / 6)
!     assert_equal(4.0, 6 *
!                       4.0 /
!                       6)
      assert_equal(4.0, 6 * 4 / 6.0)
      assert_equal(4.0, 6.0 * 4.0 / 6)
      assert_equal(4.0, 6 * 4.0 / 6.0)
*** ../vim-8.2.0561/src/version.c       2020-04-12 20:19:12.643818971 +0200
--- src/version.c       2020-04-12 20:54:21.954964146 +0200
***************
*** 740,741 ****
--- 740,743 ----
  {   /* Add new patch number below this line */
+ /**/
+     562,
  /**/

-- 
We apologise again for the fault in the subtitles.  Those responsible for
sacking the people who have just been sacked have been sacked.
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202004121856.03CIu7Cr017608%40masaka.moolenaar.net.

Raspunde prin e-mail lui