# HG changeset patch # User Christian Brabandt # Date 1469558706 -7200 # Node ID 01c9630e80e0fd54377f265a65295bd8a42b4d55 # Parent 1869038e346ba80eb0762fc4f48926c62eb9b3de commit https://github.com/vim/vim/commit/e99e84497b89e5f91df519790802770920ecf4fe Author: Bram Moolenaar Date: Tue Jul 26 20:43:40 2016 +0200 patch 7.4.2103 Problem: Can't have "augroup END" right after ":au!". Solution: Check for the bar character before the command argument. diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -52,9 +52,6 @@ effects. Be careful not to destroy your ============================================================================== 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[tocmd] [group] {event} {pat} [nested] {cmd} Add {cmd} to the list of commands that Vim will @@ -67,6 +64,12 @@ Note: The ":autocmd" command cannot be f The special pattern or defines a buffer-local autocommand. 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., "%", "") in the ":autocmd" 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 diff --git a/src/fileio.c b/src/fileio.c --- a/src/fileio.c +++ b/src/fileio.c @@ -8100,8 +8100,8 @@ event_name2nr(char_u *start, char_u **en int i; int len; - /* the event name ends with end of line, a blank or a comma */ - for (p = start; *p && !vim_iswhite(*p) && *p != ','; ++p) + /* the event name ends with end of line, '|', a blank or a comma */ + for (p = start; *p && !vim_iswhite(*p) && *p != ',' && *p != '|'; ++p) ; for (i = 0; event_names[i].name != NULL; ++i) { @@ -8153,7 +8153,7 @@ find_end_event( } else { - for (pat = arg; *pat && !vim_iswhite(*pat); pat = p) + for (pat = arg; *pat && *pat != '|' && !vim_iswhite(*pat); pat = p) { if ((int)event_name2nr(pat, &p) >= (int)NUM_EVENTS) { @@ -8286,8 +8286,9 @@ au_event_restore(char_u *old_ei) * Mostly a {group} argument can optionally appear before . */ void -do_autocmd(char_u *arg, int forceit) -{ +do_autocmd(char_u *arg_in, int forceit) +{ + char_u *arg = arg_in; char_u *pat; char_u *envpat = NULL; char_u *cmd; @@ -8296,12 +8297,20 @@ do_autocmd(char_u *arg, int forceit) int nested = FALSE; int group; - /* - * Check for a legal group name. If not, use AUGROUP_ALL. - */ - group = au_get_grouparg(&arg); - if (arg == NULL) /* out of memory */ - return; + if (*arg == '|') + { + arg = (char_u *)""; + group = AUGROUP_ALL; /* no argument, use all groups */ + } + else + { + /* + * Check for a legal group name. If not, use AUGROUP_ALL. + */ + group = au_get_grouparg(&arg); + if (arg == NULL) /* out of memory */ + return; + } /* * Scan over the events. @@ -8311,53 +8320,61 @@ do_autocmd(char_u *arg, int forceit) if (pat == NULL) return; - /* - * Scan over the pattern. Put a NUL at the end. - */ pat = skipwhite(pat); - cmd = pat; - while (*cmd && (!vim_iswhite(*cmd) || cmd[-1] == '\\')) - cmd++; - if (*cmd) - *cmd++ = NUL; - - /* Expand environment variables in the pattern. Set 'shellslash', we want - * forward slashes here. */ - if (vim_strchr(pat, '$') != NULL || vim_strchr(pat, '~') != NULL) - { + if (*pat == '|') + { + pat = (char_u *)""; + cmd = (char_u *)""; + } + else + { + /* + * Scan over the pattern. Put a NUL at the end. + */ + cmd = pat; + while (*cmd && (!vim_iswhite(*cmd) || cmd[-1] == '\\')) + cmd++; + if (*cmd) + *cmd++ = NUL; + + /* Expand environment variables in the pattern. Set 'shellslash', we want + * forward slashes here. */ + if (vim_strchr(pat, '$') != NULL || vim_strchr(pat, '~') != NULL) + { #ifdef BACKSLASH_IN_FILENAME - int p_ssl_save = p_ssl; - - p_ssl = TRUE; -#endif - envpat = expand_env_save(pat); + int p_ssl_save = p_ssl; + + p_ssl = TRUE; +#endif + envpat = expand_env_save(pat); #ifdef BACKSLASH_IN_FILENAME - p_ssl = p_ssl_save; -#endif - if (envpat != NULL) - pat = envpat; - } - - /* - * Check for "nested" flag. - */ - cmd = skipwhite(cmd); - if (*cmd != NUL && STRNCMP(cmd, "nested", 6) == 0 && vim_iswhite(cmd[6])) - { - nested = TRUE; - cmd = skipwhite(cmd + 6); - } - - /* - * Find the start of the commands. - * Expand in it. - */ - if (*cmd != NUL) - { - cmd = expand_sfile(cmd); - if (cmd == NULL) /* some error */ - return; - need_free = TRUE; + p_ssl = p_ssl_save; +#endif + if (envpat != NULL) + pat = envpat; + } + + /* + * Check for "nested" flag. + */ + cmd = skipwhite(cmd); + if (*cmd != NUL && STRNCMP(cmd, "nested", 6) == 0 && vim_iswhite(cmd[6])) + { + nested = TRUE; + cmd = skipwhite(cmd + 6); + } + + /* + * Find the start of the commands. + * Expand in it. + */ + if (*cmd != NUL) + { + cmd = expand_sfile(cmd); + if (cmd == NULL) /* some error */ + return; + need_free = TRUE; + } } /* @@ -8374,7 +8391,7 @@ do_autocmd(char_u *arg, int forceit) */ last_event = (event_T)-1; /* for listing the event 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; event = (event_T)((int)event + 1)) @@ -8384,7 +8401,7 @@ do_autocmd(char_u *arg, int forceit) } else { - while (*arg && !vim_iswhite(*arg)) + while (*arg && *arg != '|' && !vim_iswhite(*arg)) if (do_autocmd_event(event_name2nr(arg, &arg), pat, nested, cmd, forceit, group) == FAIL) break; @@ -8409,7 +8426,8 @@ au_get_grouparg(char_u **argp) char_u *arg = *argp; int group = AUGROUP_ALL; - p = skiptowhite(arg); + for (p = arg; *p && !vim_iswhite(*p) && *p != '|'; ++p) + ; if (p > arg) { group_name = vim_strnsave(arg, (int)(p - arg)); diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -19,6 +19,7 @@ if has('timers') call timer_start(100, 'ExitInsertMode') call feedkeys('a', 'x!') call assert_equal(1, g:triggered) + au! CursorHoldI endfunc func Test_cursorhold_insert_ctrl_x() @@ -29,6 +30,7 @@ if has('timers') " CursorHoldI does not trigger after CTRL-X call feedkeys("a\", 'x!') call assert_equal(0, g:triggered) + au! CursorHoldI endfunc endif @@ -58,6 +60,7 @@ function Test_bufunload() bwipeout call assert_equal(["bufunload", "bufdelete", "bufwipeout"], s:li) + au! test_bufunload_group augroup! test_bufunload_group endfunc @@ -120,3 +123,31 @@ func Test_win_tab_autocmd() augroup END unlet g:record 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 diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -759,6 +759,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2103, +/**/ 2102, /**/ 2101,