diff options
| author | Justin M. Keyes <justinkz@gmail.com> | 2018-04-04 01:29:56 +0200 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-04-04 01:29:56 +0200 | 
| commit | 8b8a75b2cf12c6c229ccdd583420b9815ba8d19a (patch) | |
| tree | 0193e2aa809c59750000ebd8013f7948668ae1ee /src/nvim/fileio.c | |
| parent | e40e300c164982ac8e1533863a79f0ea14a8c42f (diff) | |
| parent | e25e552a3d3dda7867b233ffabc5218b331e3a86 (diff) | |
| download | rneovim-8b8a75b2cf12c6c229ccdd583420b9815ba8d19a.tar.gz rneovim-8b8a75b2cf12c6c229ccdd583420b9815ba8d19a.tar.bz2 rneovim-8b8a75b2cf12c6c229ccdd583420b9815ba8d19a.zip | |
Merge #7524 from justinmk/vim-8.0.1281
Diffstat (limited to 'src/nvim/fileio.c')
| -rw-r--r-- | src/nvim/fileio.c | 133 | 
1 files changed, 79 insertions, 54 deletions
| diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 52686f6651..02f72dbce3 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -1,9 +1,7 @@  // This is an open source non-commercial project. Dear PVS-Studio, please check  // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com -/* - * fileio.c: read from and write to a file - */ +// fileio.c: read from and write to a file  #include <assert.h>  #include <errno.h> @@ -65,57 +63,62 @@  #define BUFSIZE         8192    /* size of normal write buffer */  #define SMBUFSIZE       256     /* size of emergency write buffer */ -/* - * The autocommands are stored in a list for each event. - * Autocommands for the same pattern, that are consecutive, are joined - * together, to avoid having to match the pattern too often. - * The result is an array of Autopat lists, which point to AutoCmd lists: - * - * first_autopat[0] --> Autopat.next  -->  Autopat.next -->  NULL - *                      Autopat.cmds       Autopat.cmds - *                          |                    | - *                          V                    V - *                      AutoCmd.next       AutoCmd.next - *                          |                    | - *                          V                    V - *                      AutoCmd.next            NULL - *                          | - *                          V - *                         NULL - * - * first_autopat[1] --> Autopat.next  -->  NULL - *                      Autopat.cmds - *                          | - *                          V - *                      AutoCmd.next - *                          | - *                          V - *                         NULL - *   etc. - * - *   The order of AutoCmds is important, this is the order in which they were - *   defined and will have to be executed. - */ +// +// The autocommands are stored in a list for each event. +// Autocommands for the same pattern, that are consecutive, are joined +// together, to avoid having to match the pattern too often. +// The result is an array of Autopat lists, which point to AutoCmd lists: +// +// last_autopat[0]  -----------------------------+ +//                                               V +// first_autopat[0] --> Autopat.next  -->  Autopat.next -->  NULL +//                      Autopat.cmds       Autopat.cmds +//                          |                    | +//                          V                    V +//                      AutoCmd.next       AutoCmd.next +//                          |                    | +//                          V                    V +//                      AutoCmd.next            NULL +//                          | +//                          V +//                         NULL +// +// last_autopat[1]  --------+ +//                          V +// first_autopat[1] --> Autopat.next  -->  NULL +//                      Autopat.cmds +//                          | +//                          V +//                      AutoCmd.next +//                          | +//                          V +//                         NULL +//   etc. +// +//   The order of AutoCmds is important, this is the order in which they were +//   defined and will have to be executed. +//  typedef struct AutoCmd { -  char_u          *cmd;                 /* The command to be executed (NULL -                                           when command has been removed) */ -  char nested;                          /* If autocommands nest here */ -  char last;                            /* last command in list */ -  scid_T scriptID;                      /* script ID where defined */ -  struct AutoCmd  *next;                /* Next AutoCmd in list */ +  char_u          *cmd;                 // The command to be executed (NULL +                                        // when command has been removed) +  char nested;                          // If autocommands nest here +  char last;                            // last command in list +  scid_T scriptID;                      // script ID where defined +  struct AutoCmd  *next;                // Next AutoCmd in list  } AutoCmd;  typedef struct AutoPat { -  char_u          *pat;                 /* pattern as typed (NULL when pattern -                                           has been removed) */ -  regprog_T       *reg_prog;            /* compiled regprog for pattern */ -  AutoCmd         *cmds;                /* list of commands to do */ -  struct AutoPat  *next;                /* next AutoPat in AutoPat list */ -  int group;                            /* group ID */ -  int patlen;                           /* strlen() of pat */ -  int buflocal_nr;                      /* !=0 for buffer-local AutoPat */ -  char allow_dirs;                      /* Pattern may match whole path */ -  char last;                            /* last pattern for apply_autocmds() */ +  struct AutoPat  *next;                // next AutoPat in AutoPat list; MUST +                                        // be the first entry +  char_u          *pat;                 // pattern as typed (NULL when pattern +                                        // has been removed) +  regprog_T       *reg_prog;            // compiled regprog for pattern +  AutoCmd         *cmds;                // list of commands to do +  int group;                            // group ID +  int patlen;                           // strlen() of pat +  int buflocal_nr;                      // !=0 for buffer-local AutoPat +  char allow_dirs;                      // Pattern may match whole path +  char last;                            // last pattern for apply_autocmds()  } AutoPat;  /* @@ -226,6 +229,15 @@ void filemess(buf_T *buf, char_u *name, char_u *s, int attr)    msg_scrolled_ign = FALSE;  } +static AutoPat *last_autopat[NUM_EVENTS] = { +  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; +  /*   * Read lines from file "fname" into the buffer after line "from".   * @@ -5528,6 +5540,15 @@ static void au_cleanup(void)        /* remove the pattern if it has been marked for deletion */        if (ap->pat == NULL) { +        if (ap->next == NULL) { +          if (prev_ap == &(first_autopat[(int)event])) { +            last_autopat[(int)event] = NULL; +          } else { +            // this depends on the "next" field being the first in +            // the struct +            last_autopat[(int)event] = (AutoPat *)prev_ap; +          } +        }          *prev_ap = ap->next;          vim_regfree(ap->reg_prog);          xfree(ap); @@ -6120,10 +6141,13 @@ static int do_autocmd_event(event_T event, char_u *pat, int nested, char_u *cmd,        patlen = (int)STRLEN(buflocal_pat);       /*   but not endpat */      } -    /* -     * Find AutoPat entries with this pattern. -     */ -    prev_ap = &first_autopat[(int)event]; +    // Find AutoPat entries with this pattern.  When adding a command it +    // always goes at or after the last one, so start at the end. +    if (!forceit && *cmd != NUL && last_autopat[(int)event] != NULL) { +      prev_ap = &last_autopat[(int)event]; +    } else { +      prev_ap = &first_autopat[(int)event]; +    }      while ((ap = *prev_ap) != NULL) {        if (ap->pat != NULL) {          /* Accept a pattern when: @@ -6209,6 +6233,7 @@ static int do_autocmd_event(event_T event, char_u *pat, int nested, char_u *cmd,          }          ap->cmds = NULL;          *prev_ap = ap; +        last_autopat[(int)event] = ap;          ap->next = NULL;          if (group == AUGROUP_ALL)            ap->group = current_augroup; | 
