aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/buffer.c50
-rw-r--r--src/nvim/buffer.h11
-rw-r--r--src/nvim/diff.c7
-rw-r--r--src/nvim/ex_cmds.c12
-rw-r--r--src/nvim/ex_cmds2.c32
-rw-r--r--src/nvim/ex_docmd.c9
-rw-r--r--src/nvim/ex_getln.c19
-rw-r--r--src/nvim/fileio.c70
-rw-r--r--src/nvim/fileio.h2
-rw-r--r--src/nvim/main.c9
-rw-r--r--src/nvim/memory.c8
-rw-r--r--src/nvim/quickfix.c22
-rw-r--r--src/nvim/spell.c8
-rw-r--r--src/nvim/window.c30
14 files changed, 171 insertions, 118 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 9204357fee..24aa4cdaac 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -94,7 +94,7 @@ open_buffer (
)
{
int retval = OK;
- buf_T *old_curbuf;
+ bufref_T old_curbuf;
long old_tw = curbuf->b_p_tw;
/*
@@ -136,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;
@@ -252,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);
@@ -719,8 +719,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') {
@@ -739,18 +740,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
@@ -763,13 +766,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... */
diff --git a/src/nvim/buffer.h b/src/nvim/buffer.h
index 1fe8692963..64f9daf0a8 100644
--- a/src/nvim/buffer.h
+++ b/src/nvim/buffer.h
@@ -57,21 +57,22 @@ enum bfa_values {
static inline void switch_to_win_for_buf(buf_T *buf,
win_T **save_curwinp,
tabpage_T **save_curtabp,
- buf_T **save_curbufp)
+ bufref_T *save_curbuf)
{
win_T *wp;
tabpage_T *tp;
if (!find_win_for_buf(buf, &wp, &tp)
- || switch_win(save_curwinp, save_curtabp, wp, tp, true) == FAIL)
- switch_buffer(save_curbufp, buf);
+ || switch_win(save_curwinp, save_curtabp, wp, tp, true) == FAIL) {
+ switch_buffer(save_curbuf, buf);
+ }
}
static inline void restore_win_for_buf(win_T *save_curwin,
tabpage_T *save_curtab,
- buf_T *save_curbuf)
+ bufref_T *save_curbuf)
{
- if (save_curbuf == NULL) {
+ if (save_curbuf->br_buf == NULL) {
restore_win(save_curwin, save_curtab, true);
} else {
restore_buffer(save_curbuf);
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index f7b96ba3e1..aafd50687e 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -1004,7 +1004,8 @@ theend:
void ex_diffsplit(exarg_T *eap)
{
win_T *old_curwin = curwin;
- buf_T *old_curbuf = curbuf;
+ bufref_T old_curbuf;
+ set_bufref(&old_curbuf, curbuf);
// don't use a new tab page, each tab page has its own diffs
cmdmod.tab = 0;
@@ -1022,10 +1023,10 @@ void ex_diffsplit(exarg_T *eap)
if (win_valid(old_curwin)) {
diff_win_options(old_curwin, true);
- if (buf_valid(old_curbuf)) {
+ if (bufref_valid(&old_curbuf)) {
// Move the cursor position to that of the old window.
curwin->w_cursor.lnum = diff_get_corresponding_line(
- old_curbuf,
+ old_curbuf.br_buf,
old_curwin->w_cursor.lnum,
curbuf,
curwin->w_cursor.lnum);
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 163df5dc05..3b7f3b7b97 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -2086,7 +2086,7 @@ int do_ecmd(
int did_set_swapcommand = FALSE;
buf_T *buf;
bufref_T bufref;
- buf_T *old_curbuf = curbuf;
+ bufref_T old_curbuf;
char_u *free_fname = NULL;
int retval = FAIL;
long n;
@@ -2103,6 +2103,8 @@ int do_ecmd(
if (eap != NULL)
command = eap->do_ecmd_cmd;
+ set_bufref(&old_curbuf, curbuf);
+
if (fnum != 0) {
if (fnum == curbuf->b_fnum) /* file is already being edited */
return OK; /* nothing to do */
@@ -2214,7 +2216,7 @@ int do_ecmd(
if (oldwin != NULL) {
oldwin = curwin;
}
- old_curbuf = curbuf;
+ set_bufref(&old_curbuf, curbuf);
}
if (buf == NULL)
goto theend;
@@ -2228,7 +2230,7 @@ int do_ecmd(
(void)buf_check_timestamp(buf, false);
// Check if autocommands made buffer invalid or changed the current
// buffer.
- if (!bufref_valid(&bufref) || curbuf != old_curbuf) {
+ if (!bufref_valid(&bufref) || curbuf != old_curbuf.br_buf) {
goto theend;
}
if (aborting()) {
@@ -2283,7 +2285,7 @@ int do_ecmd(
// Set the w_closing flag to avoid that autocommands close the window.
the_curwin->w_closing = true;
- if (curbuf == old_curbuf) {
+ if (curbuf == old_curbuf.br_buf) {
buf_copy_options(buf, BCO_ENTER);
}
@@ -2487,7 +2489,7 @@ int do_ecmd(
if (swap_exists_action == SEA_QUIT)
retval = FAIL;
- handle_swap_exists(old_curbuf);
+ handle_swap_exists(&old_curbuf);
} else {
/* Read the modelines, but only to set window-local options. Any
* buffer-local options have already been set and may have been
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 3b92b3734a..b4e57bc916 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -1181,6 +1181,7 @@ bool prof_def_func(void)
int autowrite(buf_T *buf, int forceit)
{
int r;
+ bufref_T bufref;
if (!(p_aw || p_awa) || !p_write
// never autowrite a "nofile" or "nowrite" buffer
@@ -1188,11 +1189,12 @@ int autowrite(buf_T *buf, int forceit)
|| (!forceit && buf->b_p_ro) || buf->b_ffname == NULL) {
return FAIL;
}
+ set_bufref(&bufref, buf);
r = buf_write_all(buf, forceit);
// Writing may succeed but the buffer still changed, e.g., when there is a
// conversion error. We do want to return FAIL then.
- if (buf_valid(buf) && bufIsChanged(buf)) {
+ if (bufref_valid(&bufref) && bufIsChanged(buf)) {
r = FAIL;
}
return r;
@@ -1207,9 +1209,11 @@ void autowrite_all(void)
FOR_ALL_BUFFERS(buf) {
if (bufIsChanged(buf) && !buf->b_p_ro) {
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
(void)buf_write_all(buf, false);
// an autocommand may have deleted the buffer
- if (!buf_valid(buf)) {
+ if (!bufref_valid(&bufref)) {
buf = firstbuf;
}
}
@@ -1221,6 +1225,8 @@ void autowrite_all(void)
bool check_changed(buf_T *buf, int flags)
{
int forceit = (flags & CCGD_FORCEIT);
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
if (!forceit
&& bufIsChanged(buf)
@@ -1236,12 +1242,12 @@ bool check_changed(buf_T *buf, int flags)
}
}
}
- if (!buf_valid(buf)) {
+ if (!bufref_valid(&bufref)) {
// Autocommand deleted buffer, oops! It's not changed now.
return false;
}
dialog_changed(buf, count > 1);
- if (!buf_valid(buf)) {
+ if (!bufref_valid(&bufref)) {
// Autocommand deleted buffer, oops! It's not changed now.
return false;
}
@@ -1300,9 +1306,10 @@ void dialog_changed(buf_T *buf, int checkall)
// Skip readonly buffers, these need to be confirmed
// individually.
FOR_ALL_BUFFERS(buf2) {
- if (bufIsChanged(buf2)
- && (buf2->b_ffname != NULL)
- && !buf2->b_p_ro) {
+ if (bufIsChanged(buf2) && (buf2->b_ffname != NULL) && !buf2->b_p_ro) {
+ bufref_T bufref;
+ set_bufref(&bufref, buf2);
+
if (buf2->b_fname != NULL
&& check_overwrite(&ea, buf2, buf2->b_fname,
buf2->b_ffname, false) == OK) {
@@ -1310,7 +1317,7 @@ void dialog_changed(buf_T *buf, int checkall)
(void)buf_write_all(buf2, false);
}
// an autocommand may have deleted the buffer
- if (!buf_valid(buf2)) {
+ if (!bufref_valid(&bufref)) {
buf2 = firstbuf;
}
}
@@ -1407,11 +1414,14 @@ bool check_changed_any(bool hidden, bool unload)
continue;
}
if ((!hidden || buf->b_nwindows == 0) && bufIsChanged(buf)) {
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+
// Try auto-writing the buffer. If this fails but the buffer no
// longer exists it's not changed, that's OK.
if (check_changed(buf, (p_awa ? CCGD_AW : 0)
| CCGD_MULTWIN
- | CCGD_ALLBUF) && buf_valid(buf)) {
+ | CCGD_ALLBUF) && bufref_valid(&bufref)) {
break; // didn't save - still changes
}
}
@@ -1447,9 +1457,11 @@ bool check_changed_any(bool hidden, bool unload)
if (buf != curbuf) {
FOR_ALL_TAB_WINDOWS(tp, wp) {
if (wp->w_buffer == buf) {
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
goto_tabpage_win(tp, wp);
// Paranoia: did autocmds wipe out the buffer with changes?
- if (!buf_valid(buf)) {
+ if (!bufref_valid(&bufref)) {
goto theend;
}
goto buf_found;
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 4070e9fe5b..c5625d7882 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -5914,10 +5914,13 @@ ex_win_close (
need_hide = (bufIsChanged(buf) && buf->b_nwindows <= 1);
if (need_hide && !P_HID(buf) && !forceit) {
if ((p_confirm || cmdmod.confirm) && p_write) {
- dialog_changed(buf, FALSE);
- if (buf_valid(buf) && bufIsChanged(buf))
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+ dialog_changed(buf, false);
+ if (bufref_valid(&bufref) && bufIsChanged(buf)) {
return;
- need_hide = FALSE;
+ }
+ need_hide = false;
} else {
EMSG(_(e_nowrtmsg));
return;
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index dba7a73814..2555b64dfd 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -5134,9 +5134,9 @@ int cmd_gchar(int offset)
static int ex_window(void)
{
struct cmdline_info save_ccline;
- buf_T *old_curbuf = curbuf;
+ bufref_T old_curbuf;
+ bufref_T bufref;
win_T *old_curwin = curwin;
- buf_T *bp;
win_T *wp;
int i;
linenr_T lnum;
@@ -5155,6 +5155,8 @@ static int ex_window(void)
return K_IGNORE;
}
+ set_bufref(&old_curbuf, curbuf);
+
/* Save current window sizes. */
win_size_save(&winsizes);
@@ -5269,7 +5271,7 @@ static int ex_window(void)
/* Safety check: The old window or buffer was deleted: It's a bug when
* this happens! */
- if (!win_valid(old_curwin) || !buf_valid(old_curbuf)) {
+ if (!win_valid(old_curwin) || !bufref_valid(&old_curbuf)) {
cmdwin_result = Ctrl_C;
EMSG(_("E199: Active window or buffer deleted"));
} else {
@@ -5320,14 +5322,15 @@ static int ex_window(void)
// Avoid command-line window first character being concealed
curwin->w_p_cole = 0;
wp = curwin;
- bp = curbuf;
+ set_bufref(&bufref, curbuf);
win_goto(old_curwin);
win_close(wp, TRUE);
- /* win_close() may have already wiped the buffer when 'bh' is
- * set to 'wipe' */
- if (buf_valid(bp))
- close_buffer(NULL, bp, DOBUF_WIPE, FALSE);
+ // win_close() may have already wiped the buffer when 'bh' is
+ // set to 'wipe'.
+ if (bufref_valid(&bufref)) {
+ close_buffer(NULL, bufref.br_buf, DOBUF_WIPE, false);
+ }
/* Restore window sizes. */
win_size_restore(&winsizes);
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index d433afab3e..7b726e9f1a 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -2402,6 +2402,7 @@ buf_write (
int did_cmd = FALSE;
int nofile_err = FALSE;
int empty_memline = (buf->b_ml.ml_mfp == NULL);
+ bufref_T bufref;
/*
* Apply PRE autocommands.
@@ -2417,8 +2418,9 @@ buf_write (
if (fname == buf->b_sfname)
buf_fname_s = TRUE;
- /* set curwin/curbuf to buf and save a few things */
+ // Set curwin/curbuf to buf and save a few things.
aucmd_prepbuf(&aco, buf);
+ set_bufref(&bufref, buf);
if (append) {
if (!(did_cmd = apply_autocmds_exarg(EVENT_FILEAPPENDCMD,
@@ -2466,14 +2468,13 @@ buf_write (
/* restore curwin/curbuf and a few other things */
aucmd_restbuf(&aco);
- /*
- * In three situations we return here and don't write the file:
- * 1. the autocommands deleted or unloaded the buffer.
- * 2. The autocommands abort script processing.
- * 3. If one of the "Cmd" autocommands was executed.
- */
- if (!buf_valid(buf))
+ // In three situations we return here and don't write the file:
+ // 1. the autocommands deleted or unloaded the buffer.
+ // 2. The autocommands abort script processing.
+ // 3. If one of the "Cmd" autocommands was executed.
+ if (!bufref_valid(&bufref)) {
buf = NULL;
+ }
if (buf == NULL || (buf->b_ml.ml_mfp == NULL && !empty_memline)
|| did_cmd || nofile_err
|| aborting()
@@ -4760,12 +4761,14 @@ check_timestamps (
for (buf = firstbuf; buf != NULL; ) {
/* Only check buffers in a window. */
if (buf->b_nwindows > 0) {
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
n = buf_check_timestamp(buf, focus);
- if (didit < n)
+ if (didit < n) {
didit = n;
- if (n > 0 && !buf_valid(buf)) {
- /* Autocommands have removed the buffer, start at the
- * first one again. */
+ }
+ if (n > 0 && !bufref_valid(&bufref)) {
+ // Autocommands have removed the buffer, start at the first one again.
buf = firstbuf;
continue;
}
@@ -4850,6 +4853,9 @@ buf_check_timestamp (
char_u *s;
char *reason;
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+
// If its a terminal, there is no file name, the buffer is not loaded,
// 'buftype' is set, we are in the middle of a save or being called
// recursively: ignore this buffer.
@@ -4919,8 +4925,9 @@ buf_check_timestamp (
allbuf_lock--;
busy = false;
if (n) {
- if (!buf_valid(buf))
+ if (!bufref_valid(&bufref)) {
EMSG(_("E246: FileChangedShell autocommand deleted buffer"));
+ }
s = get_vim_var_str(VV_FCS_CHOICE);
if (STRCMP(s, "reload") == 0 && *reason != 'd')
reload = TRUE;
@@ -5037,11 +5044,11 @@ buf_check_timestamp (
}
}
- /* Trigger FileChangedShell when the file was changed in any way. */
- if (buf_valid(buf) && retval != 0)
- (void)apply_autocmds(EVENT_FILECHANGEDSHELLPOST,
- buf->b_fname, buf->b_fname, FALSE, buf);
-
+ // Trigger FileChangedShell when the file was changed in any way.
+ if (bufref_valid(&bufref) && retval != 0) {
+ (void)apply_autocmds(EVENT_FILECHANGEDSHELLPOST, buf->b_fname, buf->b_fname,
+ false, buf);
+ }
return retval;
}
@@ -5058,6 +5065,7 @@ void buf_reload(buf_T *buf, int orig_mode)
linenr_T old_topline;
int old_ro = buf->b_p_ro;
buf_T *savebuf;
+ bufref_T bufref;
int saved = OK;
aco_save_T aco;
int flags = READ_NEW;
@@ -5093,6 +5101,7 @@ void buf_reload(buf_T *buf, int orig_mode)
} else {
// Allocate a buffer without putting it in the buffer list.
savebuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY);
+ set_bufref(&bufref, savebuf);
if (savebuf != NULL && buf == curbuf) {
/* Open the memline. */
curbuf = savebuf;
@@ -5117,7 +5126,7 @@ void buf_reload(buf_T *buf, int orig_mode)
if (!aborting()) {
EMSG2(_("E321: Could not reload \"%s\""), buf->b_fname);
}
- if (savebuf != NULL && buf_valid(savebuf) && buf == curbuf) {
+ if (savebuf != NULL && bufref_valid(&bufref) && buf == curbuf) {
/* Put the text back from the save buffer. First
* delete any lines that readfile() added. */
while (!bufempty())
@@ -5139,8 +5148,9 @@ void buf_reload(buf_T *buf, int orig_mode)
}
xfree(ea.cmd);
- if (savebuf != NULL && buf_valid(savebuf))
- wipe_buffer(savebuf, FALSE);
+ if (savebuf != NULL && bufref_valid(&bufref)) {
+ wipe_buffer(savebuf, false);
+ }
/* Invalidate diff info if necessary. */
diff_invalidate(curbuf);
@@ -6288,6 +6298,7 @@ void ex_doautoall(exarg_T *eap)
aco_save_T aco;
char_u *arg = eap->arg;
int call_do_modelines = check_nomodeline(&arg);
+ bufref_T bufref;
/*
* This is a bit tricky: For some commands curwin->w_buffer needs to be
@@ -6300,8 +6311,9 @@ void ex_doautoall(exarg_T *eap)
if (buf->b_ml.ml_mfp == NULL) {
continue;
}
- /* find a window for this buffer and save some values */
+ // Find a window for this buffer and save some values.
aucmd_prepbuf(&aco, buf);
+ set_bufref(&bufref, buf);
bool did_aucmd;
// execute the autocommands for this buffer
@@ -6318,7 +6330,7 @@ void ex_doautoall(exarg_T *eap)
aucmd_restbuf(&aco);
/* stop if there is some error or buffer was deleted */
- if (retval == FAIL || !buf_valid(buf))
+ if (retval == FAIL || !bufref_valid(&bufref))
break;
}
@@ -6426,7 +6438,7 @@ aucmd_prepbuf (
}
curbuf = buf;
aco->new_curwin = curwin;
- aco->new_curbuf = curbuf;
+ set_bufref(&aco->new_curbuf, curbuf);
}
/// Cleanup after executing autocommands for a (hidden) buffer.
@@ -6489,14 +6501,14 @@ win_found:
// Restore the buffer which was previously edited by curwin, if it was
// changed, we are still the same window and the buffer is valid.
if (curwin == aco->new_curwin
- && curbuf != aco->new_curbuf
- && buf_valid(aco->new_curbuf)
- && aco->new_curbuf->b_ml.ml_mfp != NULL) {
+ && curbuf != aco->new_curbuf.br_buf
+ && bufref_valid(&aco->new_curbuf)
+ && aco->new_curbuf.br_buf->b_ml.ml_mfp != NULL) {
if (curwin->w_s == &curbuf->b_s) {
- curwin->w_s = &aco->new_curbuf->b_s;
+ curwin->w_s = &aco->new_curbuf.br_buf->b_s;
}
curbuf->b_nwindows--;
- curbuf = aco->new_curbuf;
+ curbuf = aco->new_curbuf.br_buf;
curwin->w_buffer = curbuf;
curbuf->b_nwindows++;
}
diff --git a/src/nvim/fileio.h b/src/nvim/fileio.h
index ceb101167d..d099249961 100644
--- a/src/nvim/fileio.h
+++ b/src/nvim/fileio.h
@@ -23,7 +23,7 @@ typedef struct {
int use_aucmd_win; /* using aucmd_win */
win_T *save_curwin; /* saved curwin */
win_T *new_curwin; /* new curwin */
- buf_T *new_curbuf; /* new curbuf */
+ bufref_T new_curbuf; /* new curbuf */
char_u *globaldir; /* saved value of globaldir */
} aco_save_T;
diff --git a/src/nvim/main.c b/src/nvim/main.c
index c7a60d07c1..d89ab7a2da 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -590,10 +590,13 @@ void getout(int exitval)
/* Trigger BufUnload for buffers that are loaded */
FOR_ALL_BUFFERS(buf) {
if (buf->b_ml.ml_mfp != NULL) {
- apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname,
- FALSE, buf);
- if (!buf_valid(buf)) /* autocmd may delete the buffer */
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+ apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, false, buf);
+ if (!bufref_valid(&bufref)) {
+ // Autocmd deleted the buffer.
break;
+ }
}
}
apply_autocmds(EVENT_VIMLEAVEPRE, NULL, NULL, FALSE, curbuf);
diff --git a/src/nvim/memory.c b/src/nvim/memory.c
index 25fa2f150e..51e0dd926e 100644
--- a/src/nvim/memory.c
+++ b/src/nvim/memory.c
@@ -629,12 +629,12 @@ void free_all_mem(void)
* were freed already. */
p_acd = false;
for (buf = firstbuf; buf != NULL; ) {
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
nextbuf = buf->b_next;
close_buffer(NULL, buf, DOBUF_WIPE, false);
- if (buf_valid(buf))
- buf = nextbuf; /* didn't work, try next one */
- else
- buf = firstbuf;
+ // Didn't work, try next one.
+ buf = bufref_valid(&bufref) ? nextbuf : firstbuf;
}
free_cmdline_buf();
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 45982cc68a..259b1b864c 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -3734,7 +3734,8 @@ load_dummy_buffer (
)
{
buf_T *newbuf;
- buf_T *newbuf_to_wipe = NULL;
+ bufref_T newbufref;
+ bufref_T newbuf_to_wipe;
int failed = TRUE;
aco_save_T aco;
@@ -3743,6 +3744,7 @@ load_dummy_buffer (
if (newbuf == NULL) {
return NULL;
}
+ set_bufref(&newbufref, newbuf);
/* Init the options. */
buf_copy_options(newbuf, BCO_ENTER | BCO_NOHELP);
@@ -3762,6 +3764,7 @@ load_dummy_buffer (
* work. */
curbuf->b_flags &= ~BF_DUMMY;
+ newbuf_to_wipe.br_buf = NULL;
if (readfile(fname, NULL,
(linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM,
NULL, READ_NEW | READ_DUMMY) == OK
@@ -3769,19 +3772,19 @@ load_dummy_buffer (
&& !(curbuf->b_flags & BF_NEW)) {
failed = FALSE;
if (curbuf != newbuf) {
- /* Bloody autocommands changed the buffer! Can happen when
- * using netrw and editing a remote file. Use the current
- * buffer instead, delete the dummy one after restoring the
- * window stuff. */
- newbuf_to_wipe = newbuf;
+ // Bloody autocommands changed the buffer! Can happen when
+ // using netrw and editing a remote file. Use the current
+ // buffer instead, delete the dummy one after restoring the
+ // window stuff.
+ set_bufref(&newbuf_to_wipe, newbuf);
newbuf = curbuf;
}
}
// Restore curwin/curbuf and a few other things.
aucmd_restbuf(&aco);
- if (newbuf_to_wipe != NULL && buf_valid(newbuf_to_wipe)) {
- wipe_buffer(newbuf_to_wipe, false);
+ if (newbuf_to_wipe.br_buf != NULL && bufref_valid(&newbuf_to_wipe)) {
+ wipe_buffer(newbuf_to_wipe.br_buf, false);
}
// Add back the "dummy" flag, otherwise buflist_findname_file_id()
@@ -3797,8 +3800,9 @@ load_dummy_buffer (
os_dirname(resulting_dir, MAXPATHL);
restore_start_dir(dirname_start);
- if (!buf_valid(newbuf))
+ if (!bufref_valid(&newbufref)) {
return NULL;
+ }
if (failed) {
wipe_dummy_buffer(newbuf, dirname_start);
return NULL;
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 7e0bbd6ad1..1ace39344d 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -3746,6 +3746,9 @@ char_u *did_set_spelllang(win_T *wp)
char_u *ret_msg = NULL;
char_u *spl_copy;
+ bufref_T bufref;
+ set_bufref(&bufref, wp->w_buffer);
+
// We don't want to do this recursively. May happen when a language is
// not available and the SpellFileMissing autocommand opens a new buffer
// in which 'spell' is set.
@@ -3824,7 +3827,7 @@ char_u *did_set_spelllang(win_T *wp)
spell_load_lang(lang);
// SpellFileMissing autocommands may do anything, including
// destroying the buffer we are using...
- if (!buf_valid(wp->w_buffer)) {
+ if (!bufref_valid(&bufref)) {
ret_msg =
(char_u *)"E797: SpellFileMissing autocommand deleted buffer";
goto theend;
@@ -13037,8 +13040,9 @@ void ex_spelldump(exarg_T *eap)
set_option_value((char_u*)"spl", dummy, spl, OPT_LOCAL);
xfree(spl);
- if (!bufempty() || !buf_valid(curbuf))
+ if (!bufempty()) {
return;
+ }
spell_dump_compl(NULL, 0, NULL, eap->forceit ? DUMPFLAG_COUNT : 0);
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 801969a594..1f52af2f38 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -1945,6 +1945,8 @@ int win_close(win_T *win, int free_buf)
* Close the link to the buffer.
*/
if (win->w_buffer != NULL) {
+ bufref_T bufref;
+ set_bufref(&bufref, curbuf);
win->w_closing = true;
close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, true);
if (win_valid_any_tab(win)) {
@@ -1953,7 +1955,7 @@ int win_close(win_T *win, int free_buf)
// Make sure curbuf is valid. It can become invalid if 'bufhidden' is
// "wipe".
- if (!buf_valid(curbuf)) {
+ if (!bufref_valid(&bufref)) {
curbuf = firstbuf;
}
}
@@ -5401,31 +5403,29 @@ void restore_win(win_T *save_curwin, tabpage_T *save_curtab, int no_display)
unblock_autocmds();
}
-/*
- * Make "buf" the current buffer. restore_buffer() MUST be called to undo.
- * No autocommands will be executed. Use aucmd_prepbuf() if there are any.
- */
-void switch_buffer(buf_T **save_curbuf, buf_T *buf)
+/// Make "buf" the current buffer.
+///
+/// restore_buffer() MUST be called to undo.
+/// No autocommands will be executed. Use aucmd_prepbuf() if there are any.
+void switch_buffer(bufref_T *save_curbuf, buf_T *buf)
{
block_autocmds();
- *save_curbuf = curbuf;
+ set_bufref(save_curbuf, curbuf);
--curbuf->b_nwindows;
curbuf = buf;
curwin->w_buffer = buf;
++curbuf->b_nwindows;
}
-/*
- * Restore the current buffer after using switch_buffer().
- */
-void restore_buffer(buf_T *save_curbuf)
+/// Restore the current buffer after using switch_buffer().
+void restore_buffer(bufref_T *save_curbuf)
{
unblock_autocmds();
- /* Check for valid buffer, just in case. */
- if (buf_valid(save_curbuf)) {
+ // Check for valid buffer, just in case.
+ if (bufref_valid(save_curbuf)) {
--curbuf->b_nwindows;
- curwin->w_buffer = save_curbuf;
- curbuf = save_curbuf;
+ curwin->w_buffer = save_curbuf->br_buf;
+ curbuf = save_curbuf->br_buf;
++curbuf->b_nwindows;
}
}