0
0
mirror of https://github.com/vim/vim.git synced 2025-09-24 03:44:06 -04:00

patch 8.2.0555: Vim9: line continuation is not always needed

Problem:    Vim9: line continuation is not always needed.
Solution:   Recognize continuation lines automatically in list and dict.
This commit is contained in:
Bram Moolenaar
2020-04-12 16:38:57 +02:00
parent acc770a10f
commit 4fdae9996f
5 changed files with 111 additions and 15 deletions

View File

@@ -175,6 +175,17 @@ When using `function()` the resulting type is "func", a function with any
number of arguments and any return type. The function can be defined later. number of arguments and any return type. The function can be defined later.
Automatic line continuation ~
In many cases it is obvious that an expression continues on the next line. In
those cases there is no need to prefix the line with a backslash. For
example, when a list spans multiple lines: >
let mylist = [
'one',
'two',
]
No curly braces expansion ~ No curly braces expansion ~
|curly-braces-names| cannot be used. |curly-braces-names| cannot be used.

View File

@@ -767,7 +767,7 @@ def Test_expr7_dict()
call CheckDefFailure("let x = #{8: 8}", 'E1014:') call CheckDefFailure("let x = #{8: 8}", 'E1014:')
call CheckDefFailure("let x = #{xxx}", 'E720:') call CheckDefFailure("let x = #{xxx}", 'E720:')
call CheckDefFailure("let x = #{xxx: 1", 'E722:') call CheckDefFailure("let x = #{xxx: 1", 'E723:')
call CheckDefFailure("let x = #{xxx: 1,", 'E723:') call CheckDefFailure("let x = #{xxx: 1,", 'E723:')
call CheckDefFailure("let x = {'a': xxx}", 'E1001:') call CheckDefFailure("let x = {'a': xxx}", 'E1001:')
call CheckDefFailure("let x = {xxx: 8}", 'E1001:') call CheckDefFailure("let x = {xxx: 8}", 'E1001:')

View File

