Skip to content

Commit dcc58e0

Browse files
committed
patch 8.2.2239: Vim9: concatenating lines with backslash is inconvenient
Problem: Vim9: concatenating lines with backslash is inconvenient. Solution: Support concatenating lines starting with '|', useful for :autocmd, :command, etc. (closes #6702)
1 parent 9b8d622 commit dcc58e0

10 files changed

Lines changed: 86 additions & 41 deletions

File tree

runtime/doc/vim9.txt

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE
88

9-
Vim9 script commands and expressions. *Vim9*
9+
Vim9 script commands and expressions. *Vim9* *vim9*
1010

1111
Most expression help is in |eval.txt|. This file is about the new syntax and
1212
features in Vim9 script.
@@ -113,11 +113,12 @@ In Vi # is a command to list text with numbers. In Vim9 script you can use
113113
114114
To improve readability there must be a space between a command and the #
115115
that starts a comment: >
116-
var = value # comment
117-
var = value# error!
116+
var name = value # comment
117+
var name = value# error!
118118
119-
In legacy script # is also used for the alternate file name. In Vim9 script
120-
you need to use %% instead. Instead of ## use %%% (stands for all arguments).
119+
In legacy Vim script # is also used for the alternate file name. In Vim9
120+
script you need to use %% instead. Instead of ## use %%% (stands for all
121+
arguments).
121122

122123

123124
Vim9 functions ~
@@ -209,13 +210,13 @@ if you are developing a plugin and want to try a new version. If you renamed
209210
something you don't have to worry about the old name still hanging around.
210211

