vim-patch:7.4.2103

Problem:    Can't have "augroup END" right after ":au!".
Solution:   Check for the bar character before the command argument.

e99e84497b
This commit is contained in:
lonerover 2017-01-05 12:06:09 +08:00
parent e21aef1e10
commit bef645e5e4
4 changed files with 93 additions and 50 deletions

View File

@ -49,9 +49,6 @@ effects. Be careful not to destroy your text.
============================================================================== ==============================================================================
2. Defining autocommands *autocmd-define* 2. Defining autocommands *autocmd-define*
Note: The ":autocmd" command cannot be followed by another command, since any
'|' is considered part of the command.
*:au* *:autocmd* *:au* *:autocmd*
:au[tocmd] [group] {event} {pat} [nested] {cmd} :au[tocmd] [group] {event} {pat} [nested] {cmd}
Add {cmd} to the list of commands that Vim will Add {cmd} to the list of commands that Vim will
@ -64,6 +61,12 @@ Note: The ":autocmd" command cannot be followed by another command, since any
The special pattern <buffer> or <buffer=N> defines a buffer-local autocommand. The special pattern <buffer> or <buffer=N> defines a buffer-local autocommand.
See |autocmd-buflocal|. See |autocmd-buflocal|.
Note: The ":autocmd" command can only be followed by another command when the
'|' appears before {cmd}. This works: >
:augroup mine | au! BufRead | augroup END
But this sees "augroup" as part of the defined command: >
:augroup mine | au BufRead * set tw=70 | augroup END
Note that special characters (e.g., "%", "<cword>") in the ":autocmd" Note that special characters (e.g., "%", "<cword>") in the ":autocmd"
arguments are not expanded when the autocommand is defined. These will be arguments are not expanded when the autocommand is defined. These will be
expanded when the Event is recognized, and the {cmd} is executed. The only expanded when the Event is recognized, and the {cmd} is executed. The only

View File

