]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.2.1065: Vim9: no line break allowed inside a list v8.2.1065
authorBram Moolenaar <Bram@vim.org>
Fri, 26 Jun 2020 20:46:27 +0000 (22:46 +0200)
committerBram Moolenaar <Bram@vim.org>
Fri, 26 Jun 2020 20:46:27 +0000 (22:46 +0200)
Problem:    Vim9: no line break allowed inside a list.
Solution:   Handle line break inside a list in Vim9 script.

src/eval.c
src/list.c
src/proto/eval.pro
src/proto/list.pro
src/testdir/test_arglist.vim
src/testdir/test_vim9_expr.vim
src/version.c
src/vim9compile.c

index 1bfe808f54c34bef5202e242b1c1d4a0f68eea78..99003ced2c19043d96e2dc7d09cf3351bbbdeade 100644 (file)
@@ -1771,7 +1771,7 @@ eval_func(
  * Otherwise just return "arg" unmodified and set "getnext" to FALSE.
  * "arg" must point somewhere inside a line, not at the start.
  */
-    static char_u *
+    char_u *
 eval_next_non_blank(char_u *arg, evalarg_T *evalarg, int *getnext)
 {
     *getnext = FALSE;
@@ -1796,7 +1796,7 @@ eval_next_non_blank(char_u *arg, evalarg_T *evalarg, int *getnext)
 /*
  * To be called when eval_next_non_blank() sets "getnext" to TRUE.
  */
-    static char_u *
+    char_u *
 eval_next_line(evalarg_T *evalarg)
 {
     vim_free(evalarg->eval_tofree);
@@ -2773,7 +2773,7 @@ eval7(
     /*
      * List: [expr, expr]
      */
-    case '[':  ret = get_list_tv(arg, rettv, flags, TRUE);
+    case '[':  ret = get_list_tv(arg, rettv, evalarg, TRUE);
                break;
 
     /*
index cf0c99f1314b45dc4706401e756b52f75f5f61b6..611171d1dc62b70152bca7c4b4a91cb0012f885c 100644 (file)
@@ -1156,19 +1156,19 @@ f_join(typval_T *argvars, typval_T *rettv)
 
 /*
  * Allocate a variable for a List and fill it from "*arg".
+ * "*arg" points to the "[".
  * Return OK or FAIL.
  */
     int
-get_list_tv(char_u **arg, typval_T *rettv, int flags, int do_error)
+get_list_tv(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int do_error)
 {
-    int                evaluate = flags & EVAL_EVALUATE;
+    int                evaluate = evalarg == NULL ? FALSE
+                                        : evalarg->eval_flags & EVAL_EVALUATE;
+    int                getnext;
     list_T     *l = NULL;
     typval_T   tv;
     listitem_T *item;
-    evalarg_T  evalarg;
-
-    CLEAR_FIELD(evalarg);
-    evalarg.eval_flags = flags;
+    int                had_comma;
 
     if (evaluate)
     {
@@ -1178,9 +1178,12 @@ get_list_tv(char_u **arg, typval_T *rettv, int flags, int do_error)
     }
 
     *arg = skipwhite(*arg + 1);
+    eval_next_non_blank(*arg, evalarg, &getnext);
+    if (getnext)
+       *arg = eval_next_line(evalarg);
     while (**arg != ']' && **arg != NUL)
     {
-       if (eval1(arg, &tv, &evalarg) == FAIL)  // recursive!
+       if (eval1(arg, &tv, evalarg) == FAIL)   // recursive!
            goto failret;
        if (evaluate)
        {
@@ -1195,15 +1198,24 @@ get_list_tv(char_u **arg, typval_T *rettv, int flags, int do_error)
                clear_tv(&tv);
        }
 
+       // the comma must comma after the value
+       had_comma = **arg == ',';
+       if (had_comma)
+           *arg = skipwhite(*arg + 1);
+
+       // the "]" can be on the next line
+       eval_next_non_blank(*arg, evalarg, &getnext);
+       if (getnext)
+           *arg = eval_next_line(evalarg);
        if (**arg == ']')
            break;
-       if (**arg != ',')
+
+       if (!had_comma)
        {
            if (do_error)
                semsg(_("E696: Missing comma in List: %s"), *arg);
            goto failret;
        }
-       *arg = skipwhite(*arg + 1);
     }
 
     if (**arg != ']')
index 87e447808bc95d94a4407a05ef52ad2becfc2cf6..6ae770ce252fe75ae8cfee7a208bf29e902894b3 100644 (file)
@@ -26,6 +26,8 @@ int next_for_item(void *fi_void, char_u *arg);
 void free_for_info(void *fi_void);
 void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx);
 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);
 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);
index 07dd4e2b1d78236552fc429a1007c7601f7e9669..ddf26a5dd6896d6c4f89f99bf46129d83223e98b 100644 (file)
@@ -39,7 +39,7 @@ void vimlist_remove(list_T *l, listitem_T *item, listitem_T *item2);
 char_u *list2string(typval_T *tv, int copyID, int restore_copyID);
 int list_join(garray_T *gap, list_T *l, char_u *sep, int echo_style, int restore_copyID, int copyID);
 void f_join(typval_T *argvars, typval_T *rettv);
-int get_list_tv(char_u **arg, typval_T *rettv, int flags, int do_error);
+int get_list_tv(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int do_error);
 int write_list(FILE *fd, list_T *list, int binary);
 void init_static_list(staticList10_T *sl);
 void f_list2str(typval_T *argvars, typval_T *rettv);
index f9995a4bc89a0569c4495562c27ec075c7d4c7b9..198ca989a09a55113743b624b4087a8fb2e8305a 100644 (file)
@@ -175,22 +175,25 @@ func Test_argument()
 
   let save_columns = &columns
   let &columns = 79
-  exe 'args ' .. join(range(1, 81))
-  call assert_equal(join([
-        \ '',
-        \ '[1] 6   11  16  21  26  31  36  41  46  51  56  61  66  71  76  81  ',
-        \ '2   7   12  17  22  27  32  37  42  47  52  57  62  67  72  77  ',
-        \ '3   8   13  18  23  28  33  38  43  48  53  58  63  68  73  78  ',
-        \ '4   9   14  19  24  29  34  39  44  49  54  59  64  69  74  79  ',
-        \ '5   10  15  20  25  30  35  40  45  50  55  60  65  70  75  80  ',
-        \ ], "\n"),
-        \ execute('args'))
-
-  " No trailing newline with one item per row.
-  let long_arg = repeat('X', 81)
-  exe 'args ' .. long_arg
-  call assert_equal("\n[".long_arg.']', execute('args'))
-  let &columns = save_columns
+  try
+    exe 'args ' .. join(range(1, 81))
+    call assert_equal(join([
+          \ '',
+          \ '[1] 6   11  16  21  26  31  36  41  46  51  56  61  66  71  76  81  ',
+          \ '2   7   12  17  22  27  32  37  42  47  52  57  62  67  72  77  ',
+          \ '3   8   13  18  23  28  33  38  43  48  53  58  63  68  73  78  ',
+          \ '4   9   14  19  24  29  34  39  44  49  54  59  64  69  74  79  ',
+          \ '5   10  15  20  25  30  35  40  45  50  55  60  65  70  75  80  ',
+          \ ], "\n"),
+          \ execute('args'))
+
+    " No trailing newline with one item per row.
+    let long_arg = repeat('X', 81)
+    exe 'args ' .. long_arg
+    call assert_equal("\n[".long_arg.']', execute('args'))
+  finally
+    let &columns = save_columns
+  endtry
 
   " Setting argument list should fail when the current buffer has unsaved
   " changes
index de4d74165922f602fb0c9ac33363a2afec000126..33a282b061c893a8b6fbd12bbdb2db14490999bc 100644 (file)
@@ -974,7 +974,7 @@ def Test_expr7_list()
   " list
   assert_equal(g:list_empty, [])
   assert_equal(g:list_empty, [  ])
-  assert_equal(g:list_mixed, [1, 'b', false])
+  assert_equal(g:list_mixed, [1, 'b', false,])
   assert_equal('b', g:list_mixed[1])
 
   call CheckDefExecFailure(["let x = g:anint[3]"], 'E714:')
@@ -984,6 +984,26 @@ def Test_expr7_list()
   call CheckDefExecFailure(["let x = g:list_empty[3]"], 'E684:')
 enddef
 
+def Test_expr7_list_vim9script()
+  let lines =<< trim END
+      vim9script
+      let l = [
+               11,
+               22,
+               ]
+      assert_equal([11, 22], l)
+  END
+  CheckScriptSuccess(lines)
+
+  lines =<< trim END
+      vim9script
+      let l = [11,
+               22]
+      assert_equal([11, 22], l)
+  END
+  CheckScriptSuccess(lines)
+enddef
+
 def Test_expr7_lambda()
   " lambda
   let La = { -> 'result'}
index eb0bf8dcdcfd32e8d32390afee7745ced3f89230..074383364475f8f823b1472e7cf431e89e23c9ff 100644 (file)
@@ -754,6 +754,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1065,
 /**/
     1064,
 /**/
index 054eaa63d5d45bcf97d8a913fc969c4ec0d9f4b1..f133a94b734ddda19e6eba1acd1c34ea3855feaf 100644 (file)
@@ -2989,7 +2989,7 @@ to_name_const_end(char_u *arg)
     {
 
        // Can be "[1, 2, 3]->Func()".
-       if (get_list_tv(&p, &rettv, 0, FALSE) == FAIL)
+       if (get_list_tv(&p, &rettv, NULL, FALSE) == FAIL)
            p = arg;
     }
     else if (p == arg && *arg == '#' && arg[1] == '{')