]> granicus.if.org Git - vim/commitdiff
patch 8.2.1045: Vim9: line break before operator does not work v8.2.1045
authorBram Moolenaar <Bram@vim.org>
Tue, 23 Jun 2020 20:26:05 +0000 (22:26 +0200)
committerBram Moolenaar <Bram@vim.org>
Tue, 23 Jun 2020 20:26:05 +0000 (22:26 +0200)
Problem:    Vim9: line break before operator does not work.
Solution:   Peek the next line for an operator.

src/testdir/test_vim9_expr.vim
src/version.c
src/vim9compile.c

index 46816fdc78854648b2462938bc31a6084dabea86..46034fb30a009577268f2b5e6b8c4bbfa98505ca 100644 (file)
@@ -13,6 +13,9 @@ def Test_expr1()
     assert_equal('one', 0.1 ? 'one' : 'two')
   endif
   assert_equal('one', 'x' ? 'one' : 'two')
+  assert_equal('one', 'x'
+                       ? 'one'
+                       : 'two')
   assert_equal('one', 0z1234 ? 'one' : 'two')
   assert_equal('one', [0] ? 'one' : 'two')
   assert_equal('one', #{x: 0} ? 'one' : 'two')
@@ -70,6 +73,8 @@ def Test_expr2()
                    0 ||
                    7)
   assert_equal(0, 0 || 0)
+  assert_equal(0, 0
+                   || 0)
   assert_equal('', 0 || '')
 
   g:vals = []
@@ -81,7 +86,9 @@ def Test_expr2()
   assert_equal([0, 5], g:vals)
 
   g:vals = []
-  assert_equal(4, Record(0) || Record(4) || Record(0))
+  assert_equal(4, Record(0)
+                     || Record(4)
+                     || Record(0))
   assert_equal([0, 4], g:vals)
 
   g:vals = []
@@ -104,7 +111,9 @@ def Test_expr3()
   assert_equal(0, 0 &&
                0 &&
                7)
-  assert_equal(7, 2 && 3 && 7)
+  assert_equal(7, 2
+                   && 3
+                   && 7)
   assert_equal(0, 0 && 0)
   assert_equal(0, 0 && '')
   assert_equal('', 8 && '')
@@ -158,7 +167,8 @@ def Test_expr4_equal()
   assert_equal(true, true == true)
   assert_equal(false, true ==
                        false)
-  assert_equal(true, true == trueVar)
+  assert_equal(true, true
+                       == trueVar)
   assert_equal(false, true == falseVar)
   assert_equal(true, true == g:atrue)
   assert_equal(false, g:atrue == false)
@@ -250,7 +260,8 @@ def Test_expr4_notequal()
   assert_equal(false, true != true)
   assert_equal(true, true !=
                        false)
-  assert_equal(false, true != trueVar)
+  assert_equal(false, true
+                       != trueVar)
   assert_equal(true, true != falseVar)
   assert_equal(false, true != g:atrue)
   assert_equal(true, g:atrue != false)
@@ -334,7 +345,8 @@ def Test_expr4_greater()
   assert_true(nr2 >
                1)
   assert_false(nr2 > 2)
-  assert_false(nr2 > 3)
+  assert_false(nr2
+                   > 3)
   if has('float')
     let ff = 2.0
     assert_true(ff > 0.0)
@@ -367,7 +379,8 @@ def Test_expr4_smaller()
   assert_false(2 < 0)
   assert_false(2 <
                        2)
-  assert_true(2 < 3)
+  assert_true(2
+               < 3)
   let nr2 = 2
   assert_false(nr2 < 0)
   assert_false(nr2 < 2)
@@ -385,7 +398,8 @@ def Test_expr4_smallerequal()
   assert_false(2 <= 0)
   assert_false(2 <=
                        1)
-  assert_true(2 <= 2)
+  assert_true(2
+               <= 2)
   assert_true(2 <= 3)
   let nr2 = 2
   assert_false(nr2 <= 0)
@@ -404,6 +418,8 @@ enddef
 " test =~ comperator
 def Test_expr4_match()
   assert_equal(false, '2' =~ '0')
+  assert_equal(false, ''
+                        =~ '0')
   assert_equal(true, '2' =~
                        '[0-9]')
 enddef
@@ -411,6 +427,8 @@ enddef
 " test !~ comperator
 def Test_expr4_nomatch()
   assert_equal(true, '2' !~ '0')
+  assert_equal(true, ''
+                       !~ '0')
   assert_equal(false, '2' !~
                        '[0-9]')
 enddef
@@ -424,7 +442,8 @@ def Test_expr4_is()
                other)
 
   let myblob = 0z1234
-  assert_false(myblob is 0z1234)
+  assert_false(myblob
+                       is 0z1234)
   let otherblob = myblob
   assert_true(myblob is otherblob)
 enddef
@@ -439,7 +458,8 @@ def Test_expr4_isnot()
                        other)
 
   let myblob = 0z1234
