forked from aniani/vim
patch 8.2.3228: cannot use a simple block for the :command argument
Problem: Cannot use a simple block for the :command argument. (Maarten Tournoij) Solution: Recognize a simple {} block. (issue #8623)
This commit is contained in:
@@ -1572,6 +1572,16 @@ feature. Use the full name for new scripts.
|
|||||||
|
|
||||||
Replacement text ~
|
Replacement text ~
|
||||||
|
|
||||||
|
The {repl} argument is normally one long string, possibly with "|" separated
|
||||||
|
commands. A special case is when the argument is "{", then the following
|
||||||
|
lines, up to a line starting with "}" are used and |Vim9| syntax applies.
|
||||||
|
Example: >
|
||||||
|
:command MyCommand {
|
||||||
|
echo 'hello'
|
||||||
|
g:calledMyCommand = true
|
||||||
|
}
|
||||||
|
No nesting is supported.
|
||||||
|
|
||||||
The replacement text {repl} for a user defined command is scanned for special
|
The replacement text {repl} for a user defined command is scanned for special
|
||||||
escape sequences, using <...> notation. Escape sequences are replaced with
|
escape sequences, using <...> notation. Escape sequences are replaced with
|
||||||
values from the entered command line, and all other text is copied unchanged.
|
values from the entered command line, and all other text is copied unchanged.
|
||||||
|
21
src/misc2.c
21
src/misc2.c
@@ -1488,7 +1488,6 @@ ga_grow_inner(garray_T *gap, int n)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(FEAT_EVAL) || defined(FEAT_SEARCHPATH) || defined(PROTO)
|
|
||||||
/*
|
/*
|
||||||
* For a growing array that contains a list of strings: concatenate all the
|
* For a growing array that contains a list of strings: concatenate all the
|
||||||
* strings with a separating "sep".
|
* strings with a separating "sep".
|
||||||
@@ -1524,27 +1523,27 @@ ga_concat_strings(garray_T *gap, char *sep)
|
|||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(FEAT_VIMINFO) || defined(FEAT_EVAL) || defined(PROTO)
|
|
||||||
/*
|
/*
|
||||||
* Make a copy of string "p" and add it to "gap".
|
* Make a copy of string "p" and add it to "gap".
|
||||||
* When out of memory nothing changes.
|
* When out of memory nothing changes and FAIL is returned.
|
||||||
*/
|
*/
|
||||||
void
|
int
|
||||||
ga_add_string(garray_T *gap, char_u *p)
|
ga_add_string(garray_T *gap, char_u *p)
|
||||||
{
|
{
|
||||||
char_u *cp = vim_strsave(p);
|
char_u *cp = vim_strsave(p);
|
||||||
|
|
||||||
if (cp != NULL)
|
if (cp == NULL)
|
||||||
|
return FAIL;
|
||||||
|
|
||||||
|
if (ga_grow(gap, 1) == FAIL)
|
||||||
{
|
{
|
||||||
if (ga_grow(gap, 1) == OK)
|
vim_free(cp);
|
||||||
((char_u **)(gap->ga_data))[gap->ga_len++] = cp;
|
return FAIL;
|
||||||
else
|
|
||||||
vim_free(cp);
|
|
||||||
}
|
}
|
||||||
|
((char_u **)(gap->ga_data))[gap->ga_len++] = cp;
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Concatenate a string to a growarray which contains bytes.
|
* Concatenate a string to a growarray which contains bytes.
|
||||||
|
@@ -43,7 +43,7 @@ void ga_init2(garray_T *gap, int itemsize, int growsize);
|
|||||||
int ga_grow(garray_T *gap, int n);
|
int ga_grow(garray_T *gap, int n);
|
||||||
int ga_grow_inner(garray_T *gap, int n);
|
int ga_grow_inner(garray_T *gap, int n);
|
||||||
char_u *ga_concat_strings(garray_T *gap, char *sep);
|
char_u *ga_concat_strings(garray_T *gap, char *sep);
|
||||||
void ga_add_string(garray_T *gap, char_u *p);
|
int ga_add_string(garray_T *gap, char_u *p);
|
||||||
void ga_concat(garray_T *gap, char_u *s);
|
void ga_concat(garray_T *gap, char_u *s);
|
||||||
void ga_append(garray_T *gap, int c);
|
void ga_append(garray_T *gap, int c);
|
||||||
void append_ga_line(garray_T *gap);
|
void append_ga_line(garray_T *gap);
|
||||||
|
@@ -622,4 +622,22 @@ func Test_usercmd_custom()
|
|||||||
delfunc T2
|
delfunc T2
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_usercmd_with_block()
|
||||||
|
command DoSomething {
|
||||||
|
g:didit = 'yes'
|
||||||
|
g:didmore = 'more'
|
||||||
|
}
|
||||||
|
DoSomething
|
||||||
|
call assert_equal('yes', g:didit)
|
||||||
|
call assert_equal('more', g:didmore)
|
||||||
|
unlet g:didit
|
||||||
|
unlet g:didmore
|
||||||
|
|
||||||
|
let lines =<< trim END
|
||||||
|
command DoesNotEnd {
|
||||||
|
echo 'hello'
|
||||||
|
END
|
||||||
|
call CheckScriptFailure(lines, 'E1026:')
|
||||||
|
endfunc
|
||||||
|
|
||||||
" vim: shiftwidth=2 sts=2 expandtab
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@@ -115,6 +115,7 @@ static struct
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define UC_BUFFER 1 // -buffer: local to current buffer
|
#define UC_BUFFER 1 // -buffer: local to current buffer
|
||||||
|
#define UC_VIM9 2 // {} argument: Vim9 syntax.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Search for a user command that matches "eap->cmd".
|
* Search for a user command that matches "eap->cmd".
|
||||||
@@ -872,10 +873,10 @@ uc_add_command(
|
|||||||
replace_termcodes(rep, &rep_buf, 0, NULL);
|
replace_termcodes(rep, &rep_buf, 0, NULL);
|
||||||
if (rep_buf == NULL)
|
if (rep_buf == NULL)
|
||||||
{
|
{
|
||||||
// Can't replace termcodes - try using the string as is
|
// can't replace termcodes - try using the string as is
|
||||||
rep_buf = vim_strsave(rep);
|
rep_buf = vim_strsave(rep);
|
||||||
|
|
||||||
// Give up if out of memory
|
// give up if out of memory
|
||||||
if (rep_buf == NULL)
|
if (rep_buf == NULL)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
@@ -955,6 +956,8 @@ uc_add_command(
|
|||||||
cmd->uc_def = def;
|
cmd->uc_def = def;
|
||||||
cmd->uc_compl = compl;
|
cmd->uc_compl = compl;
|
||||||
cmd->uc_script_ctx = current_sctx;
|
cmd->uc_script_ctx = current_sctx;
|
||||||
|
if (flags & UC_VIM9)
|
||||||
|
cmd->uc_script_ctx.sc_version = SCRIPT_VERSION_VIM9;
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
cmd->uc_script_ctx.sc_lnum += SOURCING_LNUM;
|
cmd->uc_script_ctx.sc_lnum += SOURCING_LNUM;
|
||||||
cmd->uc_compl_arg = compl_arg;
|
cmd->uc_compl_arg = compl_arg;
|
||||||
@@ -1037,8 +1040,46 @@ ex_command(exarg_T *eap)
|
|||||||
(char_u *)_(e_complete_used_without_nargs), TRUE, TRUE);
|
(char_u *)_(e_complete_used_without_nargs), TRUE, TRUE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
char_u *tofree = NULL;
|
||||||
|
|
||||||
|
if (*p == '{' && ends_excmd2(eap->arg, skipwhite(p + 1))
|
||||||
|
&& eap->getline != NULL)
|
||||||
|
{
|
||||||
|
garray_T ga;
|
||||||
|
char_u *line = NULL;
|
||||||
|
|
||||||
|
ga_init2(&ga, sizeof(char_u *), 10);
|
||||||
|
if (ga_add_string(&ga, p) == FAIL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Read lines between '{' and '}'. Does not support nesting or
|
||||||
|
// here-doc constructs.
|
||||||
|
//
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
vim_free(line);
|
||||||
|
if ((line = eap->getline(':', eap->cookie,
|
||||||
|
0, GETLINE_CONCAT_CONTBAR)) == NULL)
|
||||||
|
{
|
||||||
|
emsg(_(e_missing_rcurly));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ga_add_string(&ga, line) == FAIL)
|
||||||
|
break;
|
||||||
|
if (*skipwhite(line) == '}')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
vim_free(line);
|
||||||
|
p = tofree = ga_concat_strings(&ga, "\n");
|
||||||
|
ga_clear_strings(&ga);
|
||||||
|
flags |= UC_VIM9;
|
||||||
|
}
|
||||||
|
|
||||||
uc_add_command(name, end - name, p, argt, def, flags, compl, compl_arg,
|
uc_add_command(name, end - name, p, argt, def, flags, compl, compl_arg,
|
||||||
addr_type_arg, eap->forceit);
|
addr_type_arg, eap->forceit);
|
||||||
|
vim_free(tofree);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -755,6 +755,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 */
|
||||||
|
/**/
|
||||||
|
3228,
|
||||||
/**/
|
/**/
|
||||||
3227,
|
3227,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user