211212
If you do want to keep items, use: >
212-
vimscript noclear
213+
vim9script noclear
213214
214215
You want to use this in scripts that use a `finish` command to bail out at
215216
some point when loaded again. E.g. when a buffer local option is set: >
216-
vimscript noclear
217+
vim9script noclear
217218
setlocal completefunc=SomeFunc
218-
if exists('*SomeFunc') | finish | endif
219+
if exists('*g:SomeFunc') | finish | endif
219220
def g:SomeFunc()
220221
....
221222
@@ -385,9 +386,13 @@ No line break is allowed in the arguments of a lambda up to and including the
385386
This does not work: >
386387
filter(list, (k, v)
387388
=> v > 0)
388-
This also does not work:
389+
This also does not work: >
389390
filter(list, (k,
390391
v) => v > 0)
392+
But you can use a backslash to concatenate the lines before parsing: >
393+
filter(list, (k,
394+
\ v)
395+
\ => v > 0)
391396
392397
Additionally, a lambda can contain statements in {}: >
393398
var Lambda = (arg) => {
@@ -404,8 +409,8 @@ wrap it in parenthesis: >
404409
Automatic line continuation ~
405410

406411
In many cases it is obvious that an expression continues on the next line. In
407-
those cases there is no need to prefix the line with a backslash
408-
|line-continuation|. For example, when a list spans multiple lines: >
412+
those cases there is no need to prefix the line with a backslash (see
413+
|line-continuation|). For example, when a list spans multiple lines: >
409414
var mylist = [
410415
'one',
411416
'two',
@@ -442,6 +447,12 @@ before it: >
442447
var result = MyDict
443448
.member
444449
450+
For commands that have an argument that is a list of commands, the | character
451+
at the start of the line indicates line continuation: >
452+
autocmd BufNewFile *.match if condition
453+
| echo 'match'
454+
| endif
455+
445456
< *E1050*
446457
To make it possible for the operator at the start of the line to be
447458
recognized, it is required to put a colon before a range. This will add
@@ -941,7 +952,7 @@ that you don't do that.
941952

942953

943954
Namespace ~
944-
*:vim9script* *:vim9*
955+
*vim9-namespace*
945956
To recognize a file that can be imported the `vim9script` statement must
946957
appear as the first statement in the file. It tells Vim to interpret the
947958
script in its own namespace, instead of the global namespace. If a file

src/proto/vim9compile.pro

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ int use_typecheck(type_T *actual, type_T *expected);
55
int get_script_item_idx(int sid, char_u *name, int check_writable, cctx_T *cctx);
66
imported_T *find_imported(char_u *name, size_t len, cctx_T *cctx);
77
imported_T *find_imported_in_script(char_u *name, size_t len, int sid);
8-
int vim9_comment_start(char_u *p);
98
char_u *peek_next_line_from_context(cctx_T *cctx);
109
char_u *next_line_from_context(cctx_T *cctx, int skip_comment);
1110
char_u *to_name_end(char_u *arg, int use_namespace);
@@ -15,7 +14,7 @@ void error_white_both(char_u *op, int len);
1514
int assignment_len(char_u *p, int *heredoc);
1615
void vim9_declare_error(char_u *name);
1716
int check_vim9_unlet(char_u *name);
18-
int compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx);
17+
int compile_def_function(ufunc_T *ufunc, int check_return_type, cctx_T *outer_cctx);
1918
void set_function_type(ufunc_T *ufunc);
2019
void delete_instr(isn_T *isn);
2120
void unlink_def_function(ufunc_T *ufunc);

src/proto/vim9script.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
int in_vim9script(void);
33
void ex_vim9script(exarg_T *eap);
44
int not_in_vim9(exarg_T *eap);
5+
int vim9_comment_start(char_u *p);
56
void ex_export(exarg_T *eap);
67
void free_imports_and_script_vars(int sid);
78
void mark_imports_for_reload(int sid);

src/scriptfile.c

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1739,6 +1739,10 @@ getsourceline(
17391739
struct source_cookie *sp = (struct source_cookie *)cookie;
17401740
char_u *line;
17411741
char_u *p;
1742+
int do_vim9_all = in_vim9script()
1743+
&& options == GETLINE_CONCAT_ALL;
1744+
int do_vim9_cont = do_vim9_all
1745+
|| options == GETLINE_CONCAT_CONTDEF;
17421746

17431747
#ifdef FEAT_EVAL
17441748
// If breakpoints have been added/deleted need to check for it.
@@ -1785,32 +1789,35 @@ getsourceline(
17851789
// backslash. We always need to read the next line, keep it in
17861790
// sp->nextline.
17871791
/* Also check for a comment in between continuation lines: "\ */
1788-
// Also check for a Vim9 comment and empty line.
1792+
// Also check for a Vim9 comment, empty line, line starting with '|',
1793+
// but not "||".
17891794
sp->nextline = get_one_sourceline(sp);
17901795
if (sp->nextline != NULL
17911796
&& (*(p = skipwhite(sp->nextline)) == '\\'
17921797
|| (p[0] == '"' && p[1] == '\\' && p[2] == ' ')
1793-
#ifdef FEAT_EVAL
1794-
|| (in_vim9script()
1795-
&& options == GETLINE_CONCAT_ALL
1796-
&& (*p == NUL || vim9_comment_start(p)))
1797-
#endif
1798-
))
1798+
|| (do_vim9_all && (*p == NUL
1799+
|| vim9_comment_start(p)))
1800+
|| (do_vim9_cont && p[0] == '|' && p[1] != '|')))
17991801
{
18001802
garray_T ga;
18011803

18021804
ga_init2(&ga, (int)sizeof(char_u), 400);
18031805
ga_concat(&ga, line);
18041806
if (*p == '\\')
18051807
ga_concat(&ga, p + 1);
1808+
else if (*p == '|')
1809+
{
1810+
ga_concat(&ga, (char_u *)" ");
1811+
ga_concat(&ga, p);
1812+
}
18061813
for (;;)
18071814
{
18081815
vim_free(sp->nextline);
18091816
sp->nextline = get_one_sourceline(sp);
18101817
if (sp->nextline == NULL)
18111818
break;
18121819
p = skipwhite(sp->nextline);
1813-
if (*p == '\\')
1820+
if (*p == '\\' || (do_vim9_cont && p[0] == '|' && p[1] != '|'))
18141821
{
18151822
// Adjust the growsize to the current length to speed up
18161823
// concatenating many lines.
@@ -1821,15 +1828,16 @@ getsourceline(
18211828
else
18221829
ga.ga_growsize = ga.ga_len;
18231830
}
1824-
ga_concat(&ga, p + 1);
1831+
if (*p == '\\')
1832+
ga_concat(&ga, p + 1);
1833+
else
1834+
{
1835+
ga_concat(&ga, (char_u *)" ");
1836+
ga_concat(&ga, p);
1837+
}
18251838
}
18261839
else if (!(p[0] == '"' && p[1] == '\\' && p[2] == ' ')
1827-
#ifdef FEAT_EVAL
1828-
&& !(in_vim9script()
1829-
&& options == GETLINE_CONCAT_ALL
1830-
&& (*p == NUL || vim9_comment_start(p)))
1831-
#endif
1832-
)
1840+
&& !(do_vim9_all && (*p == NUL || vim9_comment_start(p))))
18331841
break;
18341842
/* drop a # comment or "\ comment line */
18351843
}

src/structs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1565,7 +1565,8 @@ typedef void (*cfunc_free_T)(void *state);
15651565
// type of getline() last argument
15661566
typedef enum {
15671567
GETLINE_NONE, // do not concatenate any lines
1568-
GETLINE_CONCAT_CONT, // concatenate continuation lines
1568+
GETLINE_CONCAT_CONT, // concatenate continuation lines in Vim9 script
1569+
GETLINE_CONCAT_CONTDEF, // concatenate continuation lines always
15691570
GETLINE_CONCAT_ALL // concatenate continuation and Vim9 # comment lines
15701571
} getline_opt_T;
15711572

src/testdir/test_vim9_cmd.vim

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,13 +548,33 @@ def Test_command_modifier_other()
548548
bwipe!
549549

550550
au BufNewFile Xfile g:readFile = 1
551+
| g:readExtra = 2
551552
g:readFile = 0
553+
g:readExtra = 0
552554
edit Xfile
553555
assert_equal(1, g:readFile)
556+
assert_equal(2, g:readExtra)
554557
bwipe!
555558
g:readFile = 0
556559
noautocmd edit Xfile
557560
assert_equal(0, g:readFile)
561+
au! BufNewFile
562+
563+
au BufNewFile Xfile g:readFile = 1
564+
| g:readExtra = 2
565+
| g:readMore = 3
566+
g:readFile = 0
567+
g:readExtra = 0
568+
g:readMore = 0
569+
edit Xfile
570+
assert_equal(1, g:readFile)
571+
assert_equal(2, g:readExtra)
572+
assert_equal(3, g:readMore)
573+
bwipe!
574+
au! BufNewFile
575+
unlet g:readFile
576+
unlet g:readExtra
577+
unlet g:readMore
558578

559579
noswapfile edit XnoSwap
560580
assert_equal(0, &l:swapfile)

src/userfunc.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2960,7 +2960,7 @@ define_function(exarg_T *eap, char_u *name_arg)
29602960
static int func_nr = 0; // number for nameless function
29612961
int paren;
29622962
hashitem_T *hi;
2963-
getline_opt_T getline_options = GETLINE_CONCAT_CONT;
2963+
getline_opt_T getline_options;
29642964
linenr_T sourcing_lnum_off;
29652965
linenr_T sourcing_lnum_top;
29662966
int is_heredoc = FALSE;
@@ -3291,6 +3291,8 @@ define_function(exarg_T *eap, char_u *name_arg)
32913291
indent = 2;
32923292
nesting = 0;
32933293
nesting_def[nesting] = (eap->cmdidx == CMD_def);
3294+
getline_options = eap->cmdidx == CMD_def
3295+
? GETLINE_CONCAT_CONTDEF : GETLINE_CONCAT_CONT;
32943296
for (;;)
32953297
{
32963298
if (KeyTyped)
@@ -3365,7 +3367,8 @@ define_function(exarg_T *eap, char_u *name_arg)
33653367
{
33663368
VIM_CLEAR(skip_until);
33673369
VIM_CLEAR(heredoc_trimmed);
3368-
getline_options = GETLINE_CONCAT_CONT;
3370+
getline_options = eap->cmdidx == CMD_def
3371+
? GETLINE_CONCAT_CONTDEF : GETLINE_CONCAT_CONT;
33693372
is_heredoc = FALSE;
33703373
}
33713374
}

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,8 @@ static char *(features[]) =
750750

751751
static int included_patches[] =
752752
{ /* Add new patch number below this line */
753+
/**/
754+
2239,
753755
/**/
754756
2238,
755757
/**/

src/vim9compile.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2164,15 +2164,6 @@ free_imported(cctx_T *cctx)
21642164
ga_clear(&cctx->ctx_imports);
21652165
}
21662166

2167-
/*
2168-
* Return TRUE if "p" points at a "#". Does not check for white space.
2169-
*/
2170-
int
2171-
vim9_comment_start(char_u *p)
2172-
{
2173-
return p[0] == '#';
2174-
}
2175-
21762167
/*
21772168
* Return a pointer to the next line that isn't empty or only contains a
21782169
* comment. Skips over white space.

src/vim9script.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,15 @@ not_in_vim9(exarg_T *eap)
103103
return OK;
104104
}
105105

106+
/*
107+
* Return TRUE if "p" points at a "#". Does not check for white space.
108+
*/
109+
int
110+
vim9_comment_start(char_u *p)
111+
{
112+
return p[0] == '#';
113+
}
114+
106115
#if defined(FEAT_EVAL) || defined(PROTO)
107116

108117
/*

0 commit comments

Comments
 (0)