@ -5652,9 +5652,10 @@ static event_T event_name2nr(char_u *start, char_u **end)
int i; int i;
int len; int len;
/* the event name ends with end of line, a blank or a comma */ // the event name ends with end of line, '|', a blank or a comma */
for (p = start; *p && !ascii_iswhite(*p) && *p != ','; ++p) for (p = start; *p && !ascii_iswhite(*p) && *p != ',' && *p != '|'; ++p) {
; ;
}
for (i = 0; event_names[i].name != NULL; ++i) { for (i = 0; event_names[i].name != NULL; ++i) {
len = (int) event_names[i].len; len = (int) event_names[i].len;
if (len == p - start && STRNICMP(event_names[i].name, start, len) == 0) if (len == p - start && STRNICMP(event_names[i].name, start, len) == 0)
@ -5700,7 +5701,7 @@ find_end_event (
} }
pat = arg + 1; pat = arg + 1;
} else { } else {
for (pat = arg; *pat && !ascii_iswhite(*pat); pat = p) { for (pat = arg; *pat && *pat != '|' && !ascii_iswhite(*pat); pat = p) {
if ((int)event_name2nr(pat, &p) >= (int)NUM_EVENTS) { if ((int)event_name2nr(pat, &p) >= (int)NUM_EVENTS) {
if (have_group) if (have_group)
EMSG2(_("E216: No such event: %s"), pat); EMSG2(_("E216: No such event: %s"), pat);
@ -5815,8 +5816,9 @@ void au_event_restore(char_u *old_ei)
* *
* Mostly a {group} argument can optionally appear before <event>. * Mostly a {group} argument can optionally appear before <event>.
*/ */
void do_autocmd(char_u *arg, int forceit) void do_autocmd(char_u *arg_in, int forceit)
{ {
char_u *arg = arg_in;
char_u *pat; char_u *pat;
char_u *envpat = NULL; char_u *envpat = NULL;
char_u *cmd; char_u *cmd;
@ -5825,10 +5827,13 @@ void do_autocmd(char_u *arg, int forceit)
int nested = FALSE; int nested = FALSE;
int group; int group;
/* if (*arg == '|') {
* Check for a legal group name. If not, use AUGROUP_ALL. arg = (char_u *)"";
*/ group = AUGROUP_ALL; // no argument, use all groups
group = au_get_grouparg(&arg); } else {
// Check for a legal group name. If not, use AUGROUP_ALL.
group = au_get_grouparg(&arg);
}
/* /*
* Scan over the events. * Scan over the events.
@ -5838,50 +5843,53 @@ void do_autocmd(char_u *arg, int forceit)
if (pat == NULL) if (pat == NULL)
return; return;
/*
* Scan over the pattern. Put a NUL at the end.
*/
pat = skipwhite(pat); pat = skipwhite(pat);
cmd = pat; if (*pat == '|') {
while (*cmd && (!ascii_iswhite(*cmd) || cmd[-1] == '\\')) pat = (char_u *)"";
cmd++; cmd = (char_u *)"";
if (*cmd) } else {
*cmd++ = NUL; // Scan over the pattern. Put a NUL at the end.
cmd = pat;
while (*cmd && (!ascii_iswhite(*cmd) || cmd[-1] == '\\')) {
cmd++;
}
if (*cmd) {
*cmd++ = NUL;
}
/* Expand environment variables in the pattern. Set 'shellslash', we want // Expand environment variables in the pattern. Set 'shellslash', we want
* forward slashes here. */ // forward slashes here.
if (vim_strchr(pat, '$') != NULL || vim_strchr(pat, '~') != NULL) { if (vim_strchr(pat, '$') != NULL || vim_strchr(pat, '~') != NULL) {
#ifdef BACKSLASH_IN_FILENAME #ifdef BACKSLASH_IN_FILENAME
int p_ssl_save = p_ssl; int p_ssl_save = p_ssl;
p_ssl = TRUE; p_ssl = true;
#endif #endif
envpat = expand_env_save(pat); envpat = expand_env_save(pat);
#ifdef BACKSLASH_IN_FILENAME #ifdef BACKSLASH_IN_FILENAME
p_ssl = p_ssl_save; p_ssl = p_ssl_save;
#endif #endif
if (envpat != NULL) if (envpat != NULL) {
pat = envpat; pat = envpat;
} }
}
/* // Check for "nested" flag.
* Check for "nested" flag. cmd = skipwhite(cmd);
*/ if (*cmd != NUL && STRNCMP(cmd, "nested", 6) == 0 && ascii_iswhite(cmd[6])) {
cmd = skipwhite(cmd); nested = true;
if (*cmd != NUL && STRNCMP(cmd, "nested", 6) == 0 && ascii_iswhite(cmd[6])) { cmd = skipwhite(cmd + 6);
nested = TRUE; }
cmd = skipwhite(cmd + 6);
}
/* // Find the start of the commands.
* Find the start of the commands. // Expand <sfile> in it.
* Expand <sfile> in it. if (*cmd != NUL) {
*/ cmd = expand_sfile(cmd);
if (*cmd != NUL) { if (cmd == NULL) { // some error
cmd = expand_sfile(cmd); return;
if (cmd == NULL) /* some error */ }
return; need_free = true;
need_free = TRUE; }
} }
/* /*
@ -5897,14 +5905,14 @@ void do_autocmd(char_u *arg, int forceit)
*/ */
last_event = (event_T)-1; /* for listing the event name */ last_event = (event_T)-1; /* for listing the event name */
last_group = AUGROUP_ERROR; /* for listing the group name */ last_group = AUGROUP_ERROR; /* for listing the group name */
if (*arg == '*' || *arg == NUL) { if (*arg == '*' || *arg == NUL || *arg == '|') {
for (event = (event_T)0; (int)event < (int)NUM_EVENTS; for (event = (event_T)0; (int)event < (int)NUM_EVENTS;
event = (event_T)((int)event + 1)) event = (event_T)((int)event + 1))
if (do_autocmd_event(event, pat, if (do_autocmd_event(event, pat,
nested, cmd, forceit, group) == FAIL) nested, cmd, forceit, group) == FAIL)
break; break;
} else { } else {
while (*arg && !ascii_iswhite(*arg)) { while (*arg && *arg != '|' && !ascii_iswhite(*arg)) {
event_T event = event_name2nr(arg, &arg); event_T event = event_name2nr(arg, &arg);
assert(event < NUM_EVENTS); assert(event < NUM_EVENTS);
if (do_autocmd_event(event, pat, nested, cmd, forceit, group) == FAIL) { if (do_autocmd_event(event, pat, nested, cmd, forceit, group) == FAIL) {
@ -5931,7 +5939,8 @@ static int au_get_grouparg(char_u **argp)
char_u *arg = *argp; char_u *arg = *argp;
int group = AUGROUP_ALL; int group = AUGROUP_ALL;
p = skiptowhite(arg); for (p = arg; *p && !ascii_iswhite(*p) && *p != '|'; ++p)
;
if (p > arg) { if (p > arg) {
group_name = vim_strnsave(arg, (int)(p - arg)); group_name = vim_strnsave(arg, (int)(p - arg));
group = au_find_group(group_name); group = au_find_group(group_name);

View File

@ -19,6 +19,7 @@ if has('timers')
call timer_start(100, 'ExitInsertMode') call timer_start(100, 'ExitInsertMode')
call feedkeys('a', 'x!') call feedkeys('a', 'x!')
call assert_equal(1, g:triggered) call assert_equal(1, g:triggered)
au! CursorHoldI
endfunc endfunc
func Test_cursorhold_insert_ctrl_x() func Test_cursorhold_insert_ctrl_x()
@ -29,6 +30,7 @@ if has('timers')
" CursorHoldI does not trigger after CTRL-X " CursorHoldI does not trigger after CTRL-X
call feedkeys("a\<C-X>", 'x!') call feedkeys("a\<C-X>", 'x!')
call assert_equal(0, g:triggered) call assert_equal(0, g:triggered)
au! CursorHoldI
endfunc endfunc
endif endif
@ -58,5 +60,34 @@ function Test_bufunload()
bwipeout bwipeout
call assert_equal(["bufunload", "bufdelete", "bufwipeout"], s:li) call assert_equal(["bufunload", "bufdelete", "bufwipeout"], s:li)
au! test_bufunload_group
augroup! test_bufunload_group augroup! test_bufunload_group
endfunc endfunc
func s:AddAnAutocmd()
augroup vimBarTest
au BufReadCmd * echo 'hello'
augroup END
call assert_equal(3, len(split(execute('au vimBarTest'), "\n")))
endfunc
func Test_early_bar()
" test that a bar is recognized before the {event}
call s:AddAnAutocmd()
augroup vimBarTest | au! | augroup END
call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
call s:AddAnAutocmd()
augroup vimBarTest| au!| augroup END
call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
" test that a bar is recognized after the {event}
call s:AddAnAutocmd()
augroup vimBarTest| au!BufReadCmd| augroup END
call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
" test that a bar is recognized after the {group}
call s:AddAnAutocmd()
au! vimBarTest|echo 'hello'
call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
endfunc

View File

@ -337,7 +337,7 @@ static int included_patches[] = {
// 2106, // 2106,
// 2105 NA // 2105 NA
// 2104, // 2104,
// 2103, 2103,
// 2102 NA // 2102 NA
// 2101, // 2101,
// 2100, // 2100,