aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/buffer.c28
-rw-r--r--src/nvim/ex_cmds.c83
-rw-r--r--src/nvim/globals.h6
-rw-r--r--src/nvim/version.c2
4 files changed, 66 insertions, 53 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 3b18bf5366..81dceacd37 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -1114,21 +1114,19 @@ do_buffer (
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;
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index e6e85a3f6c..163df5dc05 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -1904,11 +1904,15 @@ void do_wqall(exarg_T *eap)
FALSE) == FAIL) {
++error;
} else {
- if (buf_write_all(buf, eap->forceit) == FAIL)
- ++error;
- /* an autocommand may have deleted the buffer */
- if (!buf_valid(buf))
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+ if (buf_write_all(buf, eap->forceit) == FAIL) {
+ error++;
+ }
+ // An autocommand may have deleted the buffer.
+ if (!bufref_valid(&bufref)) {
buf = firstbuf;
+ }
}
eap->forceit = save_forceit; /* check_overwrite() may set it */
}
@@ -2081,6 +2085,7 @@ int do_ecmd(
char_u *new_name = NULL;
int did_set_swapcommand = FALSE;
buf_T *buf;
+ bufref_T bufref;
buf_T *old_curbuf = curbuf;
char_u *free_fname = NULL;
int retval = FAIL;
@@ -2213,19 +2218,23 @@ int do_ecmd(
}
if (buf == NULL)
goto theend;
- if (buf->b_ml.ml_mfp == NULL) { /* no memfile yet */
- oldbuf = FALSE;
- } else { /* existing memfile */
- oldbuf = TRUE;
- (void)buf_check_timestamp(buf, FALSE);
- /* Check if autocommands made buffer invalid or changed the current
- * buffer. */
- if (!buf_valid(buf)
- || curbuf != old_curbuf
- )
+ if (buf->b_ml.ml_mfp == NULL) {
+ // No memfile yet.
+ oldbuf = false;
+ } else {
+ // Existing memfile.
+ oldbuf = true;
+ set_bufref(&bufref, buf);
+ (void)buf_check_timestamp(buf, false);
+ // Check if autocommands made buffer invalid or changed the current
+ // buffer.
+ if (!bufref_valid(&bufref) || curbuf != old_curbuf) {
goto theend;
- if (aborting()) /* autocmds may abort script processing */
+ }
+ if (aborting()) {
+ // Autocmds may abort script processing.
goto theend;
+ }
}
/* May jump to last used line number for a loaded buffer or when asked
@@ -2253,12 +2262,14 @@ int do_ecmd(
* - If we ended up in the new buffer already, need to skip a few
* things, set auto_buf.
*/
- if (buf->b_fname != NULL)
+ if (buf->b_fname != NULL) {
new_name = vim_strsave(buf->b_fname);
- au_new_curbuf = buf;
- apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
- if (!buf_valid(buf)) { /* new buffer has been deleted */
- delbuf_msg(new_name); /* frees new_name */
+ }
+ set_bufref(&au_new_curbuf, buf);
+ apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf);
+ if (!bufref_valid(&au_new_curbuf)) {
+ // New buffer has been deleted.
+ delbuf_msg(new_name); // Frees new_name.
goto theend;
}
if (aborting()) { /* autocmds may abort script processing */
@@ -2290,9 +2301,10 @@ int do_ecmd(
xfree(new_name);
goto theend;
}
- /* Be careful again, like above. */
- if (!buf_valid(buf)) { /* new buffer has been deleted */
- delbuf_msg(new_name); /* frees new_name */
+ // Be careful again, like above.
+ if (!bufref_valid(&au_new_curbuf)) {
+ // New buffer has been deleted.
+ delbuf_msg(new_name); // Frees new_name.
goto theend;
}
if (buf == curbuf) { // already in new buffer
@@ -2325,7 +2337,7 @@ int do_ecmd(
}
xfree(new_name);
- au_new_curbuf = NULL;
+ au_new_curbuf.br_buf = NULL;
}
curwin->w_pcmark.lnum = 1;
@@ -2378,10 +2390,12 @@ int do_ecmd(
solcol = curwin->w_cursor.col;
}
buf = curbuf;
- if (buf->b_fname != NULL)
+ if (buf->b_fname != NULL) {
new_name = vim_strsave(buf->b_fname);
- else
+ } else {
new_name = NULL;
+ }
+ set_bufref(&bufref, buf);
if (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur) {
/* Save all the text, so that the reload can be undone.
* Sync first so that this is a separate undo-able action. */
@@ -2394,14 +2408,15 @@ int do_ecmd(
u_unchanged(curbuf);
buf_freeall(curbuf, BFA_KEEP_UNDO);
- /* tell readfile() not to clear or reload undo info */
+ // Tell readfile() not to clear or reload undo info.
readfile_flags = READ_KEEP_UNDO;
- } else
- buf_freeall(curbuf, 0); /* free all things for buffer */
- /* If autocommands deleted the buffer we were going to re-edit, give
- * up and jump to the end. */
- if (!buf_valid(buf)) {
- delbuf_msg(new_name); /* frees new_name */
+ } else {
+ buf_freeall(curbuf, 0); // Free all things for buffer.
+ }
+ // If autocommands deleted the buffer we were going to re-edit, give
+ // up and jump to the end.
+ if (!bufref_valid(&bufref)) {
+ delbuf_msg(new_name); // Frees new_name.
goto theend;
}
xfree(new_name);
@@ -2607,7 +2622,7 @@ static void delbuf_msg(char_u *name)
EMSG2(_("E143: Autocommands unexpectedly deleted new buffer %s"),
name == NULL ? (char_u *)"" : name);
xfree(name);
- au_new_curbuf = NULL;
+ au_new_curbuf.br_buf = NULL;
}
static int append_indent = 0; /* autoindent for first line */
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index baa85c01f8..0a47eaaef2 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -512,9 +512,9 @@ EXTERN int keep_filetype INIT(= FALSE); /* value for did_filetype when
starting to execute
autocommands */
-/* When deleting the current buffer, another one must be loaded. If we know
- * which one is preferred, au_new_curbuf is set to it */
-EXTERN buf_T *au_new_curbuf INIT(= NULL);
+// When deleting the current buffer, another one must be loaded.
+// If we know which one is preferred, au_new_curbuf is set to it.
+EXTERN bufref_T au_new_curbuf INIT(= { NULL, 0 });
// When deleting a buffer/window and autocmd_busy is TRUE, do not free the
// buffer/window. but link it in the list starting with
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 4afbb4f8f4..69860aa216 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -419,7 +419,7 @@ static int included_patches[] = {
// 2024,
// 2023,
// 2022,
- // 2021,
+ 2021,
// 2020 NA
2019,
2018,