-  assert_true(myblob isnot 0z1234)
+  assert_true(myblob
+               isnot 0z1234)
   let otherblob = myblob
   assert_false(myblob isnot otherblob)
 enddef
@@ -522,26 +542,30 @@ def Test_expr5()
   assert_equal(66, 60 + 6)
   assert_equal(70, 60 +
                        g:anint)
-  assert_equal(9, g:alsoint + 5)
+  assert_equal(9, g:alsoint
+                       + 5)
   assert_equal(14, g:alsoint + g:anint)
   assert_equal([1, 2, 3, 4], [1] + g:alist)
 
   assert_equal(54, 60 - 6)
   assert_equal(50, 60 -
                    g:anint)
-  assert_equal(-1, g:alsoint - 5)
+  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('hello 123', 'hello ' ..  123)
+  assert_equal('hello 123', 'hello '
+                               ..  123)
   assert_equal('123 hello', 123 .. ' hello')
   assert_equal('123456', 123 .. 456)
 
   assert_equal([1, 2, 3, 4], [1, 2] + [3, 4])
   assert_equal(0z11223344, 0z1122 + 0z3344)
-  assert_equal(0z112201ab, 0z1122 + g:ablob)
+  assert_equal(0z112201ab, 0z1122
+                               + g:ablob)
   assert_equal(0z01ab3344, g:ablob + 0z3344)
   assert_equal(0z01ab01ab, g:ablob + g:ablob)
 enddef
@@ -554,13 +578,15 @@ def Test_expr5_float()
     assert_equal(66.0, 60.0 + 6)
     assert_equal(66.0, 60 +
                         6.0)
-    assert_equal(5.1, g:afloat + 5)
+    assert_equal(5.1, g:afloat
+                       + 5)
     assert_equal(8.1, 8 + g:afloat)
     assert_equal(10.1, g:anint + g:afloat)
     assert_equal(10.1, g:afloat + g:anint)
 
     assert_equal(54.0, 60.0 - 6.0)
-    assert_equal(54.0, 60.0 - 6)
+    assert_equal(54.0, 60.0
+                           - 6)
     assert_equal(54.0, 60 - 6.0)
     assert_equal(-4.9, g:afloat - 5)
     assert_equal(7.9, 8 - g:afloat)
@@ -599,20 +625,23 @@ def Test_expr6()
   assert_equal(36, 6 * 6)
   assert_equal(24, 6 *
                        g:alsoint)
-  assert_equal(24, g:alsoint * 6)
+  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(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(2, g:anint
+                       % g:alsoint)
 
   assert_equal(4, 6 * 4 / 6)
 
@@ -623,8 +652,10 @@ def Test_expr6()
   if has('float')
     let xf = [2.0]
     let yf = [3.0]
-    assert_equal(5.0, xf[0] + yf[0])
-    assert_equal(6.0, xf[0] * yf[0])
+    assert_equal(5.0, xf[0]
+                       + yf[0])
+    assert_equal(6.0, xf[0]
+                       * yf[0])
   endif
 
   call CheckDefFailure(["let x = 6 * xxx"], 'E1001')
index 8b6ddca3b37b45a1fa4484f4134872c140d436aa..49f9ddf22f01122445645edb79e1f8023e3ecde0 100644 (file)
@@ -754,6 +754,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1045,
 /**/
     1044,
 /**/
index 39ef5f6cda5ca09e7e3f5454572ef62d4ee7da05..054eaa63d5d45bcf97d8a913fc969c4ec0d9f4b1 100644 (file)
@@ -2413,6 +2413,27 @@ peek_next_line(cctx_T *cctx)
     return NULL;
 }
 
