src/nvim/fileio.c
// Implements :autocmd.
// Defines an autocmd (does not execute; cf. apply_autocmds_group).
//
// Can be used in the following ways:
//
// :autocmd <event> <pat> <cmd>     Add <cmd> to the list of commands that
//                                  will be automatically executed for <event>
//                                  when editing a file matching <pat>, in
//                                  the current group.
// :autocmd <event> <pat>           Show the autocommands associated with
//                                  <event> and <pat>.
// :autocmd <event>                 Show the autocommands associated with
//                                  <event>.
// :autocmd                         Show all autocommands.
// :autocmd! <event> <pat> <cmd>    Remove all autocommands associated with
//                                  <event> and <pat>, and add the command
//                                  <cmd>, for the current group.
// :autocmd! <event> <pat>          Remove all autocommands associated with
//                                  <event> and <pat> for the current group.
// :autocmd! <event>                Remove all autocommands associated with
//                                  <event> for the current group.
// :autocmd!                        Remove ALL autocommands for the current
//                                  group.
//
//  Multiple events and patterns may be given separated by commas.  Here are
//  some examples:
// :autocmd bufread,bufenter *.c,*.h    set tw=0 smartindent noic
// :autocmd bufleave         *          set tw=79 nosmartindent ic infercase
//
// :autocmd * *.c               show all autocommands for *.c files.
//
// Mostly a {group} argument can optionally appear before <event>.
Implements :autocmd.
Defines an autocmd (does not execute; cf.

Can be used in the following ways.

:autocmd        Add  to the list of commands that
will be automatically executed for 
when editing a file matching , in
the current group.
:autocmd             Show the autocommands associated with
 and .
:autocmd                  Show the autocommands associated with
.
:autocmd                         Show all autocommands.
:autocmd.       Remove all autocommands associated with
 and , and add the command
, for the current group.
:autocmd.            Remove all autocommands associated with
 and  for the current group.
:autocmd.                 Remove all autocommands associated with
 for the current group.
:autocmd.                        Remove ALL autocommands for the current
group.

Multiple events and patterns may be given separated by commas.  Here are
some examples:
:autocmd bufread,bufenter *.c,*.h    set tw=0 smartindent noic
:autocmd bufleave         *          set tw=79 nosmartindent ic infercase

:autocmd * *.c               show all autocommands for *.c files.

Mostly a {group} argument can optionally appear before .
Implements : autocmd . Defines an autocmd ( does not execute ; cf . Can be used in the following ways . : autocmd Add to the list of commands that will be automatically executed for when editing a file matching in the current group . : autocmd Show the autocommands associated with and . : autocmd Show the autocommands associated with . : autocmd Show all autocommands . : autocmd . Remove all autocommands associated with and and add the command for the current group . : autocmd . Remove all autocommands associated with and for the current group . : autocmd . Remove all autocommands associated with for the current group . : autocmd . Remove ALL autocommands for the current group . Multiple events and patterns may be given separated by commas . Here are some examples : : autocmd bufread bufenter * . c * . h set tw = 0 smartindent noic : autocmd bufleave * set tw = 79 nosmartindent ic infercase : autocmd * * . c show all autocommands for * . c files . Mostly a { group } argument can optionally appear before .
void do_autocmd(char_u *arg_in, int forceit)
{
  char_u      *arg = arg_in;
  char_u      *pat;
  char_u      *envpat = NULL;
  char_u      *cmd;
  int need_free = false;
  int nested = false;
  bool once = false;
  int group;
  if (*arg == '|') {
    arg = (char_u *)"";
    group = AUGROUP_ALL;  
  } else {
    group = au_get_grouparg(&arg);
  }
  pat = find_end_event(arg, group != AUGROUP_ALL);
  if (pat == NULL)
    return;
  pat = skipwhite(pat);
  if (*pat == '|') {
    pat = (char_u *)"";
    cmd = (char_u *)"";
  } else {
    cmd = pat;
    while (*cmd && (!ascii_iswhite(*cmd) || cmd[-1] == '\\')) {
        cmd++;
    }
    if (*cmd) {
      *cmd++ = NUL;
    }
    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);
#ifdef BACKSLASH_IN_FILENAME
      p_ssl = p_ssl_save;
#endif
      if (envpat != NULL) {
        pat = envpat;
      }
    }
    cmd = skipwhite(cmd);
    for (size_t i = 0; i < 2; i++) {
      if (*cmd != NUL) {
        if (STRNCMP(cmd, "++once", 6) == 0 && ascii_iswhite(cmd[6])) {
          if (once) {
            EMSG2(_(e_duparg2), "++once");
          }
          once = true;
          cmd = skipwhite(cmd + 6);
        }
        if ((STRNCMP(cmd, "++nested", 8) == 0 && ascii_iswhite(cmd[8]))) {
          if (nested) {
            EMSG2(_(e_duparg2), "++nested");
          }
          nested = true;
          cmd = skipwhite(cmd + 8);
        }
        if (STRNCMP(cmd, "nested", 6) == 0 && ascii_iswhite(cmd[6])) {
          if (nested) {
            EMSG2(_(e_duparg2), "nested");
          }
          nested = true;
          cmd = skipwhite(cmd + 6);
        }
      }
    }
    if (*cmd != NUL) {
      cmd = expand_sfile(cmd);
      if (cmd == NULL) {                
        return;
      }
      need_free = true;
    }
  }
  if (!forceit && *cmd == NUL) {
    MSG_PUTS_TITLE(_("\n--- Autocommands ---"));
  }
  last_event = (event_T)-1;             
  last_group = AUGROUP_ERROR;           
  if (*arg == '*' || *arg == NUL || *arg == '|') {
    for (event_T event = (event_T)0; (int)event < (int)NUM_EVENTS;
         event = (event_T)((int)event + 1)) {
      if (do_autocmd_event(event, pat, once, nested, cmd, forceit, group)
          == FAIL) {
        break;
      }
    }
  } else {
    while (*arg && *arg != '|' && !ascii_iswhite(*arg)) {
      event_T event = event_name2nr(arg, &arg);
      assert(event < NUM_EVENTS);
      if (do_autocmd_event(event, pat, once, nested, cmd, forceit, group)
          == FAIL) {
        break;
      }
    }
  }
  if (need_free)
    xfree(cmd);
  xfree(envpat);
}
void do_autocmd ( char_u * arg_in , int forceit ) { char_u * arg = arg_in ; char_u * pat ; char_u * envpat = NULL ; char_u * cmd ; int need_free = false ; int nested = false ; bool once = false ; int group ; if ( * arg == ' ' ) { arg = ( char_u * ) " " ; group = AUGROUP_ALL ; } else { group = au_get_grouparg ( & arg ) ; } pat = find_end_event ( arg , group != AUGROUP_ALL ) ; if ( pat == NULL ) return ; pat = skipwhite ( pat ) ; if ( * pat == ' ' ) { pat = ( char_u * ) " " ; cmd = ( char_u * ) " " ; } else { cmd = pat ; while ( * cmd && ( ! ascii_iswhite ( * cmd ) || cmd [ -1 ] == ' \\ ' ) ) { cmd ++ ; } if ( * cmd ) { * cmd ++ = NUL ; } 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 ) ; #ifdef BACKSLASH_IN_FILENAME p_ssl = p_ssl_save ; #endif if ( envpat != NULL ) { pat = envpat ; } } cmd = skipwhite ( cmd ) ; for ( size_t i = 0 ; i < 2 ; i ++ ) { if ( * cmd != NUL ) { if ( STRNCMP ( cmd , " " , 6 ) == 0 && ascii_iswhite ( cmd [ 6 ] ) ) { if ( once ) { EMSG2 ( _ ( e_duparg2 ) , " " ) ; } once = true ; cmd = skipwhite ( cmd + 6 ) ; } if ( ( STRNCMP ( cmd , " " , 8 ) == 0 && ascii_iswhite ( cmd [ 8 ] ) ) ) { if ( nested ) { EMSG2 ( _ ( e_duparg2 ) , " " ) ; } nested = true ; cmd = skipwhite ( cmd + 8 ) ; } if ( STRNCMP ( cmd , " " , 6 ) == 0 && ascii_iswhite ( cmd [ 6 ] ) ) { if ( nested ) { EMSG2 ( _ ( e_duparg2 ) , " " ) ; } nested = true ; cmd = skipwhite ( cmd + 6 ) ; } } } if ( * cmd != NUL ) { cmd = expand_sfile ( cmd ) ; if ( cmd == NULL ) { return ; } need_free = true ; } } if ( ! forceit && * cmd == NUL ) { MSG_PUTS_TITLE ( _ ( " \n " ) ) ; } last_event = ( event_T ) - 1 ; last_group = AUGROUP_ERROR ; if ( * arg == ' ' || * arg == NUL || * arg == ' ' ) { for ( event_T event = ( event_T ) 0 ; ( int ) event < ( int ) NUM_EVENTS ; event = ( event_T ) ( ( int ) event + 1 ) ) { if ( do_autocmd_event ( event , pat , once , nested , cmd , forceit , group ) == FAIL ) { break ; } } } else { while ( * arg && * arg != ' ' && ! ascii_iswhite ( * arg ) ) { event_T event = event_name2nr ( arg , & arg ) ; assert ( event < NUM_EVENTS ) ; if ( do_autocmd_event ( event , pat , once , nested , cmd , forceit , group ) == FAIL ) { break ; } } } if ( need_free ) xfree ( cmd ) ; xfree ( envpat ) ; }
Implements :autocmd.
Implements : autocmd .
// no argument, use all groups // Check for a legal group name.  If not, use AUGROUP_ALL. /*
   * Scan over the events.
   * If we find an illegal name, return here, don't do anything.
   */ // Scan over the pattern.  Put a NUL at the end. // Expand environment variables in the pattern.  Set 'shellslash', we want // forward slashes here. // Check for "++once" flag. // Check for "++nested" flag. // Check for the old (deprecated) "nested" flag. // Find the start of the commands. // Expand <sfile> in it. // some error /*
   * Print header when showing autocommands.
   */ // Highlight title /*
   * Loop over the events.
   */ // for listing the event name // for listing the group name