diff options
| -rw-r--r-- | runtime/doc/autocmd.txt | 9 | ||||
| -rw-r--r-- | src/nvim/fileio.c | 123 | ||||
| -rw-r--r-- | src/nvim/testdir/test_autocmd.vim | 31 | ||||
| -rw-r--r-- | src/nvim/version.c | 2 | 
4 files changed, 105 insertions, 60 deletions
| diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index 4f23aee83d..65e091edf5 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -49,9 +49,6 @@ effects.  Be careful not to destroy your text.  ==============================================================================  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 @@ -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.  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"  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/nvim/fileio.c b/src/nvim/fileio.c index 529b48adbd..bbfa56dfbf 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -5652,13 +5652,14 @@ static event_T event_name2nr(char_u *start, char_u **end)    int i;    int len; -  /* the event name ends with end of line, a blank or a comma */ -  for (p = start; *p && !ascii_iswhite(*p) && *p != ','; ++p) -    ; -  for (i = 0; event_names[i].name != NULL; ++i) { -    len = (int) event_names[i].len; -    if (len == p - start && STRNICMP(event_names[i].name, start, len) == 0) +  // the event name ends with end of line, '|', a blank or a comma */ +  for (p = start; *p && !ascii_iswhite(*p) && *p != ',' && *p != '|'; p++) { +  } +  for (i = 0; event_names[i].name != NULL; i++) { +    len = (int)event_names[i].len; +    if (len == p - start && STRNICMP(event_names[i].name, start, len) == 0) {        break; +    }    }    if (*p == ',')      ++p; @@ -5700,7 +5701,7 @@ find_end_event (      }      pat = arg + 1;    } 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 (have_group)            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>.   */ -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      *envpat = NULL;    char_u      *cmd; @@ -5825,10 +5827,13 @@ void 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 == '|') { +    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); +  }    /*     * Scan over the events. @@ -5838,50 +5843,54 @@ void 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 && (!ascii_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 && (!ascii_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; +      int p_ssl_save = p_ssl; -    p_ssl = TRUE; +      p_ssl = true;  #endif -    envpat = expand_env_save(pat); +      envpat = expand_env_save(pat);  #ifdef BACKSLASH_IN_FILENAME -    p_ssl = p_ssl_save; +      p_ssl = p_ssl_save;  #endif -    if (envpat != NULL) -      pat = envpat; -  } +      if (envpat != NULL) { +        pat = envpat; +      } +    } -  /* -   * Check for "nested" flag. -   */ -  cmd = skipwhite(cmd); -  if (*cmd != NUL && STRNCMP(cmd, "nested", 6) == 0 && ascii_iswhite(cmd[6])) { -    nested = TRUE; -    cmd = skipwhite(cmd + 6); -  } +    // Check for "nested" flag. +    cmd = skipwhite(cmd); +    if (*cmd != NUL && STRNCMP(cmd, "nested", 6) == 0 +        && ascii_iswhite(cmd[6])) { +      nested = true; +      cmd = skipwhite(cmd + 6); +    } -  /* -   * Find the start of the commands. -   * Expand <sfile> in it. -   */ -  if (*cmd != NUL) { -    cmd = expand_sfile(cmd); -    if (cmd == NULL)                /* some error */ -      return; -    need_free = TRUE; +    // Find the start of the commands. +    // Expand <sfile> in it. +    if (*cmd != NUL) { +      cmd = expand_sfile(cmd); +      if (cmd == NULL) {                // some error +        return; +      } +      need_free = true; +    }    }    /* @@ -5895,16 +5904,17 @@ void do_autocmd(char_u *arg, int forceit)    /*     * Loop over the events.     */ -  last_event = (event_T)-1;             /* for listing the event name */ -  last_group = AUGROUP_ERROR;           /* for listing the group name */ -  if (*arg == '*' || *arg == NUL) { +  last_event = (event_T)-1;             // for listing the event name +  last_group = AUGROUP_ERROR;           // for listing the group name +  if (*arg == '*' || *arg == NUL || *arg == '|') {      for (event = (event_T)0; (int)event < (int)NUM_EVENTS; -         event = (event_T)((int)event + 1)) -      if (do_autocmd_event(event, pat, -              nested, cmd, forceit, group) == FAIL) +         event = (event_T)((int)event + 1)) { +      if (do_autocmd_event(event, pat, nested, cmd, forceit, group) == FAIL) {          break; +      } +    }    } else { -    while (*arg && !ascii_iswhite(*arg)) { +    while (*arg && *arg != '|' && !ascii_iswhite(*arg)) {        event_T event = event_name2nr(arg, &arg);        assert(event < NUM_EVENTS);        if (do_autocmd_event(event, pat, nested, cmd, forceit, group) == FAIL) { @@ -5931,7 +5941,8 @@ static int au_get_grouparg(char_u **argp)    char_u      *arg = *argp;    int group = AUGROUP_ALL; -  p = skiptowhite(arg); +  for (p = arg; *p && !ascii_iswhite(*p) && *p != '|'; p++) { +  }    if (p > arg) {      group_name = vim_strnsave(arg, (int)(p - arg));      group = au_find_group(group_name); diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index 1dceb70cd4..5675697dc4 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/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\<C-X>", 'x!')      call assert_equal(0, g:triggered) +    au! CursorHoldI    endfunc  endif @@ -58,5 +60,34 @@ function Test_bufunload()    bwipeout    call assert_equal(["bufunload", "bufdelete", "bufwipeout"], s:li) +  au! test_bufunload_group    augroup! test_bufunload_group  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/nvim/version.c b/src/nvim/version.c index 884b7c9bf5..6ddc0cd77e 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -337,7 +337,7 @@ static int included_patches[] = {    // 2106,    // 2105 NA    // 2104, -  // 2103, +  2103,    // 2102 NA    // 2101,    // 2100, | 
