# HG changeset patch # User Christian Brabandt # Date 1468163705 -7200 # Node ID bdac1019552f19c1c16f7ae6dc40c17602a58b1a # Parent 4f3a46b55fd1cb083f080568a01dca38402b9598 commit https://github.com/vim/vim/commit/8240433f48f7383c281ba2453cc55f10b8ec47d9 Author: Bram Moolenaar Date: Sun Jul 10 17:00:38 2016 +0200 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 --- 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 --- 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 --- 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 *direc 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 --- 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 --- a/src/vim.h +++ b/src/vim.h @@ -941,6 +941,7 @@ extern char *(*dyn_libintl_textdomain)(c #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