@@ -966,6 +966,30 @@ def Test_interrupt_loop()
assert_true(caught, 'should have caught an exception') assert_true(caught, 'should have caught an exception')
enddef enddef
def Test_automatic_line_continuation()
let mylist = [
'one',
'two',
'three',
] " comment
assert_equal(['one', 'two', 'three'], mylist)
let mydict = {
'one': 1,
'two': 2,
'three':
3,
} " comment
assert_equal({'one': 1, 'two': 2, 'three': 3}, mydict)
mydict = #{
one: 1, " comment
two:
2,
three: 3 " comment
}
assert_equal(#{one: 1, two: 2, three: 3}, mydict)
enddef
" Keep this last, it messes up highlighting. " Keep this last, it messes up highlighting.
def Test_substitute_cmd() def Test_substitute_cmd()
new new

View File

@@ -738,6 +738,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
555,
/**/ /**/
554, 554,
/**/ /**/

View File

@@ -2534,6 +2534,27 @@ need_type(type_T *actual, type_T *expected, int offset, cctx_T *cctx)
return OK; return OK;
} }
/*
* Get the next line of the function from "cctx".
* Returns NULL when at the end.
*/
static char_u *
next_line_from_context(cctx_T *cctx)
{
char_u *line = NULL;
do
{
++cctx->ctx_lnum;
if (cctx->ctx_lnum >= cctx->ctx_ufunc->uf_lines.ga_len)
break;
line = ((char_u **)cctx->ctx_ufunc->uf_lines.ga_data)[cctx->ctx_lnum];
SOURCING_LNUM = cctx->ctx_ufunc->uf_script_ctx.sc_lnum
+ cctx->ctx_lnum + 1;
} while (line == NULL);
return line;
}
/* /*
* parse a list: [expr, expr] * parse a list: [expr, expr]
* "*arg" points to the '['. * "*arg" points to the '['.
@@ -2544,12 +2565,25 @@ compile_list(char_u **arg, cctx_T *cctx)
char_u *p = skipwhite(*arg + 1); char_u *p = skipwhite(*arg + 1);
int count = 0; int count = 0;
while (*p != ']') for (;;)
{ {
if (*p == NUL) if (*p == NUL)
{ {
semsg(_(e_list_end), *arg); p = next_line_from_context(cctx);
return FAIL; if (p == NULL)
{
semsg(_(e_list_end), *arg);
return FAIL;
}
p = skipwhite(p);
}
if (*p == ']')
{
++p;
// Allow for following comment, after at least one space.
if (VIM_ISWHITE(*p) && *skipwhite(p) == '"')
p += STRLEN(p);
break;
} }
if (compile_expr1(&p, cctx) == FAIL) if (compile_expr1(&p, cctx) == FAIL)
break; break;
@@ -2558,7 +2592,7 @@ compile_list(char_u **arg, cctx_T *cctx)
++p; ++p;
p = skipwhite(p); p = skipwhite(p);
} }
*arg = p + 1; *arg = p;
generate_NEWLIST(cctx, count); generate_NEWLIST(cctx, count);
return OK; return OK;
@@ -2657,10 +2691,21 @@ compile_dict(char_u **arg, cctx_T *cctx, int literal)
if (d == NULL) if (d == NULL)
return FAIL; return FAIL;
*arg = skipwhite(*arg + 1); *arg = skipwhite(*arg + 1);
while (**arg != '}' && **arg != NUL) for (;;)
{ {
char_u *key = NULL; char_u *key = NULL;
if (**arg == NUL || (literal && **arg == '"'))
{
*arg = next_line_from_context(cctx);
if (*arg == NULL)
goto failret;
*arg = skipwhite(*arg);
}
if (**arg == '}')
break;
if (literal) if (literal)
{ {
char_u *p = to_name_end(*arg, !literal); char_u *p = to_name_end(*arg, !literal);
@@ -2714,10 +2759,25 @@ compile_dict(char_u **arg, cctx_T *cctx, int literal)
} }
*arg = skipwhite(*arg + 1); *arg = skipwhite(*arg + 1);
if (**arg == NUL)
{
*arg = next_line_from_context(cctx);
if (*arg == NULL)
goto failret;
*arg = skipwhite(*arg);
}
if (compile_expr1(arg, cctx) == FAIL) if (compile_expr1(arg, cctx) == FAIL)
return FAIL; return FAIL;
++count; ++count;
if (**arg == NUL || *skipwhite(*arg) == '"')
{
*arg = next_line_from_context(cctx);
if (*arg == NULL)
goto failret;
*arg = skipwhite(*arg);
}
if (**arg == '}') if (**arg == '}')
break; break;
if (**arg != ',') if (**arg != ',')
@@ -2735,10 +2795,16 @@ compile_dict(char_u **arg, cctx_T *cctx, int literal)
} }
*arg = *arg + 1; *arg = *arg + 1;
// Allow for following comment, after at least one space.
if (VIM_ISWHITE(**arg) && *skipwhite(*arg) == '"')
*arg += STRLEN(*arg);
dict_unref(d); dict_unref(d);
return generate_NEWDICT(cctx, count); return generate_NEWDICT(cctx, count);
failret: failret:
if (*arg == NULL)
semsg(_(e_missing_dict_end), _("[end of lines]"));
dict_unref(d); dict_unref(d);
return FAIL; return FAIL;
} }
@@ -5645,16 +5711,9 @@ compile_def_function(ufunc_T *ufunc, int set_return_type)
} }
else else
{ {
do line = next_line_from_context(&cctx);
{ if (cctx.ctx_lnum >= ufunc->uf_lines.ga_len)
++cctx.ctx_lnum;
if (cctx.ctx_lnum == ufunc->uf_lines.ga_len)
break;
line = ((char_u **)ufunc->uf_lines.ga_data)[cctx.ctx_lnum];
} while (line == NULL);
if (cctx.ctx_lnum == ufunc->uf_lines.ga_len)
break; break;
SOURCING_LNUM = ufunc->uf_script_ctx.sc_lnum + cctx.ctx_lnum + 1;
} }
emsg_before = called_emsg; emsg_before = called_emsg;