From: Bram Moolenaar Date: Sun, 10 Jul 2016 15:00:38 +0000 (+0200) Subject: patch 7.4.2017 X-Git-Tag: v7.4.2017 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8240433f48f7383c281ba2453cc55f10b8ec47d9;p=vim patch 7.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. --- 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 @@ -10634,12 +10634,6 @@ buf_copy_options(buf_T *buf, int flags) int dont_do_help; 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 @@ -1482,6 +1482,13 @@ copy_loclist(win_T *from, win_T *to) to->w_llist->qf_curlist = qi->qf_curlist; /* current list */ } +/* + * 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. @@ -1489,8 +1496,9 @@ copy_loclist(win_T *from, win_T *to) 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 @@ -758,6 +758,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2017, /**/ 2016, /**/ 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