vim-patch:7.4.2021

Problem:  Still too many buf_valid() calls.
Solution: Make au_new_curbuf a bufref.  Use bufref_valid() in more places.

19ff9bf454
This commit is contained in:
Marco Hinz 2017-01-09 03:39:50 +01:00 committed by James McCoy
parent e177226d51
commit 1836f3cb9b
No known key found for this signature in database
GPG Key ID: DFE691AE331BA3DB
4 changed files with 66 additions and 53 deletions

View File

@ -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;

View File

@ -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 */

View File

@ -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

View File

@ -419,7 +419,7 @@ static int included_patches[] = {
// 2024,
// 2023,
// 2022,
// 2021,
2021,
// 2020 NA
2019,
2018,