mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 8.2.3271: Vim9: cannot use :command or :au with block in :def function
Problem: Vim9: cannot use :command or :au with a block in a :def function. Solution: Recognize the start of the block.
This commit is contained in:
parent
0d4d9ee9bb
commit
e4db17fb6e
@ -2741,7 +2741,7 @@ checkforcmd(
|
||||
* Check for an Ex command with optional tail, not followed by "(".
|
||||
* If there is a match advance "pp" to the argument and return TRUE.
|
||||
*/
|
||||
static int
|
||||
int
|
||||
checkforcmd_noparen(
|
||||
char_u **pp, // start of command
|
||||
char *cmd, // name of command
|
||||
|
@ -9,6 +9,7 @@ void *getline_cookie(char_u *(*fgetline)(int, void *, int, getline_opt_T), void
|
||||
char_u *getline_peek(char_u *(*fgetline)(int, void *, int, getline_opt_T), void *cookie);
|
||||
char *ex_errmsg(char *msg, char_u *arg);
|
||||
int checkforcmd(char_u **pp, char *cmd, int len);
|
||||
int checkforcmd_noparen(char_u **pp, char *cmd, int len);
|
||||
int parse_command_modifiers(exarg_T *eap, char **errormsg, cmdmod_T *cmod, int skip_only);
|
||||
int has_cmdmod(cmdmod_T *cmod);
|
||||
int cmdmod_error(void);
|
||||
|
@ -334,6 +334,34 @@ def Test_block_local_vars_with_func()
|
||||
CheckScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
" legacy func for command that's defined later
|
||||
func InvokeSomeCommand()
|
||||
SomeCommand
|
||||
endfunc
|
||||
|
||||
def Test_autocommand_block()
|
||||
com SomeCommand {
|
||||
g:someVar = 'some'
|
||||
}
|
||||
InvokeSomeCommand()
|
||||
assert_equal('some', g:someVar)
|
||||
|
||||
delcommand SomeCommand
|
||||
unlet g:someVar
|
||||
enddef
|
||||
|
||||
def Test_command_block()
|
||||
au BufNew *.xml {
|
||||
g:otherVar = 'other'
|
||||
}
|
||||
split other.xml
|
||||
assert_equal('other', g:otherVar)
|
||||
|
||||
bwipe!
|
||||
au! BufNew *.xml
|
||||
unlet g:otherVar
|
||||
enddef
|
||||
|
||||
func g:NoSuchFunc()
|
||||
echo 'none'
|
||||
endfunc
|
||||
|
@ -983,29 +983,32 @@ may_get_cmd_block(exarg_T *eap, char_u *p, char_u **tofree, int *flags)
|
||||
if (*p == '{' && ends_excmd2(eap->arg, skipwhite(p + 1))
|
||||
&& eap->getline != NULL)
|
||||
{
|
||||
garray_T ga;
|
||||
char_u *line = NULL;
|
||||
garray_T ga;
|
||||
char_u *line = NULL;
|
||||
|
||||
ga_init2(&ga, sizeof(char_u *), 10);
|
||||
if (ga_add_string(&ga, p) == FAIL)
|
||||
return retp;
|
||||
|
||||
// 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)
|
||||
// If the argument ends in "}" it must have been concatenated already
|
||||
// for ISN_EXEC.
|
||||
if (p[STRLEN(p) - 1] != '}')
|
||||
// Read lines between '{' and '}'. Does not support nesting or
|
||||
// here-doc constructs.
|
||||
for (;;)
|
||||
{
|
||||
emsg(_(e_missing_rcurly));
|
||||
break;
|
||||
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;
|
||||
}
|
||||
if (ga_add_string(&ga, line) == FAIL)
|
||||
break;
|
||||
if (*skipwhite(line) == '}')
|
||||
break;
|
||||
}
|
||||
vim_free(line);
|
||||
retp = *tofree = ga_concat_strings(&ga, "\n");
|
||||
ga_clear_strings(&ga);
|
||||
|
@ -903,12 +903,25 @@ get_function_body(
|
||||
--end;
|
||||
if (end > p && *end == '{')
|
||||
{
|
||||
int is_block;
|
||||
|
||||
// check for trailing "=> {": start of an inline function
|
||||
--end;
|
||||
while (end > p && VIM_ISWHITE(*end))
|
||||
--end;
|
||||
if (end > p + 2 && end[-1] == '=' && end[0] == '>')
|
||||
is_block = end > p + 2 && end[-1] == '=' && end[0] == '>';
|
||||
if (!is_block)
|
||||
{
|
||||
char_u *s = p;
|
||||
|
||||
// check for line starting with "au" for :autocmd or
|
||||
// "com" for :command, these can use a {} block
|
||||
is_block = checkforcmd_noparen(&s, "autocmd", 2)
|
||||
|| checkforcmd_noparen(&s, "command", 3);
|
||||
}
|
||||
|
||||
if (is_block)
|
||||
{
|
||||
// found trailing "=> {", start of an inline function
|
||||
if (nesting == MAX_FUNC_NESTING - 1)
|
||||
emsg(_(e_function_nesting_too_deep));
|
||||
else
|
||||
|
@ -755,6 +755,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
3271,
|
||||
/**/
|
||||
3270,
|
||||
/**/
|
||||
|
@ -8861,11 +8861,13 @@ compile_put(char_u *arg, exarg_T *eap, cctx_T *cctx)
|
||||
* A command that is not compiled, execute with legacy code.
|
||||
*/
|
||||
static char_u *
|
||||
compile_exec(char_u *line, exarg_T *eap, cctx_T *cctx)
|
||||
compile_exec(char_u *line_arg, exarg_T *eap, cctx_T *cctx)
|
||||
{
|
||||
char_u *line = line_arg;
|
||||
char_u *p;
|
||||
int has_expr = FALSE;
|
||||
char_u *nextcmd = (char_u *)"";
|
||||
char_u *tofree = NULL;
|
||||
|
||||
if (cctx->ctx_skip == SKIP_YES)
|
||||
goto theend;
|
||||
@ -8922,6 +8924,34 @@ compile_exec(char_u *line, exarg_T *eap, cctx_T *cctx)
|
||||
nextcmd = p + 1;
|
||||
}
|
||||
}
|
||||
else if (eap->cmdidx == CMD_command || eap->cmdidx == CMD_autocmd)
|
||||
{
|
||||
// If there is a trailing '{' read lines until the '}'
|
||||
p = eap->arg + STRLEN(eap->arg) - 1;
|
||||
while (p > eap->arg && VIM_ISWHITE(*p))
|
||||
--p;
|
||||
if (*p == '{')
|
||||
{
|
||||
exarg_T ea;
|
||||
int flags; // unused
|
||||
int start_lnum = SOURCING_LNUM;
|
||||
|
||||
CLEAR_FIELD(ea);
|
||||
ea.arg = eap->arg;
|
||||
fill_exarg_from_cctx(&ea, cctx);
|
||||
(void)may_get_cmd_block(&ea, p, &tofree, &flags);
|
||||
if (tofree != NULL)
|
||||
{
|
||||
*p = NUL;
|
||||
line = concat_str(line, tofree);
|
||||
if (line == NULL)
|
||||
goto theend;
|
||||
vim_free(tofree);
|
||||
tofree = line;
|
||||
SOURCING_LNUM = start_lnum;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (eap->cmdidx == CMD_syntax && STRNCMP(eap->arg, "include ", 8) == 0)
|
||||
@ -9008,6 +9038,7 @@ theend:
|
||||
--nextcmd;
|
||||
*nextcmd = '|';
|
||||
}
|
||||
vim_free(tofree);
|
||||
|
||||
return nextcmd;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user