summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-04-13 14:41:35 +0200
committerBram Moolenaar <Bram@vim.org>2020-04-13 14:41:35 +0200
commit2c330432cfb12181c61d698b5459bfd73d2610df (patch)
tree86e70718a23762d23c42fd292a623efed66205b2
parent1a2f4bf6c80d750615f19c34e5baddd21310c9c9 (diff)
patch 8.2.0567: Vim9: cannot put comments halfway expressionsv8.2.0567
Problem: Vim9: cannot put comments halfway expressions. Solution: Support # comments in many places.
-rw-r--r--runtime/doc/vim9.txt12
-rw-r--r--src/ex_docmd.c3
-rw-r--r--src/testdir/test_vim9_func.vim8
-rw-r--r--src/testdir/test_vim9_script.vim15
-rw-r--r--src/userfunc.c10
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c70
7 files changed, 93 insertions, 27 deletions
diff --git a/runtime/doc/vim9.txt b/runtime/doc/vim9.txt
index 88c35deff5..dd2d510565 100644
--- a/runtime/doc/vim9.txt
+++ b/runtime/doc/vim9.txt
@@ -58,6 +58,15 @@ old scripts, they keep working as before.
THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE
+Comments starting with # ~
+
+In Vim script comments normally start with double quote. That can also be the
+start of a string, thus in many places it cannot be used. In Vim9 script a
+comment can also start with #. Normally this is a command to list text with
+numbers, but you can also use `:number` for that. >
+ let count = 0 # number of occurences of Ni!
+
+
Vim9 functions ~
`:def` has no extra arguments like `:function` does: "range", "abort", "dict"
@@ -241,6 +250,9 @@ Vim9 script enforces proper use of white space. This is no longer allowed: >
let var =234 " Error!
There must be white space before and after the "=": >
let var = 234 " OK
+White space must also be put before the # that starts a comment: >
+ let var = 234# Error!
+ let var = 234 # OK
White space is required around most operators.
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 1cc231deed..047e368e57 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -4764,6 +4764,9 @@ ex_blast(exarg_T *eap)
int
ends_excmd(int c)
{
+ if (c == '#')
+ // TODO: should check for preceding white space
+ return in_vim9script();
return (c == NUL || c == '|' || c == '"' || c == '\n');
}
diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim
index c98acc906d..f0b0ad063c 100644
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -569,6 +569,14 @@ def MultiLine(
return arg1 .. arg2 .. join(rest, '-')
enddef
+def MultiLineComment(
+ arg1: string, # comment
+ arg2 = 1234, # comment
+ ...rest: list<string> # comment
+ ): string # comment
+ return arg1 .. arg2 .. join(rest, '-')
+enddef
+
def Test_multiline()
assert_equal('text1234', MultiLine('text'))
assert_equal('text777', MultiLine('text', 777))
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index 3a08344eaa..c3e3f22623 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -983,10 +983,17 @@ def Test_automatic_line_continuation()
} " comment
assert_equal({'one': 1, 'two': 2, 'three': 3}, mydict)
mydict = #{
- one: 1, " comment
- two:
- 2,
- three: 3 " comment
+ one: 1, # comment
+ two: # comment
+ 2, # comment
+ three: 3 # comment
+ }
+ assert_equal(#{one: 1, two: 2, three: 3}, mydict)
+ mydict = #{
+ one: 1,
+ two:
+ 2,
+ three: 3
}
assert_equal(#{one: 1, two: 2, three: 3}, mydict)
diff --git a/src/userfunc.c b/src/userfunc.c
index 98e1ec5f2e..95483e2b36 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -154,6 +154,7 @@ get_function_args(
int c;
int any_default = FALSE;
char_u *expr;
+ char_u *whitep = arg;
if (newargs != NULL)
ga_init2(newargs, (int)sizeof(char_u *), 3);
@@ -170,7 +171,8 @@ get_function_args(
*/
while (*p != endchar)
{
- if (eap != NULL && *p == NUL && eap->getline != NULL)
+ while (eap != NULL && eap->getline != NULL
+ && (*p == NUL || (VIM_ISWHITE(*whitep) && *p == '#')))
{
char_u *theline;
@@ -180,6 +182,7 @@ get_function_args(
break;
vim_free(*line_to_free);
*line_to_free = theline;
+ whitep = (char_u *)" ";
p = skipwhite(theline);
}
@@ -228,6 +231,7 @@ get_function_args(
// find the end of the expression (doesn't evaluate it)
any_default = TRUE;
p = skipwhite(p) + 1;
+ whitep = p;
p = skipwhite(p);
expr = p;
if (eval1(&p, &rettv, FALSE) != FAIL)
@@ -264,6 +268,7 @@ get_function_args(
else
mustend = TRUE;
}
+ whitep = p;
p = skipwhite(p);
}
@@ -2595,7 +2600,8 @@ ex_function(exarg_T *eap)
// Makes 'exe "func Test()\n...\nendfunc"' work.
if (*p == '\n')
line_arg = p + 1;
- else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg)
+ else if (*p != NUL && *p != '"' && !(eap->cmdidx == CMD_def && *p == '#')
+ && !eap->skip && !did_emsg)
emsg(_(e_trailing));
/*
diff --git a/src/version.c b/src/version.c
index 35f8df8e80..d4250e598d 100644
--- a/src/version.c
+++ b/src/version.c
@@ -739,6 +739,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 567,
+/**/
566,
/**/
565,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index 8a4684d303..666db1599a 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -2070,13 +2070,23 @@ next_line_from_context(cctx_T *cctx)
}
/*
+ * Return TRUE if "p" points at a "#" but not at "#{".
+ */
+ static int
+comment_start(char_u *p)
+{
+ return p[0] == '#' && p[1] != '{';
+}
+
+/*
* If "*arg" is at the end of the line, advance to the next line.
+ * Also when "whitep" points to white space and "*arg" is on a "#".
* Return FAIL if beyond the last line, "*arg" is unmodified then.
*/
static int
-may_get_next_line(char_u **arg, cctx_T *cctx)
+may_get_next_line(char_u *whitep, char_u **arg, cctx_T *cctx)
{
- if (**arg == NUL)
+ if (**arg == NUL || (VIM_ISWHITE(*whitep) && comment_start(*arg)))
{
char_u *next = next_line_from_context(cctx);
@@ -2321,15 +2331,17 @@ theend:
static int
compile_arguments(char_u **arg, cctx_T *cctx, int *argcount)
{
- char_u *p = *arg;
+ char_u *p = *arg;
+ char_u *whitep = *arg;
for (;;)
{
- if (*p == NUL)
+ while (*p == NUL || (VIM_ISWHITE(*whitep) && comment_start(p)))
{
p = next_line_from_context(cctx);
if (p == NULL)
- break;
+ goto failret;
+ whitep = (char_u *)" ";
p = skipwhite(p);
}
if (*p == ')')
@@ -2353,9 +2365,10 @@ compile_arguments(char_u **arg, cctx_T *cctx, int *argcount)
if (*p != NUL && !VIM_ISWHITE(*p))
semsg(_(e_white_after), ",");
}
+ whitep = p;
p = skipwhite(p);
}
-
+failret:
emsg(_(e_missing_close));
return FAIL;
}
@@ -2589,11 +2602,12 @@ need_type(type_T *actual, type_T *expected, int offset, cctx_T *cctx)
compile_list(char_u **arg, cctx_T *cctx)
{
char_u *p = skipwhite(*arg + 1);
+ char_u *whitep = *arg + 1;
int count = 0;
for (;;)
{
- if (*p == NUL)
+ while (*p == NUL || (VIM_ISWHITE(*whitep) && comment_start(p)))
{
p = next_line_from_context(cctx);
if (p == NULL)
@@ -2601,6 +2615,7 @@ compile_list(char_u **arg, cctx_T *cctx)
semsg(_(e_list_end), *arg);
return FAIL;
}
+ whitep = (char_u *)" ";
p = skipwhite(p);
}
if (*p == ']')
@@ -2616,6 +2631,7 @@ compile_list(char_u **arg, cctx_T *cctx)
++count;
if (*p == ',')
++p;
+ whitep = p;
p = skipwhite(p);
}
*arg = p;
@@ -2713,6 +2729,8 @@ compile_dict(char_u **arg, cctx_T *cctx, int literal)
int count = 0;
dict_T *d = dict_alloc();
dictitem_T *item;
+ char_u *whitep = *arg;
+ char_u *p;
if (d == NULL)
return FAIL;
@@ -2721,11 +2739,13 @@ compile_dict(char_u **arg, cctx_T *cctx, int literal)
{
char_u *key = NULL;
- if (**arg == NUL || (literal && **arg == '"'))
+ while (**arg == NUL || (literal && **arg == '"')
+ || (VIM_ISWHITE(*whitep) && comment_start(*arg)))
{
*arg = next_line_from_context(cctx);
if (*arg == NULL)
goto failret;
+ whitep = (char_u *)" ";
*arg = skipwhite(*arg);
}
@@ -2734,17 +2754,17 @@ compile_dict(char_u **arg, cctx_T *cctx, int literal)
if (literal)
{
- char_u *p = to_name_end(*arg, !literal);
+ char_u *end = to_name_end(*arg, !literal);
- if (p == *arg)
+ if (end == *arg)
{
semsg(_("E1014: Invalid key: %s"), *arg);
return FAIL;
}
- key = vim_strnsave(*arg, p - *arg);
+ key = vim_strnsave(*arg, end - *arg);
if (generate_PUSHS(cctx, key) == FAIL)
return FAIL;
- *arg = p;
+ *arg = end;
}
else
{
@@ -2784,12 +2804,14 @@ compile_dict(char_u **arg, cctx_T *cctx, int literal)
return FAIL;
}
+ whitep = *arg + 1;
*arg = skipwhite(*arg + 1);
- if (**arg == NUL)
+ while (**arg == NUL || (VIM_ISWHITE(*whitep) && comment_start(*arg)))
{
*arg = next_line_from_context(cctx);
if (*arg == NULL)
goto failret;
+ whitep = (char_u *)" ";
*arg = skipwhite(*arg);
}
@@ -2797,12 +2819,16 @@ compile_dict(char_u **arg, cctx_T *cctx, int literal)
return FAIL;
++count;
- if (**arg == NUL || *skipwhite(*arg) == '"')
+ whitep = *arg;
+ p = skipwhite(*arg);
+ while (*p == NUL || (VIM_ISWHITE(*whitep) && comment_start(p)))
{
*arg = next_line_from_context(cctx);
if (*arg == NULL)
goto failret;
+ whitep = (char_u *)" ";
*arg = skipwhite(*arg);
+ p = *arg;
}
if (**arg == '}')
break;
@@ -2811,13 +2837,15 @@ compile_dict(char_u **arg, cctx_T *cctx, int literal)
semsg(_(e_missing_dict_comma), *arg);
goto failret;
}
+ whitep = *arg + 1;
*arg = skipwhite(*arg + 1);
}
*arg = *arg + 1;
// Allow for following comment, after at least one space.
- if (VIM_ISWHITE(**arg) && *skipwhite(*arg) == '"')
+ p = skipwhite(*arg);
+ if (VIM_ISWHITE(**arg) && (*p == '"' || comment_start(p)))
*arg += STRLEN(*arg);
dict_unref(d);
@@ -3422,7 +3450,7 @@ compile_expr6(char_u **arg, cctx_T *cctx)
return FAIL;
}
*arg = skipwhite(op + 1);
- if (may_get_next_line(arg, cctx) == FAIL)
+ if (may_get_next_line(op + 1, arg, cctx) == FAIL)
return FAIL;
// get the second variable
@@ -3470,7 +3498,7 @@ compile_expr5(char_u **arg, cctx_T *cctx)
}
*arg = skipwhite(op + oplen);
- if (may_get_next_line(arg, cctx) == FAIL)
+ if (may_get_next_line(op + oplen, arg, cctx) == FAIL)
return FAIL;
// get the second variable
@@ -3608,7 +3636,7 @@ compile_expr4(char_u **arg, cctx_T *cctx)
// get the second variable
*arg = skipwhite(p + len);
- if (may_get_next_line(arg, cctx) == FAIL)
+ if (may_get_next_line(p + len, arg, cctx) == FAIL)
return FAIL;
if (compile_expr5(arg, cctx) == FAIL)
@@ -3658,7 +3686,7 @@ compile_and_or(char_u **arg, cctx_T *cctx, char *op)
// eval the next expression
*arg = skipwhite(p + 2);
- if (may_get_next_line(arg, cctx) == FAIL)
+ if (may_get_next_line(p + 2, arg, cctx) == FAIL)
return FAIL;
if ((opchar == '|' ? compile_expr3(arg, cctx)
@@ -3771,7 +3799,7 @@ compile_expr1(char_u **arg, cctx_T *cctx)
// evaluate the second expression; any type is accepted
*arg = skipwhite(p + 1);
- if (may_get_next_line(arg, cctx) == FAIL)
+ if (may_get_next_line(p + 1, arg, cctx) == FAIL)
return FAIL;
if (compile_expr1(arg, cctx) == FAIL)
@@ -3803,7 +3831,7 @@ compile_expr1(char_u **arg, cctx_T *cctx)
// evaluate the third expression
*arg = skipwhite(p + 1);
- if (may_get_next_line(arg, cctx) == FAIL)
+ if (may_get_next_line(p + 1, arg, cctx) == FAIL)
return FAIL;
if (compile_expr1(arg, cctx) == FAIL)