diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/buffer.c | 96 | ||||
-rw-r--r-- | src/nvim/buffer.h | 8 | ||||
-rw-r--r-- | src/nvim/option.c | 6 | ||||
-rw-r--r-- | src/nvim/quickfix.c | 25 | ||||
-rw-r--r-- | src/nvim/version.c | 2 |
5 files changed, 80 insertions, 57 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 26dbbe8bb5..53fb43f549 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -274,7 +274,9 @@ bool buf_valid(buf_T *buf) if (buf == NULL) { return false; } - FOR_ALL_BUFFERS(bp) { + // Assume that we more often have a recent buffer, + // start with the last one. + for (buf_T *bp = lastbuf; bp != NULL; bp = bp->b_prev) { if (bp == buf) { return true; } @@ -366,10 +368,9 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last) /* When the buffer is no longer in a window, trigger BufWinLeave */ 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)) { - /* Autocommands deleted the buffer. */ + if (apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname, false, + buf) && !buf_valid(buf)) { + // Autocommands deleted the buffer. EMSG(_(e_auabort)); return; } @@ -384,10 +385,9 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last) * BufHidden */ if (!unload_buf) { buf->b_closing = true; - apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname, - FALSE, buf); - if (!buf_valid(buf)) { - /* Autocommands deleted the buffer. */ + if (apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname, false, + buf) && !buf_valid(buf)) { + // Autocommands deleted the buffer. EMSG(_(e_auabort)); return; } @@ -535,22 +535,25 @@ void buf_freeall(buf_T *buf, int flags) // Make sure the buffer isn't closed by autocommands. 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 - return; - } + if ((buf->b_ml.ml_mfp != NULL) + && 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 */ - return; + if ((flags & BFA_DEL) + && buf->b_p_bl + && 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 */ - return; + if ((flags & BFA_WIPE) + && 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; @@ -1235,12 +1238,14 @@ void set_curbuf(buf_T *buf, int action) /* close_windows() or apply_autocmds() may change curbuf */ prevbuf = curbuf; - apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf); - if (buf_valid(prevbuf) && !aborting()) { - if (prevbuf == curwin->w_buffer) + if (!apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf) + || (buf_valid(prevbuf) && !aborting())) { + if (prevbuf == curwin->w_buffer) { reset_synblock(curwin); - if (unload) - close_windows(prevbuf, FALSE); + } + if (unload) { + close_windows(prevbuf, false); + } if (buf_valid(prevbuf) && !aborting()) { win_T *previouswin = curwin; if (prevbuf == curbuf) @@ -1378,6 +1383,8 @@ static int top_file_num = 1; ///< highest file number /// 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. /// /// @param ffname full path of fname or relative @@ -1408,16 +1415,18 @@ buf_T * buflist_new(char_u *ffname, char_u *sfname, linenr_T lnum, int flags) && (buf = buflist_findname_file_id(ffname, &file_id, file_id_valid)) != NULL) { xfree(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 (lnum != 0) { + buflist_setfpos(buf, curwin, lnum, (colnr_T)0, false); + } + 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; 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; } } @@ -1551,18 +1560,19 @@ buf_T * buflist_new(char_u *ffname, char_u *sfname, linenr_T lnum, int flags) // 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)) { - return NULL; - } + if ((flags & BLN_LISTED) + && apply_autocmds(EVENT_BUFADD, NULL, NULL, false, buf) + && !buf_valid(buf)) { + return NULL; } - if (aborting()) /* autocmds may abort script processing */ + if (aborting()) { + // Autocmds may abort script processing. return NULL; + } } return buf; diff --git a/src/nvim/buffer.h b/src/nvim/buffer.h index 36cbec7e60..1fe8692963 100644 --- a/src/nvim/buffer.h +++ b/src/nvim/buffer.h @@ -15,9 +15,11 @@ enum getf_values { // Values for buflist_new() flags enum bln_values { - BLN_CURBUF = 1, // May re-use curbuf for new buffer - BLN_LISTED = 2, // Put new buffer in buffer list - BLN_DUMMY = 4, // Allocating dummy buffer + BLN_CURBUF = 1, // May re-use curbuf for new buffer + BLN_LISTED = 2, // Put new buffer in buffer list + BLN_DUMMY = 4, // Allocating dummy buffer + // TODO(mhinz): merge patch that introduces BLN_NEW + BLN_NOOPT = 16, // Don't copy options to existing buffer }; // Values for action argument for do_buffer() diff --git a/src/nvim/option.c b/src/nvim/option.c index a4e7da770e..a218323dac 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -5588,12 +5588,6 @@ void 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/nvim/quickfix.c b/src/nvim/quickfix.c index cebff5e8b7..7b22c95967 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -1283,11 +1283,17 @@ void 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 "directory.fname". // 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; + char_u *bufname; buf_T *buf; if (fname == NULL || *fname == NUL) { // no file name return 0; @@ -1314,11 +1320,22 @@ static int 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); + // Use concatenated directory name and file name. + 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; xfree(ptr); } else { - buf = buflist_new(fname, NULL, (linenr_T)0, 0); + xfree(qf_last_bufname); + buf = buflist_new(bufname, NULL, (linenr_T)0, BLN_NOOPT); + qf_last_bufname = (bufname == ptr) ? bufname : vim_strsave(bufname); + qf_last_buf = buf; } if (buf == NULL) { return 0; diff --git a/src/nvim/version.c b/src/nvim/version.c index a12621d06f..d2014c88e1 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -423,7 +423,7 @@ static int included_patches[] = { // 2020 NA 2019, // 2018, - // 2017, + 2017, // 2016 NA 2015, 2014, |