changeset 21028:7acceb76669f v8.2.1065

patch 8.2.1065: Vim9: no line break allowed inside a list Commit: https://github.com/vim/vim/commit/7147820cb978f5b179cfec2f9d8b7774e28d43e0 Author: Bram Moolenaar <Bram@vim.org> Date: Fri Jun 26 22:46:27 2020 +0200 patch 8.2.1065: Vim9: no line break allowed inside a list Problem: Vim9: no line break allowed inside a list. Solution: Handle line break inside a list in Vim9 script.
author Bram Moolenaar <Bram@vim.org>
date Fri, 26 Jun 2020 23:00:05 +0200
parents f7d632ae239d
children 857b879cfc59
files 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
diffstat 8 files changed, 69 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/src/eval.c
+++ b/src/eval.c
@@ -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
 /*
  * 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;
 
     /*
--- a/src/list.c
+++ b/src/list.c
@@ -1156,19 +1156,19 @@ f_join(typval_T *argvars, typval_T *rett
 
 /*
  * 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 *rett
     }
 
     *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 *rett
 		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 != ']')
--- a/src/proto/eval.pro
+++ b/src/proto/eval.pro
@@ -26,6 +26,8 @@ int next_for_item(void *fi_void, char_u 
 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);
--- a/src/proto/list.pro
+++ b/src/proto/list.pro
@@ -39,7 +39,7 @@ void vimlist_remove(list_T *l, listitem_
 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);
--- a/src/testdir/test_arglist.vim
+++ b/src/testdir/test_arglist.vim
@@ -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'))
+  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'))
-  let &columns = save_columns
+    " 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
--- a/src/testdir/test_vim9_expr.vim
+++ b/src/testdir/test_vim9_expr.vim
@@ -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'}
--- 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 */
 /**/
+    1065,
+/**/
     1064,
 /**/
     1063,
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -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] == '{')