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

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:
Bram Moolenaar
2021-07-27 21:17:32 +02:00
parent 53ba05b090
commit 5d7c2df536
6 changed files with 84 additions and 14 deletions

View File

@@ -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.

View File

@@ -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.

View File

@@ -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);

View File

@@ -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

View File

@@ -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);
}
} }
/* /*

View File

@@ -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,
/**/ /**/