aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/buffer.c96
-rw-r--r--src/nvim/buffer.h8
-rw-r--r--src/nvim/option.c6
-rw-r--r--src/nvim/quickfix.c25
-rw-r--r--src/nvim/version.c2
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,