+/*
+ * Called when checking for a following operator at "arg".  When the rest of
+ * the line is empty or only a comment, peek the next line.  If there is a next
+ * line return a pointer to it and set "nextp".
+ * Otherwise skip over white space.
+ */
+    static char_u *
+may_peek_next_line(cctx_T *cctx, char_u *arg, char_u **nextp)
+{
+    char_u *p = skipwhite(arg);
+
+    *nextp = NULL;
+    if (*p == NUL || (VIM_ISWHITE(*arg) && comment_start(p)))
+    {
+       *nextp = peek_next_line(cctx);
+       if (*nextp != NULL)
+           return *nextp;
+    }
+    return p;
+}
+
 /*
  * Get the next line of the function from "cctx".
  * Skips over empty lines.  Skips over comment lines if "skip_comment" is TRUE.
@@ -3947,6 +3968,7 @@ compile_expr7(
 compile_expr6(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
 {
     char_u     *op;
+    char_u     *next;
     int                ppconst_used = ppconst->pp_used;
 
     // get the first expression
@@ -3958,9 +3980,14 @@ compile_expr6(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
      */
     for (;;)
     {
-       op = skipwhite(*arg);
+       op = may_peek_next_line(cctx, *arg, &next);
        if (*op != '*' && *op != '/' && *op != '%')
            break;
+       if (next != NULL)
+       {
+           *arg = next_line_from_context(cctx, TRUE);
+           op = skipwhite(*arg);
+       }
 
        if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(op[1]))
        {
@@ -4018,6 +4045,7 @@ compile_expr6(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
 compile_expr5(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
 {
     char_u     *op;
+    char_u     *next;
     int                oplen;
     int                ppconst_used = ppconst->pp_used;
 
@@ -4030,10 +4058,15 @@ compile_expr5(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
      */
     for (;;)
     {
-       op = skipwhite(*arg);
-       if (*op != '+' && *op != '-' && !(*op == '.' && (*(*arg + 1) == '.')))
+       op = may_peek_next_line(cctx, *arg, &next);
+       if (*op != '+' && *op != '-' && !(*op == '.' && *(op + 1) == '.'))
            break;
        oplen = (*op == '.' ? 2 : 1);
+       if (next != NULL)
+       {
+           *arg = next_line_from_context(cctx, TRUE);
+           op = skipwhite(*arg);
+       }
 
        if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(op[oplen]))
        {
@@ -4127,6 +4160,7 @@ compile_expr4(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
 {
     exptype_T  type = EXPR_UNKNOWN;
     char_u     *p;
+    char_u     *next;
     int                len = 2;
     int                type_is = FALSE;
     int                ppconst_used = ppconst->pp_used;
@@ -4135,7 +4169,7 @@ compile_expr4(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
     if (compile_expr5(arg, cctx, ppconst) == FAIL)
        return FAIL;
 
-    p = skipwhite(*arg);
+    p = may_peek_next_line(cctx, *arg, &next);
     type = get_compare_type(p, &len, &type_is);
 
     /*
@@ -4145,6 +4179,11 @@ compile_expr4(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
     {
        int ic = FALSE;  // Default: do not ignore case
 
+       if (next != NULL)
+       {
+           *arg = next_line_from_context(cctx, TRUE);
+           p = skipwhite(*arg);
+       }
        if (type_is && (p[len] == '?' || p[len] == '#'))
        {
            semsg(_(e_invexpr2), *arg);
@@ -4221,7 +4260,8 @@ compile_and_or(
        ppconst_T *ppconst,
        int     ppconst_used UNUSED)
 {
-    char_u     *p = skipwhite(*arg);
+    char_u     *next;
+    char_u     *p = may_peek_next_line(cctx, *arg, &next);
     int                opchar = *op;
 
     if (p[0] == opchar && p[1] == opchar)
@@ -4235,6 +4275,12 @@ compile_and_or(
        ga_init2(&end_ga, sizeof(int), 10);
        while (p[0] == opchar && p[1] == opchar)
        {
+           if (next != NULL)
+           {
+               *arg = next_line_from_context(cctx, TRUE);
+               p = skipwhite(*arg);
+           }
+
            if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[2]))
            {
                semsg(_(e_white_both), op);
@@ -4265,7 +4311,8 @@ compile_and_or(
                ga_clear(&end_ga);
                return FAIL;
            }
-           p = skipwhite(*arg);
+
+           p = may_peek_next_line(cctx, *arg, &next);
        }
        generate_ppconst(cctx, ppconst);
 
@@ -4349,12 +4396,13 @@ compile_expr1(char_u **arg,  cctx_T *cctx, ppconst_T *ppconst)
 {
     char_u     *p;
     int                ppconst_used = ppconst->pp_used;
+    char_u     *next;
 
     // Evaluate the first expression.
     if (compile_expr2(arg, cctx, ppconst) == FAIL)
        return FAIL;
 
-    p = skipwhite(*arg);
+    p = may_peek_next_line(cctx, *arg, &next);
     if (*p == '?')
     {
        garray_T        *instr = &cctx->ctx_instr;
@@ -4368,6 +4416,12 @@ compile_expr1(char_u **arg,  cctx_T *cctx, ppconst_T *ppconst)
        int             const_value = FALSE;
        int             save_skip = cctx->ctx_skip;
 
+       if (next != NULL)
+       {
+           *arg = next_line_from_context(cctx, TRUE);
+           p = skipwhite(*arg);
+       }
+
        if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[1]))
        {
            semsg(_(e_white_both), "?");
@@ -4415,12 +4469,18 @@ compile_expr1(char_u **arg,  cctx_T *cctx, ppconst_T *ppconst)
        }
 
        // Check for the ":".
-       p = skipwhite(*arg);
+       p = may_peek_next_line(cctx, *arg, &next);
        if (*p != ':')
        {
            emsg(_(e_missing_colon));
            return FAIL;
        }
+       if (next != NULL)
+       {
+           *arg = next_line_from_context(cctx, TRUE);
+           p = skipwhite(*arg);
+       }
+
        if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[1]))
        {
            semsg(_(e_white_both), ":");