# HG changeset patch # User Bram Moolenaar # Date 1593205205 -7200 # Node ID 7acceb76669f5651918b3d7775779c0a6e70bb25 # Parent f7d632ae239d8c252eeca2c7e5a74b9e19f01e17 patch 8.2.1065: Vim9: no line break allowed inside a list Commit: https://github.com/vim/vim/commit/7147820cb978f5b179cfec2f9d8b7774e28d43e0 Author: Bram Moolenaar 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. diff --git a/src/eval.c b/src/eval.c --- 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; /* diff --git a/src/list.c b/src/list.c --- 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 != ']') diff --git a/src/proto/eval.pro b/src/proto/eval.pro --- 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); diff --git a/src/proto/list.pro b/src/proto/list.pro --- 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); diff --git a/src/testdir/test_arglist.vim b/src/testdir/test_arglist.vim --- 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 diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim --- 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'} 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 */ /**/ + 1065, +/**/ 1064, /**/ 1063, diff --git a/src/vim9compile.c b/src/vim9compile.c --- 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] == '{')