mirror of
https://github.com/neovim/neovim.git
synced 2025-09-21 10:48:18 +00:00
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.
8240433f48
This commit is contained in:
@@ -274,7 +274,9 @@ bool buf_valid(buf_T *buf)
|
|||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
return false;
|
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) {
|
if (bp == buf) {
|
||||||
return true;
|
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 */
|
/* When the buffer is no longer in a window, trigger BufWinLeave */
|
||||||
if (buf->b_nwindows == 1) {
|
if (buf->b_nwindows == 1) {
|
||||||
buf->b_closing = true;
|
buf->b_closing = true;
|
||||||
apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
|
if (apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname, false,
|
||||||
FALSE, buf);
|
buf) && !buf_valid(buf)) {
|
||||||
if (!buf_valid(buf)) {
|
// Autocommands deleted the buffer.
|
||||||
/* Autocommands deleted the buffer. */
|
|
||||||
EMSG(_(e_auabort));
|
EMSG(_(e_auabort));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -384,10 +385,9 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last)
|
|||||||
* BufHidden */
|
* BufHidden */
|
||||||
if (!unload_buf) {
|
if (!unload_buf) {
|
||||||
buf->b_closing = true;
|
buf->b_closing = true;
|
||||||
apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname,
|
if (apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname, false,
|
||||||
FALSE, buf);
|
buf) && !buf_valid(buf)) {
|
||||||
if (!buf_valid(buf)) {
|
// Autocommands deleted the buffer.
|
||||||
/* Autocommands deleted the buffer. */
|
|
||||||
EMSG(_(e_auabort));
|
EMSG(_(e_auabort));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -535,22 +535,25 @@ void buf_freeall(buf_T *buf, int flags)
|
|||||||
|
|
||||||
// Make sure the buffer isn't closed by autocommands.
|
// Make sure the buffer isn't closed by autocommands.
|
||||||
buf->b_closing = true;
|
buf->b_closing = true;
|
||||||
if (buf->b_ml.ml_mfp != NULL) {
|
if ((buf->b_ml.ml_mfp != NULL)
|
||||||
apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, false, buf);
|
&& apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, false, buf)
|
||||||
if (!buf_valid(buf)) { // autocommands may delete the buffer
|
&& !buf_valid(buf)) {
|
||||||
return;
|
// Autocommands may delete the buffer.
|
||||||
}
|
return;
|
||||||
}
|
}
|
||||||
if ((flags & BFA_DEL) && buf->b_p_bl) {
|
if ((flags & BFA_DEL)
|
||||||
apply_autocmds(EVENT_BUFDELETE, buf->b_fname, buf->b_fname, FALSE, buf);
|
&& buf->b_p_bl
|
||||||
if (!buf_valid(buf)) /* autocommands may delete the buffer */
|
&& apply_autocmds(EVENT_BUFDELETE, buf->b_fname, buf->b_fname, false, buf)
|
||||||
return;
|
&& !buf_valid(buf)) {
|
||||||
|
// Autocommands may delete the buffer.
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (flags & BFA_WIPE) {
|
if ((flags & BFA_WIPE)
|
||||||
apply_autocmds(EVENT_BUFWIPEOUT, buf->b_fname, buf->b_fname,
|
&& apply_autocmds(EVENT_BUFWIPEOUT, buf->b_fname, buf->b_fname, false,
|
||||||
FALSE, buf);
|
buf)
|
||||||
if (!buf_valid(buf)) /* autocommands may delete the buffer */
|
&& !buf_valid(buf)) {
|
||||||
return;
|
// Autocommands may delete the buffer.
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
buf->b_closing = false;
|
buf->b_closing = false;
|
||||||
|
|
||||||
@@ -1235,12 +1238,14 @@ void set_curbuf(buf_T *buf, int action)
|
|||||||
/* close_windows() or apply_autocmds() may change curbuf */
|
/* close_windows() or apply_autocmds() may change curbuf */
|
||||||
prevbuf = curbuf;
|
prevbuf = curbuf;
|
||||||
|
|
||||||
apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
|
if (!apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf)
|
||||||
if (buf_valid(prevbuf) && !aborting()) {
|
|| (buf_valid(prevbuf) && !aborting())) {
|
||||||
if (prevbuf == curwin->w_buffer)
|
if (prevbuf == curwin->w_buffer) {
|
||||||
reset_synblock(curwin);
|
reset_synblock(curwin);
|
||||||
if (unload)
|
}
|
||||||
close_windows(prevbuf, FALSE);
|
if (unload) {
|
||||||
|
close_windows(prevbuf, false);
|
||||||
|
}
|
||||||
if (buf_valid(prevbuf) && !aborting()) {
|
if (buf_valid(prevbuf) && !aborting()) {
|
||||||
win_T *previouswin = curwin;
|
win_T *previouswin = curwin;
|
||||||
if (prevbuf == curbuf)
|
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_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_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_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.
|
/// This is the ONLY way to create a new buffer.
|
||||||
///
|
///
|
||||||
/// @param ffname full path of fname or relative
|
/// @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,
|
&& (buf = buflist_findname_file_id(ffname, &file_id,
|
||||||
file_id_valid)) != NULL) {
|
file_id_valid)) != NULL) {
|
||||||
xfree(ffname);
|
xfree(ffname);
|
||||||
if (lnum != 0)
|
if (lnum != 0) {
|
||||||
buflist_setfpos(buf, curwin, lnum, (colnr_T)0, FALSE);
|
buflist_setfpos(buf, curwin, lnum, (colnr_T)0, false);
|
||||||
/* copy the options now, if 'cpo' doesn't have 's' and not done
|
}
|
||||||
* already */
|
if ((flags & BLN_NOOPT) == 0) {
|
||||||
buf_copy_options(buf, 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) {
|
if ((flags & BLN_LISTED) && !buf->b_p_bl) {
|
||||||
buf->b_p_bl = TRUE;
|
buf->b_p_bl = TRUE;
|
||||||
if (!(flags & BLN_DUMMY)) {
|
if (!(flags & BLN_DUMMY)) {
|
||||||
apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
|
if (apply_autocmds(EVENT_BUFADD, NULL, NULL, false, buf)
|
||||||
if (!buf_valid(buf)) {
|
&& !buf_valid(buf)) {
|
||||||
return NULL;
|
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
|
// 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
|
// split the window with re-using the one empty buffer. This may result in
|
||||||
// unexpectedly losing the empty buffer.
|
// unexpectedly losing the empty buffer.
|
||||||
apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, buf);
|
if (apply_autocmds(EVENT_BUFNEW, NULL, NULL, false, buf)
|
||||||
if (!buf_valid(buf)) {
|
&& !buf_valid(buf)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (flags & BLN_LISTED) {
|
if ((flags & BLN_LISTED)
|
||||||
apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
|
&& apply_autocmds(EVENT_BUFADD, NULL, NULL, false, buf)
|
||||||
if (!buf_valid(buf)) {
|
&& !buf_valid(buf)) {
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (aborting()) /* autocmds may abort script processing */
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
if (aborting()) {
|
||||||
|
// Autocmds may abort script processing.
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
|
@@ -15,9 +15,11 @@ enum getf_values {
|
|||||||
|
|
||||||
// Values for buflist_new() flags
|
// Values for buflist_new() flags
|
||||||
enum bln_values {
|
enum bln_values {
|
||||||
BLN_CURBUF = 1, // May re-use curbuf for new buffer
|
BLN_CURBUF = 1, // May re-use curbuf for new buffer
|
||||||
BLN_LISTED = 2, // Put new buffer in buffer list
|
BLN_LISTED = 2, // Put new buffer in buffer list
|
||||||
BLN_DUMMY = 4, // Allocating dummy buffer
|
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()
|
// Values for action argument for do_buffer()
|
||||||
|
@@ -5587,12 +5587,6 @@ void buf_copy_options(buf_T *buf, int flags)
|
|||||||
int dont_do_help;
|
int dont_do_help;
|
||||||
int did_isk = FALSE;
|
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
|
* Skip this when the option defaults have not been set yet. Happens when
|
||||||
* main() allocates the first buffer.
|
* main() allocates the first buffer.
|
||||||
|
@@ -1283,11 +1283,17 @@ void copy_loclist(win_T *from, win_T *to)
|
|||||||
to->w_llist->qf_curlist = qi->qf_curlist; /* current list */
|
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".
|
// Get buffer number for file "directory.fname".
|
||||||
// Also sets the b_has_qf_entry flag.
|
// Also sets the b_has_qf_entry flag.
|
||||||
static int qf_get_fnum(qf_info_T *qi, char_u *directory, char_u *fname)
|
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;
|
buf_T *buf;
|
||||||
if (fname == NULL || *fname == NUL) { // no file name
|
if (fname == NULL || *fname == NUL) { // no file name
|
||||||
return 0;
|
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);
|
ptr = vim_strsave(fname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Use concatenated directory name and file name
|
// 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;
|
||||||
xfree(ptr);
|
xfree(ptr);
|
||||||
} else {
|
} 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) {
|
if (buf == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -423,7 +423,7 @@ static int included_patches[] = {
|
|||||||
// 2020 NA
|
// 2020 NA
|
||||||
2019,
|
2019,
|
||||||
// 2018,
|
// 2018,
|
||||||
// 2017,
|
2017,
|
||||||
// 2016 NA
|
// 2016 NA
|
||||||
2015,
|
2015,
|
||||||
2014,
|
2014,
|
||||||
|
Reference in New Issue
Block a user