0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

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)
This commit is contained in:
Bram Moolenaar
2020-12-28 20:53:21 +01:00
parent 9b8d62267f
commit dcc58e031d
10 changed files with 86 additions and 41 deletions

View File

@@ -6,7 +6,7 @@
THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE
Vim9 script commands and expressions. *Vim9* Vim9 script commands and expressions. *Vim9* *vim9*
Most expression help is in |eval.txt|. This file is about the new syntax and Most expression help is in |eval.txt|. This file is about the new syntax and
features in Vim9 script. features in Vim9 script.
@@ -113,11 +113,12 @@ In Vi # is a command to list text with numbers. In Vim9 script you can use
To improve readability there must be a space between a command and the # To improve readability there must be a space between a command and the #
that starts a comment: > that starts a comment: >
var = value # comment var name = value # comment
var = value# error! var name = value# error!
In legacy script # is also used for the alternate file name. In Vim9 script In legacy Vim script # is also used for the alternate file name. In Vim9
you need to use %% instead. Instead of ## use %%% (stands for all arguments). script you need to use %% instead. Instead of ## use %%% (stands for all
arguments).
Vim9 functions ~ Vim9 functions ~
@@ -209,13 +210,13 @@ if you are developing a plugin and want to try a new version. If you renamed
something you don't have to worry about the old name still hanging around. something you don't have to worry about the old name still hanging around.
If you do want to keep items, use: > If you do want to keep items, use: >
vimscript noclear vim9script noclear
You want to use this in scripts that use a `finish` command to bail out at You want to use this in scripts that use a `finish` command to bail out at
some point when loaded again. E.g. when a buffer local option is set: > some point when loaded again. E.g. when a buffer local option is set: >
vimscript noclear vim9script noclear
setlocal completefunc=SomeFunc setlocal completefunc=SomeFunc
if exists('*SomeFunc') | finish | endif if exists('*g:SomeFunc') | finish | endif
def g:SomeFunc() def g:SomeFunc()
.... ....
@@ -385,9 +386,13 @@ No line break is allowed in the arguments of a lambda up to and including the
This does not work: > This does not work: >
filter(list, (k, v) filter(list, (k, v)
=> v > 0) => v > 0)
This also does not work: This also does not work: >
filter(list, (k, filter(list, (k,
v) => v > 0) v) => v > 0)
But you can use a backslash to concatenate the lines before parsing: >
filter(list, (k,
\ v)
\ => v > 0)
Additionally, a lambda can contain statements in {}: > Additionally, a lambda can contain statements in {}: >
var Lambda = (arg) => { var Lambda = (arg) => {
@@ -404,8 +409,8 @@ wrap it in parenthesis: >
Automatic line continuation ~ Automatic line continuation ~
In many cases it is obvious that an expression continues on the next line. In 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 those cases there is no need to prefix the line with a backslash (see
|line-continuation|. For example, when a list spans multiple lines: > |line-continuation|). For example, when a list spans multiple lines: >
var mylist = [ var mylist = [
'one', 'one',
'two', 'two',
@@ -442,6 +447,12 @@ before it: >
var result = MyDict var result = MyDict
.member .member
For commands that have an argument that is a list of commands, the | character
at the start of the line indicates line continuation: >
autocmd BufNewFile *.match if condition
| echo 'match'
| endif
< *E1050* < *E1050*
To make it possible for the operator at the start of the line to be To make it possible for the operator at the start of the line to be
recognized, it is required to put a colon before a range. This will add recognized, it is required to put a colon before a range. This will add
@@ -941,7 +952,7 @@ that you don't do that.
Namespace ~ Namespace ~
*:vim9script* *:vim9* *vim9-namespace*
To recognize a file that can be imported the `vim9script` statement must To recognize a file that can be imported the `vim9script` statement must
appear as the first statement in the file. It tells Vim to interpret the appear as the first statement in the file. It tells Vim to interpret the
script in its own namespace, instead of the global namespace. If a file script in its own namespace, instead of the global namespace. If a file

View File

@@ -5,7 +5,6 @@ int use_typecheck(type_T *actual, type_T *expected);
int get_script_item_idx(int sid, char_u *name, int check_writable, cctx_T *cctx); int get_script_item_idx(int sid, char_u *name, int check_writable, cctx_T *cctx);
imported_T *find_imported(char_u *name, size_t len, cctx_T *cctx); imported_T *find_imported(char_u *name, size_t len, cctx_T *cctx);
imported_T *find_imported_in_script(char_u *name, size_t len, int sid); imported_T *find_imported_in_script(char_u *name, size_t len, int sid);
int vim9_comment_start(char_u *p);
char_u *peek_next_line_from_context(cctx_T *cctx); char_u *peek_next_line_from_context(cctx_T *cctx);
char_u *next_line_from_context(cctx_T *cctx, int skip_comment); char_u *next_line_from_context(cctx_T *cctx, int skip_comment);
char_u *to_name_end(char_u *arg, int use_namespace); char_u *to_name_end(char_u *arg, int use_namespace);
@@ -15,7 +14,7 @@ void error_white_both(char_u *op, int len);
int assignment_len(char_u *p, int *heredoc); int assignment_len(char_u *p, int *heredoc);
void vim9_declare_error(char_u *name); void vim9_declare_error(char_u *name);
int check_vim9_unlet(char_u *name); int check_vim9_unlet(char_u *name);
int compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx); int compile_def_function(ufunc_T *ufunc, int check_return_type, cctx_T *outer_cctx);
void set_function_type(ufunc_T *ufunc); void set_function_type(ufunc_T *ufunc);
void delete_instr(isn_T *isn); void delete_instr(isn_T *isn);
void unlink_def_function(ufunc_T *ufunc); void unlink_def_function(ufunc_T *ufunc);

View File

@@ -2,6 +2,7 @@
int in_vim9script(void); int in_vim9script(void);
void ex_vim9script(exarg_T *eap); void ex_vim9script(exarg_T *eap);
int not_in_vim9(exarg_T *eap); int not_in_vim9(exarg_T *eap);
int vim9_comment_start(char_u *p);
void ex_export(exarg_T *eap); void ex_export(exarg_T *eap);
void free_imports_and_script_vars(int sid); void free_imports_and_script_vars(int sid);
void mark_imports_for_reload(int sid); void mark_imports_for_reload(int sid);

View File

@@ -1739,6 +1739,10 @@ getsourceline(
struct source_cookie *sp = (struct source_cookie *)cookie; struct source_cookie *sp = (struct source_cookie *)cookie;
char_u *line; char_u *line;
char_u *p; char_u *p;
int do_vim9_all = in_vim9script()
&& options == GETLINE_CONCAT_ALL;
int do_vim9_cont = do_vim9_all
|| options == GETLINE_CONCAT_CONTDEF;
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
// If breakpoints have been added/deleted need to check for it. // If breakpoints have been added/deleted need to check for it.
@@ -1785,17 +1789,15 @@ getsourceline(
// backslash. We always need to read the next line, keep it in // backslash. We always need to read the next line, keep it in
// sp->nextline. // sp->nextline.
/* Also check for a comment in between continuation lines: "\ */ /* Also check for a comment in between continuation lines: "\ */
// Also check for a Vim9 comment and empty line. // Also check for a Vim9 comment, empty line, line starting with '|',
// but not "||".
sp->nextline = get_one_sourceline(sp); sp->nextline = get_one_sourceline(sp);
if (sp->nextline != NULL if (sp->nextline != NULL
&& (*(p = skipwhite(sp->nextline)) == '\\' && (*(p = skipwhite(sp->nextline)) == '\\'
|| (p[0] == '"' && p[1] == '\\' && p[2] == ' ') || (p[0] == '"' && p[1] == '\\' && p[2] == ' ')
#ifdef FEAT_EVAL || (do_vim9_all && (*p == NUL
|| (in_vim9script() || vim9_comment_start(p)))
&& options == GETLINE_CONCAT_ALL || (do_vim9_cont && p[0] == '|' && p[1] != '|')))
&& (*p == NUL || vim9_comment_start(p)))
#endif
))
{ {
garray_T ga; garray_T ga;
@@ -1803,6 +1805,11 @@ getsourceline(
ga_concat(&ga, line); ga_concat(&ga, line);
if (*p == '\\') if (*p == '\\')
ga_concat(&ga, p + 1); ga_concat(&ga, p + 1);
else if (*p == '|')
{
ga_concat(&ga, (char_u *)" ");
ga_concat(&ga, p);
}
for (;;) for (;;)
{ {
vim_free(sp->nextline); vim_free(sp->nextline);
@@ -1810,7 +1817,7 @@ getsourceline(
if (sp->nextline == NULL) if (sp->nextline == NULL)
break; break;
p = skipwhite(sp->nextline); p = skipwhite(sp->nextline);
if (*p == '\\') if (*p == '\\' || (do_vim9_cont && p[0] == '|' && p[1] != '|'))
{ {
// Adjust the growsize to the current length to speed up // Adjust the growsize to the current length to speed up
// concatenating many lines. // concatenating many lines.
@@ -1821,15 +1828,16 @@ getsourceline(
else else
ga.ga_growsize = ga.ga_len; ga.ga_growsize = ga.ga_len;
} }
ga_concat(&ga, p + 1); if (*p == '\\')
ga_concat(&ga, p + 1);
else
{
ga_concat(&ga, (char_u *)" ");
ga_concat(&ga, p);
}
} }
else if (!(p[0] == '"' && p[1] == '\\' && p[2] == ' ') else if (!(p[0] == '"' && p[1] == '\\' && p[2] == ' ')
#ifdef FEAT_EVAL && !(do_vim9_all && (*p == NUL || vim9_comment_start(p))))
&& !(in_vim9script()
&& options == GETLINE_CONCAT_ALL
&& (*p == NUL || vim9_comment_start(p)))
#endif
)
break; break;
/* drop a # comment or "\ comment line */ /* drop a # comment or "\ comment line */
} }

View File

@@ -1565,7 +1565,8 @@ typedef void (*cfunc_free_T)(void *state);
// type of getline() last argument // type of getline() last argument
typedef enum { typedef enum {
GETLINE_NONE, // do not concatenate any lines GETLINE_NONE, // do not concatenate any lines
GETLINE_CONCAT_CONT, // concatenate continuation lines GETLINE_CONCAT_CONT, // concatenate continuation lines in Vim9 script
GETLINE_CONCAT_CONTDEF, // concatenate continuation lines always
GETLINE_CONCAT_ALL // concatenate continuation and Vim9 # comment lines GETLINE_CONCAT_ALL // concatenate continuation and Vim9 # comment lines
} getline_opt_T; } getline_opt_T;

View File

@@ -548,13 +548,33 @@ def Test_command_modifier_other()
bwipe! bwipe!
au BufNewFile Xfile g:readFile = 1 au BufNewFile Xfile g:readFile = 1
| g:readExtra = 2
g:readFile = 0 g:readFile = 0
g:readExtra = 0
edit Xfile edit Xfile
assert_equal(1, g:readFile) assert_equal(1, g:readFile)
assert_equal(2, g:readExtra)
bwipe! bwipe!
g:readFile = 0 g:readFile = 0
noautocmd edit Xfile noautocmd edit Xfile
assert_equal(0, g:readFile) assert_equal(0, g:readFile)
au! BufNewFile
au BufNewFile Xfile g:readFile = 1
| g:readExtra = 2
| g:readMore = 3
g:readFile = 0
g:readExtra = 0
g:readMore = 0
edit Xfile
assert_equal(1, g:readFile)
assert_equal(2, g:readExtra)
assert_equal(3, g:readMore)
bwipe!
au! BufNewFile
unlet g:readFile
unlet g:readExtra
unlet g:readMore
noswapfile edit XnoSwap noswapfile edit XnoSwap
assert_equal(0, &l:swapfile) assert_equal(0, &l:swapfile)

View File

@@ -2960,7 +2960,7 @@ define_function(exarg_T *eap, char_u *name_arg)
static int func_nr = 0; // number for nameless function static int func_nr = 0; // number for nameless function
int paren; int paren;
hashitem_T *hi; hashitem_T *hi;
getline_opt_T getline_options = GETLINE_CONCAT_CONT; getline_opt_T getline_options;
linenr_T sourcing_lnum_off; linenr_T sourcing_lnum_off;
linenr_T sourcing_lnum_top; linenr_T sourcing_lnum_top;
int is_heredoc = FALSE; int is_heredoc = FALSE;
@@ -3291,6 +3291,8 @@ define_function(exarg_T *eap, char_u *name_arg)
indent = 2; indent = 2;
nesting = 0; nesting = 0;
nesting_def[nesting] = (eap->cmdidx == CMD_def); nesting_def[nesting] = (eap->cmdidx == CMD_def);
getline_options = eap->cmdidx == CMD_def
? GETLINE_CONCAT_CONTDEF : GETLINE_CONCAT_CONT;
for (;;) for (;;)
{ {
if (KeyTyped) if (KeyTyped)
@@ -3365,7 +3367,8 @@ define_function(exarg_T *eap, char_u *name_arg)
{ {
VIM_CLEAR(skip_until); VIM_CLEAR(skip_until);
VIM_CLEAR(heredoc_trimmed); VIM_CLEAR(heredoc_trimmed);
getline_options = GETLINE_CONCAT_CONT; getline_options = eap->cmdidx == CMD_def
? GETLINE_CONCAT_CONTDEF : GETLINE_CONCAT_CONT;
is_heredoc = FALSE; is_heredoc = FALSE;
} }
} }

View File

@@ -750,6 +750,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 */
/**/
2239,
/**/ /**/
2238, 2238,
/**/ /**/

View File

@@ -2164,15 +2164,6 @@ free_imported(cctx_T *cctx)
ga_clear(&cctx->ctx_imports); ga_clear(&cctx->ctx_imports);
} }
/*
* Return TRUE if "p" points at a "#". Does not check for white space.
*/
int
vim9_comment_start(char_u *p)
{
return p[0] == '#';
}
/* /*
* Return a pointer to the next line that isn't empty or only contains a * Return a pointer to the next line that isn't empty or only contains a
* comment. Skips over white space. * comment. Skips over white space.

View File

@@ -103,6 +103,15 @@ not_in_vim9(exarg_T *eap)
return OK; return OK;
} }
/*
* Return TRUE if "p" points at a "#". Does not check for white space.
*/
int
vim9_comment_start(char_u *p)
{
return p[0] == '#';
}
#if defined(FEAT_EVAL) || defined(PROTO) #if defined(FEAT_EVAL) || defined(PROTO)
/* /*