mirror of
https://github.com/neovim/neovim.git
synced 2025-09-07 20:08:17 +00:00
Merge pull request #5913 from mhinz/buf-lookup-patches
vim-patch:7.4.2017,7.4.2018,7.4.2021,7.4.2022,7.4.2023,7.4.2024
This commit is contained in:
@@ -78,6 +78,9 @@ static char *msg_loclist = N_("[Location List]");
|
||||
static char *msg_qflist = N_("[Quickfix List]");
|
||||
static char *e_auabort = N_("E855: Autocommands caused command to abort");
|
||||
|
||||
// Number of times free_buffer() was called.
|
||||
static int buf_free_count = 0;
|
||||
|
||||
/*
|
||||
* Open current buffer, that is: open the memfile and read the file into
|
||||
* memory.
|
||||
@@ -91,7 +94,7 @@ open_buffer (
|
||||
)
|
||||
{
|
||||
int retval = OK;
|
||||
buf_T *old_curbuf;
|
||||
bufref_T old_curbuf;
|
||||
long old_tw = curbuf->b_p_tw;
|
||||
|
||||
/*
|
||||
@@ -133,10 +136,10 @@ open_buffer (
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
/* The autocommands in readfile() may change the buffer, but only AFTER
|
||||
* reading the file. */
|
||||
old_curbuf = curbuf;
|
||||
modified_was_set = FALSE;
|
||||
// The autocommands in readfile() may change the buffer, but only AFTER
|
||||
// reading the file.
|
||||
set_bufref(&old_curbuf, curbuf);
|
||||
modified_was_set = false;
|
||||
|
||||
/* mark cursor position as being invalid */
|
||||
curwin->w_valid = 0;
|
||||
@@ -249,11 +252,11 @@ open_buffer (
|
||||
* The autocommands may have changed the current buffer. Apply the
|
||||
* modelines to the correct buffer, if it still exists and is loaded.
|
||||
*/
|
||||
if (buf_valid(old_curbuf) && old_curbuf->b_ml.ml_mfp != NULL) {
|
||||
if (bufref_valid(&old_curbuf) && old_curbuf.br_buf->b_ml.ml_mfp != NULL) {
|
||||
aco_save_T aco;
|
||||
|
||||
/* Go to the buffer that was opened. */
|
||||
aucmd_prepbuf(&aco, old_curbuf);
|
||||
// Go to the buffer that was opened.
|
||||
aucmd_prepbuf(&aco, old_curbuf.br_buf);
|
||||
do_modelines(0);
|
||||
curbuf->b_flags &= ~(BF_CHECK_RO | BF_NEVERLOADED);
|
||||
|
||||
@@ -267,14 +270,42 @@ open_buffer (
|
||||
return retval;
|
||||
}
|
||||
|
||||
/// Check that "buf" points to a valid buffer (in the buffer list).
|
||||
/// Store "buf" in "bufref" and set the free count.
|
||||
///
|
||||
/// @param bufref Reference to be used for the buffer.
|
||||
/// @param buf The buffer to reference.
|
||||
void set_bufref(bufref_T *bufref, buf_T *buf)
|
||||
{
|
||||
bufref->br_buf = buf;
|
||||
bufref->br_buf_free_count = buf_free_count;
|
||||
}
|
||||
|
||||
/// Check if "bufref" points to a valid buffer.
|
||||
///
|
||||
/// Only goes through the buffer list if buf_free_count changed.
|
||||
///
|
||||
/// @param bufref Buffer reference to check for.
|
||||
bool bufref_valid(bufref_T *bufref)
|
||||
{
|
||||
return bufref->br_buf_free_count == buf_free_count
|
||||
? true
|
||||
: buf_valid(bufref->br_buf);
|
||||
}
|
||||
|
||||
/// Check that "buf" points to a valid buffer in the buffer list.
|
||||
///
|
||||
/// Can be slow if there are many buffers, prefer using bufref_valid().
|
||||
///
|
||||
/// @param buf The buffer to check for.
|
||||
bool buf_valid(buf_T *buf)
|
||||
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
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;
|
||||
}
|
||||
@@ -363,13 +394,15 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last)
|
||||
win->w_cursor.col, TRUE);
|
||||
}
|
||||
|
||||
bufref_T bufref;
|
||||
set_bufref(&bufref, buf);
|
||||
|
||||
/* 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) && !bufref_valid(&bufref)) {
|
||||
// Autocommands deleted the buffer.
|
||||
EMSG(_(e_auabort));
|
||||
return;
|
||||
}
|
||||
@@ -384,10 +417,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) && !bufref_valid(&bufref)) {
|
||||
// Autocommands deleted the buffer.
|
||||
EMSG(_(e_auabort));
|
||||
return;
|
||||
}
|
||||
@@ -431,11 +463,14 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last)
|
||||
|
||||
buf_freeall(buf, (del_buf ? BFA_DEL : 0) + (wipe_buf ? BFA_WIPE : 0));
|
||||
|
||||
/* Autocommands may have deleted the buffer. */
|
||||
if (!buf_valid(buf))
|
||||
if (!bufref_valid(&bufref)) {
|
||||
// Autocommands may have deleted the buffer.
|
||||
return;
|
||||
if (aborting()) /* autocmds may abort script processing */
|
||||
}
|
||||
if (aborting()) {
|
||||
// Autocmds may abort script processing.
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* It's possible that autocommands change curbuf to the one being deleted.
|
||||
@@ -535,22 +570,29 @@ 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;
|
||||
}
|
||||
|
||||
bufref_T bufref;
|
||||
set_bufref(&bufref, buf);
|
||||
|
||||
if ((buf->b_ml.ml_mfp != NULL)
|
||||
&& apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, false, buf)
|
||||
&& !bufref_valid(&bufref)) {
|
||||
// Autocommands deleted 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)
|
||||
&& !bufref_valid(&bufref)) {
|
||||
// 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)
|
||||
&& !bufref_valid(&bufref)) {
|
||||
// Autocommands may delete the buffer.
|
||||
return;
|
||||
}
|
||||
buf->b_closing = false;
|
||||
|
||||
@@ -603,7 +645,8 @@ void buf_freeall(buf_T *buf, int flags)
|
||||
static void free_buffer(buf_T *buf)
|
||||
{
|
||||
handle_unregister_buffer(buf);
|
||||
free_buffer_stuff(buf, TRUE);
|
||||
buf_free_count++;
|
||||
free_buffer_stuff(buf, true);
|
||||
unref_var_dict(buf->b_vars);
|
||||
aubuflocal_remove(buf);
|
||||
buf_hashtab_remove(buf);
|
||||
@@ -678,8 +721,9 @@ static void clear_wininfo(buf_T *buf)
|
||||
void goto_buffer(exarg_T *eap, int start, int dir, int count)
|
||||
{
|
||||
(void)do_buffer(*eap->cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO,
|
||||
start, dir, count, eap->forceit);
|
||||
buf_T *old_curbuf = curbuf;
|
||||
start, dir, count, eap->forceit);
|
||||
bufref_T old_curbuf;
|
||||
set_bufref(&old_curbuf, curbuf);
|
||||
swap_exists_action = SEA_DIALOG;
|
||||
|
||||
if (swap_exists_action == SEA_QUIT && *eap->cmd == 's') {
|
||||
@@ -698,18 +742,20 @@ void goto_buffer(exarg_T *eap, int start, int dir, int count)
|
||||
* new aborting error, interrupt, or uncaught exception. */
|
||||
leave_cleanup(&cs);
|
||||
} else {
|
||||
handle_swap_exists(old_curbuf);
|
||||
handle_swap_exists(&old_curbuf);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle the situation of swap_exists_action being set.
|
||||
* It is allowed for "old_curbuf" to be NULL or invalid.
|
||||
*/
|
||||
void handle_swap_exists(buf_T *old_curbuf)
|
||||
/// Handle the situation of swap_exists_action being set.
|
||||
///
|
||||
/// It is allowed for "old_curbuf" to be NULL or invalid.
|
||||
///
|
||||
/// @param old_curbuf The buffer to check for.
|
||||
void handle_swap_exists(bufref_T *old_curbuf)
|
||||
{
|
||||
cleanup_T cs;
|
||||
long old_tw = curbuf->b_p_tw;
|
||||
buf_T *buf;
|
||||
|
||||
if (swap_exists_action == SEA_QUIT) {
|
||||
/* Reset the error/interrupt/exception state here so that
|
||||
@@ -722,13 +768,18 @@ void handle_swap_exists(buf_T *old_curbuf)
|
||||
swap_exists_action = SEA_NONE; // don't want it again
|
||||
swap_exists_did_quit = true;
|
||||
close_buffer(curwin, curbuf, DOBUF_UNLOAD, false);
|
||||
if (!buf_valid(old_curbuf) || old_curbuf == curbuf) {
|
||||
old_curbuf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED);
|
||||
if (old_curbuf == NULL
|
||||
|| !bufref_valid(old_curbuf)
|
||||
|| old_curbuf->br_buf == curbuf) {
|
||||
buf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED);
|
||||
} else {
|
||||
buf = old_curbuf->br_buf;
|
||||
}
|
||||
if (old_curbuf != NULL) {
|
||||
enter_buffer(old_curbuf);
|
||||
if (old_tw != curbuf->b_p_tw)
|
||||
if (buf != NULL) {
|
||||
enter_buffer(buf);
|
||||
if (old_tw != curbuf->b_p_tw) {
|
||||
check_colorcolumn(curwin);
|
||||
}
|
||||
}
|
||||
/* If "old_curbuf" is NULL we are in big trouble here... */
|
||||
|
||||
@@ -879,6 +930,9 @@ static int empty_curbuf(int close_others, int forceit, int action)
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
bufref_T bufref;
|
||||
set_bufref(&bufref, buf);
|
||||
|
||||
if (close_others) {
|
||||
/* Close any other windows on this buffer, then make it empty. */
|
||||
close_windows(buf, TRUE);
|
||||
@@ -888,15 +942,17 @@ static int empty_curbuf(int close_others, int forceit, int action)
|
||||
retval = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE,
|
||||
forceit ? ECMD_FORCEIT : 0, curwin);
|
||||
|
||||
/*
|
||||
* do_ecmd() may create a new buffer, then we have to delete
|
||||
* the old one. But do_ecmd() may have done that already, check
|
||||
* if the buffer still exists.
|
||||
*/
|
||||
if (buf != curbuf && buf_valid(buf) && buf->b_nwindows == 0)
|
||||
close_buffer(NULL, buf, action, FALSE);
|
||||
if (!close_others)
|
||||
need_fileinfo = FALSE;
|
||||
// do_ecmd() may create a new buffer, then we have to delete
|
||||
// the old one. But do_ecmd() may have done that already, check
|
||||
// if the buffer still exists.
|
||||
if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows == 0) {
|
||||
close_buffer(NULL, buf, action, false);
|
||||
}
|
||||
|
||||
if (!close_others) {
|
||||
need_fileinfo = false;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
/*
|
||||
@@ -998,6 +1054,8 @@ do_buffer (
|
||||
*/
|
||||
if (unload) {
|
||||
int forward;
|
||||
bufref_T bufref;
|
||||
set_bufref(&bufref, buf);
|
||||
|
||||
/* When unloading or deleting a buffer that's already unloaded and
|
||||
* unlisted: fail silently. */
|
||||
@@ -1006,15 +1064,16 @@ do_buffer (
|
||||
|
||||
if (!forceit && (buf->terminal || bufIsChanged(buf))) {
|
||||
if ((p_confirm || cmdmod.confirm) && p_write && !buf->terminal) {
|
||||
dialog_changed(buf, FALSE);
|
||||
if (!buf_valid(buf))
|
||||
/* Autocommand deleted buffer, oops! It's not changed
|
||||
* now. */
|
||||
dialog_changed(buf, false);
|
||||
if (!bufref_valid(&bufref)) {
|
||||
// Autocommand deleted buffer, oops! It's not changed now.
|
||||
return FAIL;
|
||||
/* If it's still changed fail silently, the dialog already
|
||||
* mentioned why it fails. */
|
||||
if (bufIsChanged(buf))
|
||||
}
|
||||
// If it's still changed fail silently, the dialog already
|
||||
// mentioned why it fails.
|
||||
if (bufIsChanged(buf)) {
|
||||
return FAIL;
|
||||
}
|
||||
} else {
|
||||
if (buf->terminal) {
|
||||
EMSG2(_("E89: %s will be killed(add ! to override)"),
|
||||
@@ -1058,27 +1117,26 @@ do_buffer (
|
||||
* If the buffer to be deleted is not the current one, delete it here.
|
||||
*/
|
||||
if (buf != curbuf) {
|
||||
close_windows(buf, FALSE);
|
||||
if (buf != curbuf && buf_valid(buf) && buf->b_nwindows <= 0)
|
||||
close_buffer(NULL, buf, action, FALSE);
|
||||
close_windows(buf, false);
|
||||
if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows <= 0) {
|
||||
close_buffer(NULL, buf, action, false);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deleting the current buffer: Need to find another buffer to go to.
|
||||
* There should be another, otherwise it would have been handled
|
||||
* above. However, autocommands may have deleted all buffers.
|
||||
* First use au_new_curbuf, if it is valid.
|
||||
* Then prefer the buffer we most recently visited.
|
||||
* Else try to find one that is loaded, after the current buffer,
|
||||
* then before the current buffer.
|
||||
* Finally use any buffer.
|
||||
*/
|
||||
buf = NULL; /* selected buffer */
|
||||
bp = NULL; /* used when no loaded buffer found */
|
||||
if (au_new_curbuf != NULL && buf_valid(au_new_curbuf))
|
||||
buf = au_new_curbuf;
|
||||
else if (curwin->w_jumplistlen > 0) {
|
||||
// Deleting the current buffer: Need to find another buffer to go to.
|
||||
// There should be another, otherwise it would have been handled
|
||||
// above. However, autocommands may have deleted all buffers.
|
||||
// First use au_new_curbuf.br_buf, if it is valid.
|
||||
// Then prefer the buffer we most recently visited.
|
||||
// Else try to find one that is loaded, after the current buffer,
|
||||
// then before the current buffer.
|
||||
// Finally use any buffer.
|
||||
buf = NULL; // Selected buffer.
|
||||
bp = NULL; // Used when no loaded buffer found.
|
||||
if (au_new_curbuf.br_buf != NULL && bufref_valid(&au_new_curbuf)) {
|
||||
buf = au_new_curbuf.br_buf;
|
||||
} else if (curwin->w_jumplistlen > 0) {
|
||||
int jumpidx;
|
||||
|
||||
jumpidx = curwin->w_jumplistidx - 1;
|
||||
@@ -1183,10 +1241,13 @@ do_buffer (
|
||||
*/
|
||||
if (action == DOBUF_GOTO && !can_abandon(curbuf, forceit)) {
|
||||
if ((p_confirm || cmdmod.confirm) && p_write) {
|
||||
dialog_changed(curbuf, FALSE);
|
||||
if (!buf_valid(buf))
|
||||
/* Autocommand deleted buffer, oops! */
|
||||
bufref_T bufref;
|
||||
set_bufref(&bufref, buf);
|
||||
dialog_changed(curbuf, false);
|
||||
if (!bufref_valid(&bufref)) {
|
||||
// Autocommand deleted buffer, oops!
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
if (bufIsChanged(curbuf)) {
|
||||
EMSG(_(e_nowrtmsg));
|
||||
@@ -1234,14 +1295,18 @@ void set_curbuf(buf_T *buf, int action)
|
||||
|
||||
/* close_windows() or apply_autocmds() may change curbuf */
|
||||
prevbuf = curbuf;
|
||||
bufref_T bufref;
|
||||
set_bufref(&bufref, prevbuf);
|
||||
|
||||
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)
|
||||
|| (bufref_valid(&bufref) && !aborting())) {
|
||||
if (prevbuf == curwin->w_buffer) {
|
||||
reset_synblock(curwin);
|
||||
if (unload)
|
||||
close_windows(prevbuf, FALSE);
|
||||
if (buf_valid(prevbuf) && !aborting()) {
|
||||
}
|
||||
if (unload) {
|
||||
close_windows(prevbuf, false);
|
||||
}
|
||||
if (bufref_valid(&bufref) && !aborting()) {
|
||||
win_T *previouswin = curwin;
|
||||
if (prevbuf == curbuf)
|
||||
u_sync(FALSE);
|
||||
@@ -1378,6 +1443,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 +1475,20 @@ 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;
|
||||
buf->b_p_bl = true;
|
||||
bufref_T bufref;
|
||||
set_bufref(&bufref, buf);
|
||||
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)
|
||||
&& !bufref_valid(&bufref)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -1551,18 +1622,21 @@ 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)) {
|
||||
bufref_T bufref;
|
||||
set_bufref(&bufref, buf);
|
||||
if (apply_autocmds(EVENT_BUFNEW, NULL, NULL, false, buf)
|
||||
&& !bufref_valid(&bufref)) {
|
||||
return NULL;
|
||||
}
|
||||
if (flags & BLN_LISTED) {
|
||||
apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
|
||||
if (!buf_valid(buf)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (aborting()) /* autocmds may abort script processing */
|
||||
if ((flags & BLN_LISTED)
|
||||
&& apply_autocmds(EVENT_BUFADD, NULL, NULL, false, buf)
|
||||
&& !bufref_valid(&bufref)) {
|
||||
return NULL;
|
||||
}
|
||||
if (aborting()) {
|
||||
// Autocmds may abort script processing.
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
@@ -1785,7 +1859,8 @@ buf_T *buflist_findname(char_u *ffname)
|
||||
static buf_T *buflist_findname_file_id(char_u *ffname, FileID *file_id,
|
||||
bool file_id_valid)
|
||||
{
|
||||
FOR_ALL_BUFFERS(buf) {
|
||||
// Start at the last buffer, expect to find a match sooner.
|
||||
FOR_ALL_BUFFERS_BACKWARDS(buf) {
|
||||
if ((buf->b_flags & BF_DUMMY) == 0
|
||||
&& !otherfile_buf(buf, ffname, file_id, file_id_valid)) {
|
||||
return buf;
|
||||
@@ -1859,7 +1934,7 @@ int buflist_findpat(
|
||||
return -1;
|
||||
}
|
||||
|
||||
FOR_ALL_BUFFERS(buf) {
|
||||
FOR_ALL_BUFFERS_BACKWARDS(buf) {
|
||||
if (buf->b_p_bl == find_listed
|
||||
&& (!diffmode || diff_mode_buf(buf))
|
||||
&& buflist_match(®match, buf, false) != NULL) {
|
||||
@@ -4223,12 +4298,13 @@ do_arg_all (
|
||||
|| !bufIsChanged(buf)) {
|
||||
/* If the buffer was changed, and we would like to hide it,
|
||||
* try autowriting. */
|
||||
if (!P_HID(buf) && buf->b_nwindows <= 1
|
||||
&& bufIsChanged(buf)) {
|
||||
(void)autowrite(buf, FALSE);
|
||||
/* check if autocommands removed the window */
|
||||
if (!win_valid(wp) || !buf_valid(buf)) {
|
||||
wpnext = firstwin; /* start all over... */
|
||||
if (!P_HID(buf) && buf->b_nwindows <= 1 && bufIsChanged(buf)) {
|
||||
bufref_T bufref;
|
||||
set_bufref(&bufref, buf);
|
||||
(void)autowrite(buf, false);
|
||||
// Check if autocommands removed the window.
|
||||
if (!win_valid(wp) || !bufref_valid(&bufref)) {
|
||||
wpnext = firstwin; // Start all over...
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -4442,7 +4518,9 @@ void ex_buffer_all(exarg_T *eap)
|
||||
}
|
||||
|
||||
if (wp == NULL && split_ret == OK) {
|
||||
/* Split the window and put the buffer in it */
|
||||
bufref_T bufref;
|
||||
set_bufref(&bufref, buf);
|
||||
// Split the window and put the buffer in it.
|
||||
p_ea_save = p_ea;
|
||||
p_ea = true; /* use space from all windows */
|
||||
split_ret = win_split(0, WSP_ROOM | WSP_BELOW);
|
||||
@@ -4454,7 +4532,8 @@ void ex_buffer_all(exarg_T *eap)
|
||||
/* Open the buffer in this window. */
|
||||
swap_exists_action = SEA_DIALOG;
|
||||
set_curbuf(buf, DOBUF_GOTO);
|
||||
if (!buf_valid(buf)) { /* autocommands deleted the buffer!!! */
|
||||
if (!bufref_valid(&bufref)) {
|
||||
// Autocommands deleted the buffer.
|
||||
swap_exists_action = SEA_NONE;
|
||||
break;
|
||||
}
|
||||
|
Reference in New Issue
Block a user