summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2016-07-10 17:00:38 +0200
committerBram Moolenaar <Bram@vim.org>2016-07-10 17:00:38 +0200
commit8240433f48f7383c281ba2453cc55f10b8ec47d9 (patch)
tree6b70e050976645909c15236df272ab9f61672e14
parent2bc127f94016801250f8f24234f90a5182d77e73 (diff)
downloadvim-git-8240433f48f7383c281ba2453cc55f10b8ec47d9.tar.gz
patch 7.4.2017v7.4.2017
Problem: When there are many errors adding them to the quickfix list takes a long time. Solution: Add BLN_NOOPT. Don't call buf_valid() in buf_copy_options(). Remember the last file name used. When going through the buffer list start from the end of the list. Only call buf_valid() when autocommands were executed.
-rw-r--r--src/buffer.c61
-rw-r--r--src/option.c6
-rw-r--r--src/quickfix.c31
-rw-r--r--src/version.c2
-rw-r--r--src/vim.h1
5 files changed, 66 insertions, 35 deletions
diff --git a/src/buffer.c b/src/buffer.c
index b434d58e9..586ab3848 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -316,7 +316,9 @@ buf_valid(buf_T *buf)
{
buf_T *bp;
- for (bp = firstbuf; bp != NULL; bp = bp->b_next)
+ /* Assume that we more often have a recent buffer, start with the last
+ * one. */
+ for (bp = lastbuf; bp != NULL; bp = bp->b_prev)
if (bp == buf)
return TRUE;
return FALSE;
@@ -397,9 +399,9 @@ close_buffer(
if (buf->b_nwindows == 1)
{
buf->b_closing = TRUE;
- apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
- FALSE, buf);
- if (!buf_valid(buf))
+ if (apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
+ FALSE, buf)
+ && !buf_valid(buf))
{
/* Autocommands deleted the buffer. */
aucmd_abort:
@@ -416,9 +418,9 @@ aucmd_abort:
if (!unload_buf)
{
buf->b_closing = TRUE;
- apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname,
- FALSE, buf);
- if (!buf_valid(buf))
+ if (apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname,
+ FALSE, buf)
+ && !buf_valid(buf))
/* Autocommands deleted the buffer. */
goto aucmd_abort;
buf->b_closing = FALSE;
@@ -577,21 +579,23 @@ buf_freeall(buf_T *buf, int flags)
buf->b_closing = TRUE;
if (buf->b_ml.ml_mfp != NULL)
{
- apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, FALSE, buf);
- if (!buf_valid(buf)) /* autocommands may delete the buffer */
+ if (apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname,
+ FALSE, buf)
+ && !buf_valid(buf)) /* autocommands may delete the buffer */
return;
}
if ((flags & BFA_DEL) && buf->b_p_bl)
{
- apply_autocmds(EVENT_BUFDELETE, buf->b_fname, buf->b_fname, FALSE, buf);
- if (!buf_valid(buf)) /* autocommands may delete the buffer */
+ if (apply_autocmds(EVENT_BUFDELETE, buf->b_fname, buf->b_fname,
+ FALSE, buf)
+ && !buf_valid(buf)) /* autocommands may delete the buffer */
return;
}
if (flags & BFA_WIPE)
{
- apply_autocmds(EVENT_BUFWIPEOUT, buf->b_fname, buf->b_fname,
- FALSE, buf);
- if (!buf_valid(buf)) /* autocommands may delete the buffer */
+ if (apply_autocmds(EVENT_BUFWIPEOUT, buf->b_fname, buf->b_fname,
+ FALSE, buf)
+ && !buf_valid(buf)) /* autocommands may delete the buffer */
return;
}
buf->b_closing = FALSE;
@@ -1452,11 +1456,11 @@ set_curbuf(buf_T *buf, int action)
prevbuf = curbuf;
#ifdef FEAT_AUTOCMD
- apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
+ if (!apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf)
# ifdef FEAT_EVAL
- if (buf_valid(prevbuf) && !aborting())
+ || (buf_valid(prevbuf) && !aborting()))
# else
- if (buf_valid(prevbuf))
+ || buf_valid(prevbuf))
# endif
#endif
{
@@ -1654,6 +1658,8 @@ do_autochdir(void)
* If (flags & BLN_LISTED) is TRUE, add new buffer to buffer list.
* If (flags & BLN_DUMMY) is TRUE, don't count it as a real buffer.
* If (flags & BLN_NEW) is TRUE, don't use an existing buffer.
+ * If (flags & BLN_NOOPT) is TRUE, don't copy options from the current buffer
+ * if the buffer already exists.
* This is the ONLY way to create a new buffer.
*/
static int top_file_num = 1; /* highest file number */
@@ -1692,17 +1698,20 @@ buflist_new(
vim_free(ffname);
if (lnum != 0)
buflist_setfpos(buf, curwin, lnum, (colnr_T)0, FALSE);
- /* copy the options now, if 'cpo' doesn't have 's' and not done
- * already */
- buf_copy_options(buf, 0);
+
+ if ((flags & BLN_NOOPT) == 0)
+ /* copy the options now, if 'cpo' doesn't have 's' and not done
+ * already */
+ buf_copy_options(buf, 0);
+
if ((flags & BLN_LISTED) && !buf->b_p_bl)
{
buf->b_p_bl = TRUE;
#ifdef FEAT_AUTOCMD
if (!(flags & BLN_DUMMY))
{
- apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
- if (!buf_valid(buf))
+ if (apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf)
+ && !buf_valid(buf))
return NULL;
}
#endif
@@ -1881,13 +1890,13 @@ buflist_new(
/* Tricky: these autocommands may change the buffer list. They could
* also split the window with re-using the one empty buffer. This may
* result in unexpectedly losing the empty buffer. */
- apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, buf);
- if (!buf_valid(buf))
+ if (apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, buf)
+ && !buf_valid(buf))
return NULL;
if (flags & BLN_LISTED)
{
- apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
- if (!buf_valid(buf))
+ if (apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf)
+ && !buf_valid(buf))
return NULL;
}
# ifdef FEAT_EVAL
diff --git a/src/option.c b/src/option.c
index 95f4c734a..fbf07600e 100644
--- a/src/option.c
+++ b/src/option.c
@@ -10635,12 +10635,6 @@ buf_copy_options(buf_T *buf, int flags)
int did_isk = FALSE;
/*
- * Don't do anything if the buffer is invalid.
- */
- if (buf == NULL || !buf_valid(buf))
- return;
-
- /*
* Skip this when the option defaults have not been set yet. Happens when
* main() allocates the first buffer.
*/
diff --git a/src/quickfix.c b/src/quickfix.c
index 92a020417..065216afe 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -1483,14 +1483,22 @@ copy_loclist(win_T *from, win_T *to)
}
/*
+ * Looking up a buffer can be slow if there are many. Remember the last one
+ * to make this a lot faster if there are multiple matches in the same file.
+ */
+static char_u *qf_last_bufname = NULL;
+static buf_T *qf_last_buf = NULL;
+
+/*
* Get buffer number for file "dir.name".
* Also sets the b_has_qf_entry flag.
*/
static int
qf_get_fnum(qf_info_T *qi, char_u *directory, char_u *fname)
{
- char_u *ptr;
+ char_u *ptr = NULL;
buf_T *buf;
+ char_u *bufname;
if (fname == NULL || *fname == NUL) /* no file name */
return 0;
@@ -1522,13 +1530,30 @@ qf_get_fnum(qf_info_T *qi, char_u *directory, char_u *fname)
ptr = vim_strsave(fname);
}
/* Use concatenated directory name and file name */
- buf = buflist_new(ptr, NULL, (linenr_T)0, 0);
+ bufname = ptr;
+ }
+ else
+ bufname = fname;
+
+ if (qf_last_bufname != NULL && STRCMP(bufname, qf_last_bufname) == 0
+ && buf_valid(qf_last_buf))
+ {
+ buf = qf_last_buf;
vim_free(ptr);
}
else
- buf = buflist_new(fname, NULL, (linenr_T)0, 0);
+ {
+ vim_free(qf_last_bufname);
+ buf = buflist_new(bufname, NULL, (linenr_T)0, BLN_NOOPT);
+ if (bufname == ptr)
+ qf_last_bufname = bufname;
+ else
+ qf_last_bufname = vim_strsave(bufname);
+ qf_last_buf = buf;
+ }
if (buf == NULL)
return 0;
+
buf->b_has_qf_entry = TRUE;
return buf->b_fnum;
}
diff --git a/src/version.c b/src/version.c
index cce37b19f..0d39ffa62 100644
--- 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 */
/**/
+ 2017,
+/**/
2016,
/**/
2015,
diff --git a/src/vim.h b/src/vim.h
index 7d76504bb..4d6f9340d 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -941,6 +941,7 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
#define BLN_LISTED 2 /* put new buffer in buffer list */
#define BLN_DUMMY 4 /* allocating dummy buffer */
#define BLN_NEW 8 /* create a new buffer */
+#define BLN_NOOPT 16 /* don't copy options to existing buffer */
/* Values for in_cinkeys() */
#define KEY_OPEN_FORW 0x101