mirror of
https://github.com/neovim/neovim.git
synced 2025-09-21 10:48:18 +00:00
vim-patch:8.0.1284: loading file type detection slows down startup
Problem: Loading file type detection slows down startup.
Solution: Store the last pattern of an autocommand event to make appending
quicker.
462455ee8b
This commit is contained in:
@@ -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;
|
||||
|
Reference in New Issue
Block a user