diff options
author | Bram Moolenaar <Bram@vim.org> | 2016-07-10 17:00:38 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2016-07-10 17:00:38 +0200 |
commit | 8240433f48f7383c281ba2453cc55f10b8ec47d9 (patch) | |
tree | 6b70e050976645909c15236df272ab9f61672e14 | |
parent | 2bc127f94016801250f8f24234f90a5182d77e73 (diff) | |
download | vim-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.c | 61 | ||||
-rw-r--r-- | src/option.c | 6 | ||||
-rw-r--r-- | src/quickfix.c | 31 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim.h | 1 |
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, @@ -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 |