mirror of
https://github.com/neovim/neovim.git
synced 2025-09-18 09:18:19 +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:
@@ -290,7 +290,6 @@ void nvim_buf_set_lines(uint64_t channel_id,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf_T *save_curbuf = NULL;
|
|
||||||
win_T *save_curwin = NULL;
|
win_T *save_curwin = NULL;
|
||||||
tabpage_T *save_curtab = NULL;
|
tabpage_T *save_curtab = NULL;
|
||||||
size_t new_len = replacement.size;
|
size_t new_len = replacement.size;
|
||||||
@@ -322,6 +321,7 @@ void nvim_buf_set_lines(uint64_t channel_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
try_start();
|
try_start();
|
||||||
|
bufref_T save_curbuf = { NULL, 0 };
|
||||||
switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
|
switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
|
||||||
|
|
||||||
if (u_save((linenr_T)(start - 1), (linenr_T)end) == FAIL) {
|
if (u_save((linenr_T)(start - 1), (linenr_T)end) == FAIL) {
|
||||||
@@ -389,7 +389,7 @@ void nvim_buf_set_lines(uint64_t channel_id,
|
|||||||
// changed range, and move any in the remainder of the buffer.
|
// changed range, and move any in the remainder of the buffer.
|
||||||
// Only adjust marks if we managed to switch to a window that holds
|
// Only adjust marks if we managed to switch to a window that holds
|
||||||
// the buffer, otherwise line numbers will be invalid.
|
// the buffer, otherwise line numbers will be invalid.
|
||||||
if (save_curbuf == NULL) {
|
if (save_curbuf.br_buf == NULL) {
|
||||||
mark_adjust((linenr_T)start, (linenr_T)(end - 1), MAXLNUM, extra);
|
mark_adjust((linenr_T)start, (linenr_T)(end - 1), MAXLNUM, extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,7 +405,7 @@ end:
|
|||||||
}
|
}
|
||||||
|
|
||||||
xfree(lines);
|
xfree(lines);
|
||||||
restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
|
restore_win_for_buf(save_curwin, save_curtab, &save_curbuf);
|
||||||
try_end(err);
|
try_end(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -651,13 +651,13 @@ ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pos_T *posp;
|
pos_T *posp;
|
||||||
buf_T *savebuf;
|
|
||||||
char mark = *name.data;
|
char mark = *name.data;
|
||||||
|
|
||||||
try_start();
|
try_start();
|
||||||
switch_buffer(&savebuf, buf);
|
bufref_T save_buf;
|
||||||
|
switch_buffer(&save_buf, buf);
|
||||||
posp = getmark(mark, false);
|
posp = getmark(mark, false);
|
||||||
restore_buffer(savebuf);
|
restore_buffer(&save_buf);
|
||||||
|
|
||||||
if (try_end(err)) {
|
if (try_end(err)) {
|
||||||
return rv;
|
return rv;
|
||||||
|
@@ -899,7 +899,7 @@ static void set_option_value_for(char *key,
|
|||||||
{
|
{
|
||||||
win_T *save_curwin = NULL;
|
win_T *save_curwin = NULL;
|
||||||
tabpage_T *save_curtab = NULL;
|
tabpage_T *save_curtab = NULL;
|
||||||
buf_T *save_curbuf = NULL;
|
bufref_T save_curbuf = { NULL, 0 };
|
||||||
|
|
||||||
try_start();
|
try_start();
|
||||||
switch (opt_type)
|
switch (opt_type)
|
||||||
@@ -922,7 +922,7 @@ static void set_option_value_for(char *key,
|
|||||||
case SREQ_BUF:
|
case SREQ_BUF:
|
||||||
switch_buffer(&save_curbuf, (buf_T *)from);
|
switch_buffer(&save_curbuf, (buf_T *)from);
|
||||||
set_option_value_err(key, numval, stringval, opt_flags, err);
|
set_option_value_err(key, numval, stringval, opt_flags, err);
|
||||||
restore_buffer(save_curbuf);
|
restore_buffer(&save_curbuf);
|
||||||
break;
|
break;
|
||||||
case SREQ_GLOBAL:
|
case SREQ_GLOBAL:
|
||||||
set_option_value_err(key, numval, stringval, opt_flags, err);
|
set_option_value_err(key, numval, stringval, opt_flags, err);
|
||||||
|
@@ -78,6 +78,9 @@ static char *msg_loclist = N_("[Location List]");
|
|||||||
static char *msg_qflist = N_("[Quickfix List]");
|
static char *msg_qflist = N_("[Quickfix List]");
|
||||||
static char *e_auabort = N_("E855: Autocommands caused command to abort");
|
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
|
* Open current buffer, that is: open the memfile and read the file into
|
||||||
* memory.
|
* memory.
|
||||||
@@ -91,7 +94,7 @@ open_buffer (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
int retval = OK;
|
int retval = OK;
|
||||||
buf_T *old_curbuf;
|
bufref_T old_curbuf;
|
||||||
long old_tw = curbuf->b_p_tw;
|
long old_tw = curbuf->b_p_tw;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -133,10 +136,10 @@ open_buffer (
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The autocommands in readfile() may change the buffer, but only AFTER
|
// The autocommands in readfile() may change the buffer, but only AFTER
|
||||||
* reading the file. */
|
// reading the file.
|
||||||
old_curbuf = curbuf;
|
set_bufref(&old_curbuf, curbuf);
|
||||||
modified_was_set = FALSE;
|
modified_was_set = false;
|
||||||
|
|
||||||
/* mark cursor position as being invalid */
|
/* mark cursor position as being invalid */
|
||||||
curwin->w_valid = 0;
|
curwin->w_valid = 0;
|
||||||
@@ -249,11 +252,11 @@ open_buffer (
|
|||||||
* The autocommands may have changed the current buffer. Apply the
|
* The autocommands may have changed the current buffer. Apply the
|
||||||
* modelines to the correct buffer, if it still exists and is loaded.
|
* 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;
|
aco_save_T aco;
|
||||||
|
|
||||||
/* Go to the buffer that was opened. */
|
// Go to the buffer that was opened.
|
||||||
aucmd_prepbuf(&aco, old_curbuf);
|
aucmd_prepbuf(&aco, old_curbuf.br_buf);
|
||||||
do_modelines(0);
|
do_modelines(0);
|
||||||
curbuf->b_flags &= ~(BF_CHECK_RO | BF_NEVERLOADED);
|
curbuf->b_flags &= ~(BF_CHECK_RO | BF_NEVERLOADED);
|
||||||
|
|
||||||
@@ -267,14 +270,42 @@ open_buffer (
|
|||||||
return retval;
|
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)
|
bool buf_valid(buf_T *buf)
|
||||||
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
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;
|
||||||
}
|
}
|
||||||
@@ -363,13 +394,15 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last)
|
|||||||
win->w_cursor.col, TRUE);
|
win->w_cursor.col, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bufref_T bufref;
|
||||||
|
set_bufref(&bufref, buf);
|
||||||
|
|
||||||
/* 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) && !bufref_valid(&bufref)) {
|
||||||
if (!buf_valid(buf)) {
|
// Autocommands deleted the buffer.
|
||||||
/* Autocommands deleted the buffer. */
|
|
||||||
EMSG(_(e_auabort));
|
EMSG(_(e_auabort));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -384,10 +417,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) && !bufref_valid(&bufref)) {
|
||||||
if (!buf_valid(buf)) {
|
// Autocommands deleted the buffer.
|
||||||
/* Autocommands deleted the buffer. */
|
|
||||||
EMSG(_(e_auabort));
|
EMSG(_(e_auabort));
|
||||||
return;
|
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));
|
buf_freeall(buf, (del_buf ? BFA_DEL : 0) + (wipe_buf ? BFA_WIPE : 0));
|
||||||
|
|
||||||
/* Autocommands may have deleted the buffer. */
|
if (!bufref_valid(&bufref)) {
|
||||||
if (!buf_valid(buf))
|
// Autocommands may have deleted the buffer.
|
||||||
return;
|
return;
|
||||||
if (aborting()) /* autocmds may abort script processing */
|
}
|
||||||
|
if (aborting()) {
|
||||||
|
// Autocmds may abort script processing.
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* It's possible that autocommands change curbuf to the one being deleted.
|
* 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.
|
// Make sure the buffer isn't closed by autocommands.
|
||||||
buf->b_closing = true;
|
buf->b_closing = true;
|
||||||
if (buf->b_ml.ml_mfp != NULL) {
|
|
||||||
apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, false, buf);
|
bufref_T bufref;
|
||||||
if (!buf_valid(buf)) { // autocommands may delete the buffer
|
set_bufref(&bufref, buf);
|
||||||
return;
|
|
||||||
}
|
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) {
|
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;
|
&& !bufref_valid(&bufref)) {
|
||||||
|
// 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 */
|
&& !bufref_valid(&bufref)) {
|
||||||
return;
|
// Autocommands may delete the buffer.
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
buf->b_closing = false;
|
buf->b_closing = false;
|
||||||
|
|
||||||
@@ -603,7 +645,8 @@ void buf_freeall(buf_T *buf, int flags)
|
|||||||
static void free_buffer(buf_T *buf)
|
static void free_buffer(buf_T *buf)
|
||||||
{
|
{
|
||||||
handle_unregister_buffer(buf);
|
handle_unregister_buffer(buf);
|
||||||
free_buffer_stuff(buf, TRUE);
|
buf_free_count++;
|
||||||
|
free_buffer_stuff(buf, true);
|
||||||
unref_var_dict(buf->b_vars);
|
unref_var_dict(buf->b_vars);
|
||||||
aubuflocal_remove(buf);
|
aubuflocal_remove(buf);
|
||||||
buf_hashtab_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 goto_buffer(exarg_T *eap, int start, int dir, int count)
|
||||||
{
|
{
|
||||||
(void)do_buffer(*eap->cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO,
|
(void)do_buffer(*eap->cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO,
|
||||||
start, dir, count, eap->forceit);
|
start, dir, count, eap->forceit);
|
||||||
buf_T *old_curbuf = curbuf;
|
bufref_T old_curbuf;
|
||||||
|
set_bufref(&old_curbuf, curbuf);
|
||||||
swap_exists_action = SEA_DIALOG;
|
swap_exists_action = SEA_DIALOG;
|
||||||
|
|
||||||
if (swap_exists_action == SEA_QUIT && *eap->cmd == 's') {
|
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. */
|
* new aborting error, interrupt, or uncaught exception. */
|
||||||
leave_cleanup(&cs);
|
leave_cleanup(&cs);
|
||||||
} else {
|
} else {
|
||||||
handle_swap_exists(old_curbuf);
|
handle_swap_exists(&old_curbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/// Handle the situation of swap_exists_action being set.
|
||||||
* Handle the situation of swap_exists_action being set.
|
///
|
||||||
* It is allowed for "old_curbuf" to be NULL or invalid.
|
/// It is allowed for "old_curbuf" to be NULL or invalid.
|
||||||
*/
|
///
|
||||||
void handle_swap_exists(buf_T *old_curbuf)
|
/// @param old_curbuf The buffer to check for.
|
||||||
|
void handle_swap_exists(bufref_T *old_curbuf)
|
||||||
{
|
{
|
||||||
cleanup_T cs;
|
cleanup_T cs;
|
||||||
long old_tw = curbuf->b_p_tw;
|
long old_tw = curbuf->b_p_tw;
|
||||||
|
buf_T *buf;
|
||||||
|
|
||||||
if (swap_exists_action == SEA_QUIT) {
|
if (swap_exists_action == SEA_QUIT) {
|
||||||
/* Reset the error/interrupt/exception state here so that
|
/* 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_action = SEA_NONE; // don't want it again
|
||||||
swap_exists_did_quit = true;
|
swap_exists_did_quit = true;
|
||||||
close_buffer(curwin, curbuf, DOBUF_UNLOAD, false);
|
close_buffer(curwin, curbuf, DOBUF_UNLOAD, false);
|
||||||
if (!buf_valid(old_curbuf) || old_curbuf == curbuf) {
|
if (old_curbuf == NULL
|
||||||
old_curbuf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED);
|
|| !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) {
|
if (buf != NULL) {
|
||||||
enter_buffer(old_curbuf);
|
enter_buffer(buf);
|
||||||
if (old_tw != curbuf->b_p_tw)
|
if (old_tw != curbuf->b_p_tw) {
|
||||||
check_colorcolumn(curwin);
|
check_colorcolumn(curwin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* If "old_curbuf" is NULL we are in big trouble here... */
|
/* 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;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bufref_T bufref;
|
||||||
|
set_bufref(&bufref, buf);
|
||||||
|
|
||||||
if (close_others) {
|
if (close_others) {
|
||||||
/* Close any other windows on this buffer, then make it empty. */
|
/* Close any other windows on this buffer, then make it empty. */
|
||||||
close_windows(buf, TRUE);
|
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,
|
retval = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE,
|
||||||
forceit ? ECMD_FORCEIT : 0, curwin);
|
forceit ? ECMD_FORCEIT : 0, curwin);
|
||||||
|
|
||||||
/*
|
// do_ecmd() may create a new buffer, then we have to delete
|
||||||
* do_ecmd() may create a new buffer, then we have to delete
|
// the old one. But do_ecmd() may have done that already, check
|
||||||
* the old one. But do_ecmd() may have done that already, check
|
// if the buffer still exists.
|
||||||
* if the buffer still exists.
|
if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows == 0) {
|
||||||
*/
|
close_buffer(NULL, buf, action, false);
|
||||||
if (buf != curbuf && buf_valid(buf) && buf->b_nwindows == 0)
|
}
|
||||||
close_buffer(NULL, buf, action, FALSE);
|
|
||||||
if (!close_others)
|
if (!close_others) {
|
||||||
need_fileinfo = FALSE;
|
need_fileinfo = false;
|
||||||
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -998,6 +1054,8 @@ do_buffer (
|
|||||||
*/
|
*/
|
||||||
if (unload) {
|
if (unload) {
|
||||||
int forward;
|
int forward;
|
||||||
|
bufref_T bufref;
|
||||||
|
set_bufref(&bufref, buf);
|
||||||
|
|
||||||
/* When unloading or deleting a buffer that's already unloaded and
|
/* When unloading or deleting a buffer that's already unloaded and
|
||||||
* unlisted: fail silently. */
|
* unlisted: fail silently. */
|
||||||
@@ -1006,15 +1064,16 @@ do_buffer (
|
|||||||
|
|
||||||
if (!forceit && (buf->terminal || bufIsChanged(buf))) {
|
if (!forceit && (buf->terminal || bufIsChanged(buf))) {
|
||||||
if ((p_confirm || cmdmod.confirm) && p_write && !buf->terminal) {
|
if ((p_confirm || cmdmod.confirm) && p_write && !buf->terminal) {
|
||||||
dialog_changed(buf, FALSE);
|
dialog_changed(buf, false);
|
||||||
if (!buf_valid(buf))
|
if (!bufref_valid(&bufref)) {
|
||||||
/* Autocommand deleted buffer, oops! It's not changed
|
// Autocommand deleted buffer, oops! It's not changed now.
|
||||||
* now. */
|
|
||||||
return FAIL;
|
return FAIL;
|
||||||
/* If it's still changed fail silently, the dialog already
|
}
|
||||||
* mentioned why it fails. */
|
// If it's still changed fail silently, the dialog already
|
||||||
if (bufIsChanged(buf))
|
// mentioned why it fails.
|
||||||
|
if (bufIsChanged(buf)) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (buf->terminal) {
|
if (buf->terminal) {
|
||||||
EMSG2(_("E89: %s will be killed(add ! to override)"),
|
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 the buffer to be deleted is not the current one, delete it here.
|
||||||
*/
|
*/
|
||||||
if (buf != curbuf) {
|
if (buf != curbuf) {
|
||||||
close_windows(buf, FALSE);
|
close_windows(buf, false);
|
||||||
if (buf != curbuf && buf_valid(buf) && buf->b_nwindows <= 0)
|
if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows <= 0) {
|
||||||
close_buffer(NULL, buf, action, FALSE);
|
close_buffer(NULL, buf, action, false);
|
||||||
|
}
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Deleting the current buffer: Need to find another buffer to go to.
|
||||||
* Deleting the current buffer: Need to find another buffer to go to.
|
// There should be another, otherwise it would have been handled
|
||||||
* There should be another, otherwise it would have been handled
|
// above. However, autocommands may have deleted all buffers.
|
||||||
* above. However, autocommands may have deleted all buffers.
|
// First use au_new_curbuf.br_buf, if it is valid.
|
||||||
* First use au_new_curbuf, if it is valid.
|
// Then prefer the buffer we most recently visited.
|
||||||
* Then prefer the buffer we most recently visited.
|
// Else try to find one that is loaded, after the current buffer,
|
||||||
* Else try to find one that is loaded, after the current buffer,
|
// then before the current buffer.
|
||||||
* then before the current buffer.
|
// Finally use any buffer.
|
||||||
* Finally use any buffer.
|
buf = NULL; // Selected buffer.
|
||||||
*/
|
bp = NULL; // Used when no loaded buffer found.
|
||||||
buf = NULL; /* selected buffer */
|
if (au_new_curbuf.br_buf != NULL && bufref_valid(&au_new_curbuf)) {
|
||||||
bp = NULL; /* used when no loaded buffer found */
|
buf = au_new_curbuf.br_buf;
|
||||||
if (au_new_curbuf != NULL && buf_valid(au_new_curbuf))
|
} else if (curwin->w_jumplistlen > 0) {
|
||||||
buf = au_new_curbuf;
|
|
||||||
else if (curwin->w_jumplistlen > 0) {
|
|
||||||
int jumpidx;
|
int jumpidx;
|
||||||
|
|
||||||
jumpidx = curwin->w_jumplistidx - 1;
|
jumpidx = curwin->w_jumplistidx - 1;
|
||||||
@@ -1183,10 +1241,13 @@ do_buffer (
|
|||||||
*/
|
*/
|
||||||
if (action == DOBUF_GOTO && !can_abandon(curbuf, forceit)) {
|
if (action == DOBUF_GOTO && !can_abandon(curbuf, forceit)) {
|
||||||
if ((p_confirm || cmdmod.confirm) && p_write) {
|
if ((p_confirm || cmdmod.confirm) && p_write) {
|
||||||
dialog_changed(curbuf, FALSE);
|
bufref_T bufref;
|
||||||
if (!buf_valid(buf))
|
set_bufref(&bufref, buf);
|
||||||
/* Autocommand deleted buffer, oops! */
|
dialog_changed(curbuf, false);
|
||||||
|
if (!bufref_valid(&bufref)) {
|
||||||
|
// Autocommand deleted buffer, oops!
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (bufIsChanged(curbuf)) {
|
if (bufIsChanged(curbuf)) {
|
||||||
EMSG(_(e_nowrtmsg));
|
EMSG(_(e_nowrtmsg));
|
||||||
@@ -1234,14 +1295,18 @@ 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;
|
||||||
|
bufref_T bufref;
|
||||||
|
set_bufref(&bufref, prevbuf);
|
||||||
|
|
||||||
apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
|
if (!apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf)
|
||||||
if (buf_valid(prevbuf) && !aborting()) {
|
|| (bufref_valid(&bufref) && !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) {
|
||||||
if (buf_valid(prevbuf) && !aborting()) {
|
close_windows(prevbuf, false);
|
||||||
|
}
|
||||||
|
if (bufref_valid(&bufref) && !aborting()) {
|
||||||
win_T *previouswin = curwin;
|
win_T *previouswin = curwin;
|
||||||
if (prevbuf == curbuf)
|
if (prevbuf == curbuf)
|
||||||
u_sync(FALSE);
|
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_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 +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,
|
&& (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;
|
||||||
|
bufref_T bufref;
|
||||||
|
set_bufref(&bufref, buf);
|
||||||
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)) {
|
&& !bufref_valid(&bufref)) {
|
||||||
return NULL;
|
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
|
// 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);
|
bufref_T bufref;
|
||||||
if (!buf_valid(buf)) {
|
set_bufref(&bufref, buf);
|
||||||
|
if (apply_autocmds(EVENT_BUFNEW, NULL, NULL, false, buf)
|
||||||
|
&& !bufref_valid(&bufref)) {
|
||||||
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)) {
|
&& !bufref_valid(&bufref)) {
|
||||||
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;
|
||||||
@@ -1785,7 +1859,8 @@ buf_T *buflist_findname(char_u *ffname)
|
|||||||
static buf_T *buflist_findname_file_id(char_u *ffname, FileID *file_id,
|
static buf_T *buflist_findname_file_id(char_u *ffname, FileID *file_id,
|
||||||
bool file_id_valid)
|
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
|
if ((buf->b_flags & BF_DUMMY) == 0
|
||||||
&& !otherfile_buf(buf, ffname, file_id, file_id_valid)) {
|
&& !otherfile_buf(buf, ffname, file_id, file_id_valid)) {
|
||||||
return buf;
|
return buf;
|
||||||
@@ -1859,7 +1934,7 @@ int buflist_findpat(
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
FOR_ALL_BUFFERS(buf) {
|
FOR_ALL_BUFFERS_BACKWARDS(buf) {
|
||||||
if (buf->b_p_bl == find_listed
|
if (buf->b_p_bl == find_listed
|
||||||
&& (!diffmode || diff_mode_buf(buf))
|
&& (!diffmode || diff_mode_buf(buf))
|
||||||
&& buflist_match(®match, buf, false) != NULL) {
|
&& buflist_match(®match, buf, false) != NULL) {
|
||||||
@@ -4223,12 +4298,13 @@ do_arg_all (
|
|||||||
|| !bufIsChanged(buf)) {
|
|| !bufIsChanged(buf)) {
|
||||||
/* If the buffer was changed, and we would like to hide it,
|
/* If the buffer was changed, and we would like to hide it,
|
||||||
* try autowriting. */
|
* try autowriting. */
|
||||||
if (!P_HID(buf) && buf->b_nwindows <= 1
|
if (!P_HID(buf) && buf->b_nwindows <= 1 && bufIsChanged(buf)) {
|
||||||
&& bufIsChanged(buf)) {
|
bufref_T bufref;
|
||||||
(void)autowrite(buf, FALSE);
|
set_bufref(&bufref, buf);
|
||||||
/* check if autocommands removed the window */
|
(void)autowrite(buf, false);
|
||||||
if (!win_valid(wp) || !buf_valid(buf)) {
|
// Check if autocommands removed the window.
|
||||||
wpnext = firstwin; /* start all over... */
|
if (!win_valid(wp) || !bufref_valid(&bufref)) {
|
||||||
|
wpnext = firstwin; // Start all over...
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4442,7 +4518,9 @@ void ex_buffer_all(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (wp == NULL && split_ret == OK) {
|
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_save = p_ea;
|
||||||
p_ea = true; /* use space from all windows */
|
p_ea = true; /* use space from all windows */
|
||||||
split_ret = win_split(0, WSP_ROOM | WSP_BELOW);
|
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. */
|
/* Open the buffer in this window. */
|
||||||
swap_exists_action = SEA_DIALOG;
|
swap_exists_action = SEA_DIALOG;
|
||||||
set_curbuf(buf, DOBUF_GOTO);
|
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;
|
swap_exists_action = SEA_NONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -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()
|
||||||
@@ -55,21 +57,22 @@ enum bfa_values {
|
|||||||
static inline void switch_to_win_for_buf(buf_T *buf,
|
static inline void switch_to_win_for_buf(buf_T *buf,
|
||||||
win_T **save_curwinp,
|
win_T **save_curwinp,
|
||||||
tabpage_T **save_curtabp,
|
tabpage_T **save_curtabp,
|
||||||
buf_T **save_curbufp)
|
bufref_T *save_curbuf)
|
||||||
{
|
{
|
||||||
win_T *wp;
|
win_T *wp;
|
||||||
tabpage_T *tp;
|
tabpage_T *tp;
|
||||||
|
|
||||||
if (!find_win_for_buf(buf, &wp, &tp)
|
if (!find_win_for_buf(buf, &wp, &tp)
|
||||||
|| switch_win(save_curwinp, save_curtabp, wp, tp, true) == FAIL)
|
|| switch_win(save_curwinp, save_curtabp, wp, tp, true) == FAIL) {
|
||||||
switch_buffer(save_curbufp, buf);
|
switch_buffer(save_curbuf, buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void restore_win_for_buf(win_T *save_curwin,
|
static inline void restore_win_for_buf(win_T *save_curwin,
|
||||||
tabpage_T *save_curtab,
|
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);
|
restore_win(save_curwin, save_curtab, true);
|
||||||
} else {
|
} else {
|
||||||
restore_buffer(save_curbuf);
|
restore_buffer(save_curbuf);
|
||||||
@@ -78,12 +81,12 @@ static inline void restore_win_for_buf(win_T *save_curwin,
|
|||||||
|
|
||||||
#define WITH_BUFFER(b, code) \
|
#define WITH_BUFFER(b, code) \
|
||||||
do { \
|
do { \
|
||||||
buf_T *save_curbuf = NULL; \
|
|
||||||
win_T *save_curwin = NULL; \
|
win_T *save_curwin = NULL; \
|
||||||
tabpage_T *save_curtab = NULL; \
|
tabpage_T *save_curtab = NULL; \
|
||||||
|
bufref_T save_curbuf = { NULL, 0 }; \
|
||||||
switch_to_win_for_buf(b, &save_curwin, &save_curtab, &save_curbuf); \
|
switch_to_win_for_buf(b, &save_curwin, &save_curtab, &save_curbuf); \
|
||||||
code; \
|
code; \
|
||||||
restore_win_for_buf(save_curwin, save_curtab, save_curbuf); \
|
restore_win_for_buf(save_curwin, save_curtab, &save_curbuf); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -8,6 +8,13 @@
|
|||||||
|
|
||||||
typedef struct file_buffer buf_T; // Forward declaration
|
typedef struct file_buffer buf_T; // Forward declaration
|
||||||
|
|
||||||
|
// Reference to a buffer that stores the value of buf_free_count.
|
||||||
|
// bufref_valid() only needs to check "buf" when the count differs.
|
||||||
|
typedef struct {
|
||||||
|
buf_T *br_buf;
|
||||||
|
int br_buf_free_count;
|
||||||
|
} bufref_T;
|
||||||
|
|
||||||
// for garray_T
|
// for garray_T
|
||||||
#include "nvim/garray.h"
|
#include "nvim/garray.h"
|
||||||
// for pos_T, lpos_T and linenr_T
|
// for pos_T, lpos_T and linenr_T
|
||||||
|
@@ -1004,7 +1004,8 @@ theend:
|
|||||||
void ex_diffsplit(exarg_T *eap)
|
void ex_diffsplit(exarg_T *eap)
|
||||||
{
|
{
|
||||||
win_T *old_curwin = curwin;
|
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
|
// don't use a new tab page, each tab page has its own diffs
|
||||||
cmdmod.tab = 0;
|
cmdmod.tab = 0;
|
||||||
@@ -1022,10 +1023,10 @@ void ex_diffsplit(exarg_T *eap)
|
|||||||
if (win_valid(old_curwin)) {
|
if (win_valid(old_curwin)) {
|
||||||
diff_win_options(old_curwin, true);
|
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.
|
// Move the cursor position to that of the old window.
|
||||||
curwin->w_cursor.lnum = diff_get_corresponding_line(
|
curwin->w_cursor.lnum = diff_get_corresponding_line(
|
||||||
old_curbuf,
|
old_curbuf.br_buf,
|
||||||
old_curwin->w_cursor.lnum,
|
old_curwin->w_cursor.lnum,
|
||||||
curbuf,
|
curbuf,
|
||||||
curwin->w_cursor.lnum);
|
curwin->w_cursor.lnum);
|
||||||
|
@@ -10306,7 +10306,7 @@ static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
|
|
||||||
ExpandInit(&xpc);
|
ExpandInit(&xpc);
|
||||||
xpc.xp_pattern = get_tv_string(&argvars[0]);
|
xpc.xp_pattern = get_tv_string(&argvars[0]);
|
||||||
xpc.xp_pattern_len = STRLEN(xpc.xp_pattern);
|
xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
|
||||||
xpc.xp_context = cmdcomplete_str_to_type(get_tv_string(&argvars[1]));
|
xpc.xp_context = cmdcomplete_str_to_type(get_tv_string(&argvars[1]));
|
||||||
if (xpc.xp_context == EXPAND_NOTHING) {
|
if (xpc.xp_context == EXPAND_NOTHING) {
|
||||||
if (argvars[1].v_type == VAR_STRING) {
|
if (argvars[1].v_type == VAR_STRING) {
|
||||||
@@ -10319,17 +10319,17 @@ static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
|
|
||||||
if (xpc.xp_context == EXPAND_MENUS) {
|
if (xpc.xp_context == EXPAND_MENUS) {
|
||||||
set_context_in_menu_cmd(&xpc, (char_u *)"menu", xpc.xp_pattern, false);
|
set_context_in_menu_cmd(&xpc, (char_u *)"menu", xpc.xp_pattern, false);
|
||||||
xpc.xp_pattern_len = STRLEN(xpc.xp_pattern);
|
xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xpc.xp_context == EXPAND_CSCOPE) {
|
if (xpc.xp_context == EXPAND_CSCOPE) {
|
||||||
set_context_in_cscope_cmd(&xpc, xpc.xp_pattern, CMD_cscope);
|
set_context_in_cscope_cmd(&xpc, xpc.xp_pattern, CMD_cscope);
|
||||||
xpc.xp_pattern_len = STRLEN(xpc.xp_pattern);
|
xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xpc.xp_context == EXPAND_SIGN) {
|
if (xpc.xp_context == EXPAND_SIGN) {
|
||||||
set_context_in_sign_cmd(&xpc, xpc.xp_pattern);
|
set_context_in_sign_cmd(&xpc, xpc.xp_pattern);
|
||||||
xpc.xp_pattern_len = STRLEN(xpc.xp_pattern);
|
xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
pat = addstar(xpc.xp_pattern, xpc.xp_pattern_len, xpc.xp_context);
|
pat = addstar(xpc.xp_pattern, xpc.xp_pattern_len, xpc.xp_context);
|
||||||
|
@@ -1904,11 +1904,15 @@ void do_wqall(exarg_T *eap)
|
|||||||
FALSE) == FAIL) {
|
FALSE) == FAIL) {
|
||||||
++error;
|
++error;
|
||||||
} else {
|
} else {
|
||||||
if (buf_write_all(buf, eap->forceit) == FAIL)
|
bufref_T bufref;
|
||||||
++error;
|
set_bufref(&bufref, buf);
|
||||||
/* an autocommand may have deleted the buffer */
|
if (buf_write_all(buf, eap->forceit) == FAIL) {
|
||||||
if (!buf_valid(buf))
|
error++;
|
||||||
|
}
|
||||||
|
// An autocommand may have deleted the buffer.
|
||||||
|
if (!bufref_valid(&bufref)) {
|
||||||
buf = firstbuf;
|
buf = firstbuf;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
eap->forceit = save_forceit; /* check_overwrite() may set it */
|
eap->forceit = save_forceit; /* check_overwrite() may set it */
|
||||||
}
|
}
|
||||||
@@ -2081,7 +2085,8 @@ int do_ecmd(
|
|||||||
char_u *new_name = NULL;
|
char_u *new_name = NULL;
|
||||||
int did_set_swapcommand = FALSE;
|
int did_set_swapcommand = FALSE;
|
||||||
buf_T *buf;
|
buf_T *buf;
|
||||||
buf_T *old_curbuf = curbuf;
|
bufref_T bufref;
|
||||||
|
bufref_T old_curbuf;
|
||||||
char_u *free_fname = NULL;
|
char_u *free_fname = NULL;
|
||||||
int retval = FAIL;
|
int retval = FAIL;
|
||||||
long n;
|
long n;
|
||||||
@@ -2098,6 +2103,8 @@ int do_ecmd(
|
|||||||
if (eap != NULL)
|
if (eap != NULL)
|
||||||
command = eap->do_ecmd_cmd;
|
command = eap->do_ecmd_cmd;
|
||||||
|
|
||||||
|
set_bufref(&old_curbuf, curbuf);
|
||||||
|
|
||||||
if (fnum != 0) {
|
if (fnum != 0) {
|
||||||
if (fnum == curbuf->b_fnum) /* file is already being edited */
|
if (fnum == curbuf->b_fnum) /* file is already being edited */
|
||||||
return OK; /* nothing to do */
|
return OK; /* nothing to do */
|
||||||
@@ -2209,23 +2216,27 @@ int do_ecmd(
|
|||||||
if (oldwin != NULL) {
|
if (oldwin != NULL) {
|
||||||
oldwin = curwin;
|
oldwin = curwin;
|
||||||
}
|
}
|
||||||
old_curbuf = curbuf;
|
set_bufref(&old_curbuf, curbuf);
|
||||||
}
|
}
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
goto theend;
|
goto theend;
|
||||||
if (buf->b_ml.ml_mfp == NULL) { /* no memfile yet */
|
if (buf->b_ml.ml_mfp == NULL) {
|
||||||
oldbuf = FALSE;
|
// No memfile yet.
|
||||||
} else { /* existing memfile */
|
oldbuf = false;
|
||||||
oldbuf = TRUE;
|
} else {
|
||||||
(void)buf_check_timestamp(buf, FALSE);
|
// Existing memfile.
|
||||||
/* Check if autocommands made buffer invalid or changed the current
|
oldbuf = true;
|
||||||
* buffer. */
|
set_bufref(&bufref, buf);
|
||||||
if (!buf_valid(buf)
|
(void)buf_check_timestamp(buf, false);
|
||||||
|| curbuf != old_curbuf
|
// Check if autocommands made buffer invalid or changed the current
|
||||||
)
|
// buffer.
|
||||||
|
if (!bufref_valid(&bufref) || curbuf != old_curbuf.br_buf) {
|
||||||
goto theend;
|
goto theend;
|
||||||
if (aborting()) /* autocmds may abort script processing */
|
}
|
||||||
|
if (aborting()) {
|
||||||
|
// Autocmds may abort script processing.
|
||||||
goto theend;
|
goto theend;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* May jump to last used line number for a loaded buffer or when asked
|
/* May jump to last used line number for a loaded buffer or when asked
|
||||||
@@ -2253,12 +2264,14 @@ int do_ecmd(
|
|||||||
* - If we ended up in the new buffer already, need to skip a few
|
* - If we ended up in the new buffer already, need to skip a few
|
||||||
* things, set auto_buf.
|
* things, set auto_buf.
|
||||||
*/
|
*/
|
||||||
if (buf->b_fname != NULL)
|
if (buf->b_fname != NULL) {
|
||||||
new_name = vim_strsave(buf->b_fname);
|
new_name = vim_strsave(buf->b_fname);
|
||||||
au_new_curbuf = buf;
|
}
|
||||||
apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
|
set_bufref(&au_new_curbuf, buf);
|
||||||
if (!buf_valid(buf)) { /* new buffer has been deleted */
|
apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf);
|
||||||
delbuf_msg(new_name); /* frees new_name */
|
if (!bufref_valid(&au_new_curbuf)) {
|
||||||
|
// New buffer has been deleted.
|
||||||
|
delbuf_msg(new_name); // Frees new_name.
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
if (aborting()) { /* autocmds may abort script processing */
|
if (aborting()) { /* autocmds may abort script processing */
|
||||||
@@ -2272,7 +2285,7 @@ int do_ecmd(
|
|||||||
|
|
||||||
// Set the w_closing flag to avoid that autocommands close the window.
|
// Set the w_closing flag to avoid that autocommands close the window.
|
||||||
the_curwin->w_closing = true;
|
the_curwin->w_closing = true;
|
||||||
if (curbuf == old_curbuf) {
|
if (curbuf == old_curbuf.br_buf) {
|
||||||
buf_copy_options(buf, BCO_ENTER);
|
buf_copy_options(buf, BCO_ENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2290,9 +2303,10 @@ int do_ecmd(
|
|||||||
xfree(new_name);
|
xfree(new_name);
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
/* Be careful again, like above. */
|
// Be careful again, like above.
|
||||||
if (!buf_valid(buf)) { /* new buffer has been deleted */
|
if (!bufref_valid(&au_new_curbuf)) {
|
||||||
delbuf_msg(new_name); /* frees new_name */
|
// New buffer has been deleted.
|
||||||
|
delbuf_msg(new_name); // Frees new_name.
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
if (buf == curbuf) { // already in new buffer
|
if (buf == curbuf) { // already in new buffer
|
||||||
@@ -2325,7 +2339,7 @@ int do_ecmd(
|
|||||||
|
|
||||||
}
|
}
|
||||||
xfree(new_name);
|
xfree(new_name);
|
||||||
au_new_curbuf = NULL;
|
au_new_curbuf.br_buf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
curwin->w_pcmark.lnum = 1;
|
curwin->w_pcmark.lnum = 1;
|
||||||
@@ -2378,10 +2392,12 @@ int do_ecmd(
|
|||||||
solcol = curwin->w_cursor.col;
|
solcol = curwin->w_cursor.col;
|
||||||
}
|
}
|
||||||
buf = curbuf;
|
buf = curbuf;
|
||||||
if (buf->b_fname != NULL)
|
if (buf->b_fname != NULL) {
|
||||||
new_name = vim_strsave(buf->b_fname);
|
new_name = vim_strsave(buf->b_fname);
|
||||||
else
|
} else {
|
||||||
new_name = NULL;
|
new_name = NULL;
|
||||||
|
}
|
||||||
|
set_bufref(&bufref, buf);
|
||||||
if (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur) {
|
if (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur) {
|
||||||
/* Save all the text, so that the reload can be undone.
|
/* Save all the text, so that the reload can be undone.
|
||||||
* Sync first so that this is a separate undo-able action. */
|
* Sync first so that this is a separate undo-able action. */
|
||||||
@@ -2394,14 +2410,15 @@ int do_ecmd(
|
|||||||
u_unchanged(curbuf);
|
u_unchanged(curbuf);
|
||||||
buf_freeall(curbuf, BFA_KEEP_UNDO);
|
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;
|
readfile_flags = READ_KEEP_UNDO;
|
||||||
} else
|
} else {
|
||||||
buf_freeall(curbuf, 0); /* free all things for buffer */
|
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 autocommands deleted the buffer we were going to re-edit, give
|
||||||
if (!buf_valid(buf)) {
|
// up and jump to the end.
|
||||||
delbuf_msg(new_name); /* frees new_name */
|
if (!bufref_valid(&bufref)) {
|
||||||
|
delbuf_msg(new_name); // Frees new_name.
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
xfree(new_name);
|
xfree(new_name);
|
||||||
@@ -2472,7 +2489,7 @@ int do_ecmd(
|
|||||||
|
|
||||||
if (swap_exists_action == SEA_QUIT)
|
if (swap_exists_action == SEA_QUIT)
|
||||||
retval = FAIL;
|
retval = FAIL;
|
||||||
handle_swap_exists(old_curbuf);
|
handle_swap_exists(&old_curbuf);
|
||||||
} else {
|
} else {
|
||||||
/* Read the modelines, but only to set window-local options. Any
|
/* Read the modelines, but only to set window-local options. Any
|
||||||
* buffer-local options have already been set and may have been
|
* buffer-local options have already been set and may have been
|
||||||
@@ -2607,7 +2624,7 @@ static void delbuf_msg(char_u *name)
|
|||||||
EMSG2(_("E143: Autocommands unexpectedly deleted new buffer %s"),
|
EMSG2(_("E143: Autocommands unexpectedly deleted new buffer %s"),
|
||||||
name == NULL ? (char_u *)"" : name);
|
name == NULL ? (char_u *)"" : name);
|
||||||
xfree(name);
|
xfree(name);
|
||||||
au_new_curbuf = NULL;
|
au_new_curbuf.br_buf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int append_indent = 0; /* autoindent for first line */
|
static int append_indent = 0; /* autoindent for first line */
|
||||||
|
@@ -1181,6 +1181,7 @@ bool prof_def_func(void)
|
|||||||
int autowrite(buf_T *buf, int forceit)
|
int autowrite(buf_T *buf, int forceit)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
bufref_T bufref;
|
||||||
|
|
||||||
if (!(p_aw || p_awa) || !p_write
|
if (!(p_aw || p_awa) || !p_write
|
||||||
// never autowrite a "nofile" or "nowrite" buffer
|
// 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) {
|
|| (!forceit && buf->b_p_ro) || buf->b_ffname == NULL) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
set_bufref(&bufref, buf);
|
||||||
r = buf_write_all(buf, forceit);
|
r = buf_write_all(buf, forceit);
|
||||||
|
|
||||||
// Writing may succeed but the buffer still changed, e.g., when there is a
|
// Writing may succeed but the buffer still changed, e.g., when there is a
|
||||||
// conversion error. We do want to return FAIL then.
|
// conversion error. We do want to return FAIL then.
|
||||||
if (buf_valid(buf) && bufIsChanged(buf)) {
|
if (bufref_valid(&bufref) && bufIsChanged(buf)) {
|
||||||
r = FAIL;
|
r = FAIL;
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
@@ -1207,9 +1209,11 @@ void autowrite_all(void)
|
|||||||
|
|
||||||
FOR_ALL_BUFFERS(buf) {
|
FOR_ALL_BUFFERS(buf) {
|
||||||
if (bufIsChanged(buf) && !buf->b_p_ro) {
|
if (bufIsChanged(buf) && !buf->b_p_ro) {
|
||||||
|
bufref_T bufref;
|
||||||
|
set_bufref(&bufref, buf);
|
||||||
(void)buf_write_all(buf, false);
|
(void)buf_write_all(buf, false);
|
||||||
// an autocommand may have deleted the buffer
|
// an autocommand may have deleted the buffer
|
||||||
if (!buf_valid(buf)) {
|
if (!bufref_valid(&bufref)) {
|
||||||
buf = firstbuf;
|
buf = firstbuf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1221,6 +1225,8 @@ void autowrite_all(void)
|
|||||||
bool check_changed(buf_T *buf, int flags)
|
bool check_changed(buf_T *buf, int flags)
|
||||||
{
|
{
|
||||||
int forceit = (flags & CCGD_FORCEIT);
|
int forceit = (flags & CCGD_FORCEIT);
|
||||||
|
bufref_T bufref;
|
||||||
|
set_bufref(&bufref, buf);
|
||||||
|
|
||||||
if (!forceit
|
if (!forceit
|
||||||
&& bufIsChanged(buf)
|
&& 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.
|
// Autocommand deleted buffer, oops! It's not changed now.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
dialog_changed(buf, count > 1);
|
dialog_changed(buf, count > 1);
|
||||||
if (!buf_valid(buf)) {
|
if (!bufref_valid(&bufref)) {
|
||||||
// Autocommand deleted buffer, oops! It's not changed now.
|
// Autocommand deleted buffer, oops! It's not changed now.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1300,9 +1306,10 @@ void dialog_changed(buf_T *buf, int checkall)
|
|||||||
// Skip readonly buffers, these need to be confirmed
|
// Skip readonly buffers, these need to be confirmed
|
||||||
// individually.
|
// individually.
|
||||||
FOR_ALL_BUFFERS(buf2) {
|
FOR_ALL_BUFFERS(buf2) {
|
||||||
if (bufIsChanged(buf2)
|
if (bufIsChanged(buf2) && (buf2->b_ffname != NULL) && !buf2->b_p_ro) {
|
||||||
&& (buf2->b_ffname != NULL)
|
bufref_T bufref;
|
||||||
&& !buf2->b_p_ro) {
|
set_bufref(&bufref, buf2);
|
||||||
|
|
||||||
if (buf2->b_fname != NULL
|
if (buf2->b_fname != NULL
|
||||||
&& check_overwrite(&ea, buf2, buf2->b_fname,
|
&& check_overwrite(&ea, buf2, buf2->b_fname,
|
||||||
buf2->b_ffname, false) == OK) {
|
buf2->b_ffname, false) == OK) {
|
||||||
@@ -1310,7 +1317,7 @@ void dialog_changed(buf_T *buf, int checkall)
|
|||||||
(void)buf_write_all(buf2, false);
|
(void)buf_write_all(buf2, false);
|
||||||
}
|
}
|
||||||
// an autocommand may have deleted the buffer
|
// an autocommand may have deleted the buffer
|
||||||
if (!buf_valid(buf2)) {
|
if (!bufref_valid(&bufref)) {
|
||||||
buf2 = firstbuf;
|
buf2 = firstbuf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1407,11 +1414,14 @@ bool check_changed_any(bool hidden, bool unload)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ((!hidden || buf->b_nwindows == 0) && bufIsChanged(buf)) {
|
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
|
// Try auto-writing the buffer. If this fails but the buffer no
|
||||||
// longer exists it's not changed, that's OK.
|
// longer exists it's not changed, that's OK.
|
||||||
if (check_changed(buf, (p_awa ? CCGD_AW : 0)
|
if (check_changed(buf, (p_awa ? CCGD_AW : 0)
|
||||||
| CCGD_MULTWIN
|
| CCGD_MULTWIN
|
||||||
| CCGD_ALLBUF) && buf_valid(buf)) {
|
| CCGD_ALLBUF) && bufref_valid(&bufref)) {
|
||||||
break; // didn't save - still changes
|
break; // didn't save - still changes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1447,9 +1457,11 @@ bool check_changed_any(bool hidden, bool unload)
|
|||||||
if (buf != curbuf) {
|
if (buf != curbuf) {
|
||||||
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
||||||
if (wp->w_buffer == buf) {
|
if (wp->w_buffer == buf) {
|
||||||
|
bufref_T bufref;
|
||||||
|
set_bufref(&bufref, buf);
|
||||||
goto_tabpage_win(tp, wp);
|
goto_tabpage_win(tp, wp);
|
||||||
// Paranoia: did autocmds wipe out the buffer with changes?
|
// Paranoia: did autocmds wipe out the buffer with changes?
|
||||||
if (!buf_valid(buf)) {
|
if (!bufref_valid(&bufref)) {
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
goto buf_found;
|
goto buf_found;
|
||||||
|
@@ -5914,10 +5914,13 @@ ex_win_close (
|
|||||||
need_hide = (bufIsChanged(buf) && buf->b_nwindows <= 1);
|
need_hide = (bufIsChanged(buf) && buf->b_nwindows <= 1);
|
||||||
if (need_hide && !P_HID(buf) && !forceit) {
|
if (need_hide && !P_HID(buf) && !forceit) {
|
||||||
if ((p_confirm || cmdmod.confirm) && p_write) {
|
if ((p_confirm || cmdmod.confirm) && p_write) {
|
||||||
dialog_changed(buf, FALSE);
|
bufref_T bufref;
|
||||||
if (buf_valid(buf) && bufIsChanged(buf))
|
set_bufref(&bufref, buf);
|
||||||
|
dialog_changed(buf, false);
|
||||||
|
if (bufref_valid(&bufref) && bufIsChanged(buf)) {
|
||||||
return;
|
return;
|
||||||
need_hide = FALSE;
|
}
|
||||||
|
need_hide = false;
|
||||||
} else {
|
} else {
|
||||||
EMSG(_(e_nowrtmsg));
|
EMSG(_(e_nowrtmsg));
|
||||||
return;
|
return;
|
||||||
|
@@ -5134,9 +5134,9 @@ int cmd_gchar(int offset)
|
|||||||
static int ex_window(void)
|
static int ex_window(void)
|
||||||
{
|
{
|
||||||
struct cmdline_info save_ccline;
|
struct cmdline_info save_ccline;
|
||||||
buf_T *old_curbuf = curbuf;
|
bufref_T old_curbuf;
|
||||||
|
bufref_T bufref;
|
||||||
win_T *old_curwin = curwin;
|
win_T *old_curwin = curwin;
|
||||||
buf_T *bp;
|
|
||||||
win_T *wp;
|
win_T *wp;
|
||||||
int i;
|
int i;
|
||||||
linenr_T lnum;
|
linenr_T lnum;
|
||||||
@@ -5155,6 +5155,8 @@ static int ex_window(void)
|
|||||||
return K_IGNORE;
|
return K_IGNORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_bufref(&old_curbuf, curbuf);
|
||||||
|
|
||||||
/* Save current window sizes. */
|
/* Save current window sizes. */
|
||||||
win_size_save(&winsizes);
|
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
|
/* Safety check: The old window or buffer was deleted: It's a bug when
|
||||||
* this happens! */
|
* this happens! */
|
||||||
if (!win_valid(old_curwin) || !buf_valid(old_curbuf)) {
|
if (!win_valid(old_curwin) || !bufref_valid(&old_curbuf)) {
|
||||||
cmdwin_result = Ctrl_C;
|
cmdwin_result = Ctrl_C;
|
||||||
EMSG(_("E199: Active window or buffer deleted"));
|
EMSG(_("E199: Active window or buffer deleted"));
|
||||||
} else {
|
} else {
|
||||||
@@ -5320,14 +5322,15 @@ static int ex_window(void)
|
|||||||
// Avoid command-line window first character being concealed
|
// Avoid command-line window first character being concealed
|
||||||
curwin->w_p_cole = 0;
|
curwin->w_p_cole = 0;
|
||||||
wp = curwin;
|
wp = curwin;
|
||||||
bp = curbuf;
|
set_bufref(&bufref, curbuf);
|
||||||
win_goto(old_curwin);
|
win_goto(old_curwin);
|
||||||
win_close(wp, TRUE);
|
win_close(wp, TRUE);
|
||||||
|
|
||||||
/* win_close() may have already wiped the buffer when 'bh' is
|
// win_close() may have already wiped the buffer when 'bh' is
|
||||||
* set to 'wipe' */
|
// set to 'wipe'.
|
||||||
if (buf_valid(bp))
|
if (bufref_valid(&bufref)) {
|
||||||
close_buffer(NULL, bp, DOBUF_WIPE, FALSE);
|
close_buffer(NULL, bufref.br_buf, DOBUF_WIPE, false);
|
||||||
|
}
|
||||||
|
|
||||||
/* Restore window sizes. */
|
/* Restore window sizes. */
|
||||||
win_size_restore(&winsizes);
|
win_size_restore(&winsizes);
|
||||||
|
@@ -2402,6 +2402,7 @@ buf_write (
|
|||||||
int did_cmd = FALSE;
|
int did_cmd = FALSE;
|
||||||
int nofile_err = FALSE;
|
int nofile_err = FALSE;
|
||||||
int empty_memline = (buf->b_ml.ml_mfp == NULL);
|
int empty_memline = (buf->b_ml.ml_mfp == NULL);
|
||||||
|
bufref_T bufref;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Apply PRE autocommands.
|
* Apply PRE autocommands.
|
||||||
@@ -2417,8 +2418,9 @@ buf_write (
|
|||||||
if (fname == buf->b_sfname)
|
if (fname == buf->b_sfname)
|
||||||
buf_fname_s = TRUE;
|
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);
|
aucmd_prepbuf(&aco, buf);
|
||||||
|
set_bufref(&bufref, buf);
|
||||||
|
|
||||||
if (append) {
|
if (append) {
|
||||||
if (!(did_cmd = apply_autocmds_exarg(EVENT_FILEAPPENDCMD,
|
if (!(did_cmd = apply_autocmds_exarg(EVENT_FILEAPPENDCMD,
|
||||||
@@ -2466,14 +2468,13 @@ buf_write (
|
|||||||
/* restore curwin/curbuf and a few other things */
|
/* restore curwin/curbuf and a few other things */
|
||||||
aucmd_restbuf(&aco);
|
aucmd_restbuf(&aco);
|
||||||
|
|
||||||
/*
|
// In three situations we return here and don't write the file:
|
||||||
* In three situations we return here and don't write the file:
|
// 1. the autocommands deleted or unloaded the buffer.
|
||||||
* 1. the autocommands deleted or unloaded the buffer.
|
// 2. The autocommands abort script processing.
|
||||||
* 2. The autocommands abort script processing.
|
// 3. If one of the "Cmd" autocommands was executed.
|
||||||
* 3. If one of the "Cmd" autocommands was executed.
|
if (!bufref_valid(&bufref)) {
|
||||||
*/
|
|
||||||
if (!buf_valid(buf))
|
|
||||||
buf = NULL;
|
buf = NULL;
|
||||||
|
}
|
||||||
if (buf == NULL || (buf->b_ml.ml_mfp == NULL && !empty_memline)
|
if (buf == NULL || (buf->b_ml.ml_mfp == NULL && !empty_memline)
|
||||||
|| did_cmd || nofile_err
|
|| did_cmd || nofile_err
|
||||||
|| aborting()
|
|| aborting()
|
||||||
@@ -4760,12 +4761,14 @@ check_timestamps (
|
|||||||
for (buf = firstbuf; buf != NULL; ) {
|
for (buf = firstbuf; buf != NULL; ) {
|
||||||
/* Only check buffers in a window. */
|
/* Only check buffers in a window. */
|
||||||
if (buf->b_nwindows > 0) {
|
if (buf->b_nwindows > 0) {
|
||||||
|
bufref_T bufref;
|
||||||
|
set_bufref(&bufref, buf);
|
||||||
n = buf_check_timestamp(buf, focus);
|
n = buf_check_timestamp(buf, focus);
|
||||||
if (didit < n)
|
if (didit < n) {
|
||||||
didit = n;
|
didit = n;
|
||||||
if (n > 0 && !buf_valid(buf)) {
|
}
|
||||||
/* Autocommands have removed the buffer, start at the
|
if (n > 0 && !bufref_valid(&bufref)) {
|
||||||
* first one again. */
|
// Autocommands have removed the buffer, start at the first one again.
|
||||||
buf = firstbuf;
|
buf = firstbuf;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -4850,6 +4853,9 @@ buf_check_timestamp (
|
|||||||
char_u *s;
|
char_u *s;
|
||||||
char *reason;
|
char *reason;
|
||||||
|
|
||||||
|
bufref_T bufref;
|
||||||
|
set_bufref(&bufref, buf);
|
||||||
|
|
||||||
// If its a terminal, there is no file name, the buffer is not loaded,
|
// 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
|
// 'buftype' is set, we are in the middle of a save or being called
|
||||||
// recursively: ignore this buffer.
|
// recursively: ignore this buffer.
|
||||||
@@ -4919,8 +4925,9 @@ buf_check_timestamp (
|
|||||||
allbuf_lock--;
|
allbuf_lock--;
|
||||||
busy = false;
|
busy = false;
|
||||||
if (n) {
|
if (n) {
|
||||||
if (!buf_valid(buf))
|
if (!bufref_valid(&bufref)) {
|
||||||
EMSG(_("E246: FileChangedShell autocommand deleted buffer"));
|
EMSG(_("E246: FileChangedShell autocommand deleted buffer"));
|
||||||
|
}
|
||||||
s = get_vim_var_str(VV_FCS_CHOICE);
|
s = get_vim_var_str(VV_FCS_CHOICE);
|
||||||
if (STRCMP(s, "reload") == 0 && *reason != 'd')
|
if (STRCMP(s, "reload") == 0 && *reason != 'd')
|
||||||
reload = TRUE;
|
reload = TRUE;
|
||||||
@@ -5037,11 +5044,11 @@ buf_check_timestamp (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Trigger FileChangedShell when the file was changed in any way. */
|
// Trigger FileChangedShell when the file was changed in any way.
|
||||||
if (buf_valid(buf) && retval != 0)
|
if (bufref_valid(&bufref) && retval != 0) {
|
||||||
(void)apply_autocmds(EVENT_FILECHANGEDSHELLPOST,
|
(void)apply_autocmds(EVENT_FILECHANGEDSHELLPOST, buf->b_fname, buf->b_fname,
|
||||||
buf->b_fname, buf->b_fname, FALSE, buf);
|
false, buf);
|
||||||
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5058,6 +5065,7 @@ void buf_reload(buf_T *buf, int orig_mode)
|
|||||||
linenr_T old_topline;
|
linenr_T old_topline;
|
||||||
int old_ro = buf->b_p_ro;
|
int old_ro = buf->b_p_ro;
|
||||||
buf_T *savebuf;
|
buf_T *savebuf;
|
||||||
|
bufref_T bufref;
|
||||||
int saved = OK;
|
int saved = OK;
|
||||||
aco_save_T aco;
|
aco_save_T aco;
|
||||||
int flags = READ_NEW;
|
int flags = READ_NEW;
|
||||||
@@ -5093,6 +5101,7 @@ void buf_reload(buf_T *buf, int orig_mode)
|
|||||||
} else {
|
} else {
|
||||||
// Allocate a buffer without putting it in the buffer list.
|
// Allocate a buffer without putting it in the buffer list.
|
||||||
savebuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY);
|
savebuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY);
|
||||||
|
set_bufref(&bufref, savebuf);
|
||||||
if (savebuf != NULL && buf == curbuf) {
|
if (savebuf != NULL && buf == curbuf) {
|
||||||
/* Open the memline. */
|
/* Open the memline. */
|
||||||
curbuf = savebuf;
|
curbuf = savebuf;
|
||||||
@@ -5117,12 +5126,14 @@ void buf_reload(buf_T *buf, int orig_mode)
|
|||||||
if (!aborting()) {
|
if (!aborting()) {
|
||||||
EMSG2(_("E321: Could not reload \"%s\""), buf->b_fname);
|
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
|
// Put the text back from the save buffer. First
|
||||||
* delete any lines that readfile() added. */
|
// delete any lines that readfile() added.
|
||||||
while (!bufempty())
|
while (!bufempty()) {
|
||||||
if (ml_delete(buf->b_ml.ml_line_count, FALSE) == FAIL)
|
if (ml_delete(buf->b_ml.ml_line_count, false) == FAIL) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
(void)move_lines(savebuf, buf);
|
(void)move_lines(savebuf, buf);
|
||||||
}
|
}
|
||||||
} else if (buf == curbuf) { /* "buf" still valid */
|
} else if (buf == curbuf) { /* "buf" still valid */
|
||||||
@@ -5139,8 +5150,9 @@ void buf_reload(buf_T *buf, int orig_mode)
|
|||||||
}
|
}
|
||||||
xfree(ea.cmd);
|
xfree(ea.cmd);
|
||||||
|
|
||||||
if (savebuf != NULL && buf_valid(savebuf))
|
if (savebuf != NULL && bufref_valid(&bufref)) {
|
||||||
wipe_buffer(savebuf, FALSE);
|
wipe_buffer(savebuf, false);
|
||||||
|
}
|
||||||
|
|
||||||
/* Invalidate diff info if necessary. */
|
/* Invalidate diff info if necessary. */
|
||||||
diff_invalidate(curbuf);
|
diff_invalidate(curbuf);
|
||||||
@@ -6288,6 +6300,7 @@ void ex_doautoall(exarg_T *eap)
|
|||||||
aco_save_T aco;
|
aco_save_T aco;
|
||||||
char_u *arg = eap->arg;
|
char_u *arg = eap->arg;
|
||||||
int call_do_modelines = check_nomodeline(&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
|
* This is a bit tricky: For some commands curwin->w_buffer needs to be
|
||||||
@@ -6300,8 +6313,9 @@ void ex_doautoall(exarg_T *eap)
|
|||||||
if (buf->b_ml.ml_mfp == NULL) {
|
if (buf->b_ml.ml_mfp == NULL) {
|
||||||
continue;
|
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);
|
aucmd_prepbuf(&aco, buf);
|
||||||
|
set_bufref(&bufref, buf);
|
||||||
|
|
||||||
bool did_aucmd;
|
bool did_aucmd;
|
||||||
// execute the autocommands for this buffer
|
// execute the autocommands for this buffer
|
||||||
@@ -6317,9 +6331,10 @@ void ex_doautoall(exarg_T *eap)
|
|||||||
/* restore the current window */
|
/* restore the current window */
|
||||||
aucmd_restbuf(&aco);
|
aucmd_restbuf(&aco);
|
||||||
|
|
||||||
/* stop if there is some error or buffer was deleted */
|
// Stop if there is some error or buffer was deleted.
|
||||||
if (retval == FAIL || !buf_valid(buf))
|
if (retval == FAIL || !bufref_valid(&bufref)) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
check_cursor(); /* just in case lines got deleted */
|
check_cursor(); /* just in case lines got deleted */
|
||||||
@@ -6426,7 +6441,7 @@ aucmd_prepbuf (
|
|||||||
}
|
}
|
||||||
curbuf = buf;
|
curbuf = buf;
|
||||||
aco->new_curwin = curwin;
|
aco->new_curwin = curwin;
|
||||||
aco->new_curbuf = curbuf;
|
set_bufref(&aco->new_curbuf, curbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cleanup after executing autocommands for a (hidden) buffer.
|
/// Cleanup after executing autocommands for a (hidden) buffer.
|
||||||
@@ -6489,14 +6504,14 @@ win_found:
|
|||||||
// Restore the buffer which was previously edited by curwin, if it was
|
// Restore the buffer which was previously edited by curwin, if it was
|
||||||
// changed, we are still the same window and the buffer is valid.
|
// changed, we are still the same window and the buffer is valid.
|
||||||
if (curwin == aco->new_curwin
|
if (curwin == aco->new_curwin
|
||||||
&& curbuf != aco->new_curbuf
|
&& curbuf != aco->new_curbuf.br_buf
|
||||||
&& buf_valid(aco->new_curbuf)
|
&& bufref_valid(&aco->new_curbuf)
|
||||||
&& aco->new_curbuf->b_ml.ml_mfp != NULL) {
|
&& aco->new_curbuf.br_buf->b_ml.ml_mfp != NULL) {
|
||||||
if (curwin->w_s == &curbuf->b_s) {
|
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->b_nwindows--;
|
||||||
curbuf = aco->new_curbuf;
|
curbuf = aco->new_curbuf.br_buf;
|
||||||
curwin->w_buffer = curbuf;
|
curwin->w_buffer = curbuf;
|
||||||
curbuf->b_nwindows++;
|
curbuf->b_nwindows++;
|
||||||
}
|
}
|
||||||
|
@@ -19,12 +19,12 @@
|
|||||||
* not the current buffer.
|
* not the current buffer.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
buf_T *save_curbuf; /* saved curbuf */
|
buf_T *save_curbuf; ///< saved curbuf
|
||||||
int use_aucmd_win; /* using aucmd_win */
|
int use_aucmd_win; ///< using aucmd_win
|
||||||
win_T *save_curwin; /* saved curwin */
|
win_T *save_curwin; ///< saved curwin
|
||||||
win_T *new_curwin; /* new 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 */
|
char_u *globaldir; ///< saved value of globaldir
|
||||||
} aco_save_T;
|
} aco_save_T;
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
|
@@ -512,9 +512,9 @@ EXTERN int keep_filetype INIT(= FALSE); /* value for did_filetype when
|
|||||||
starting to execute
|
starting to execute
|
||||||
autocommands */
|
autocommands */
|
||||||
|
|
||||||
/* When deleting the current buffer, another one must be loaded. If we know
|
// When deleting the current buffer, another one must be loaded.
|
||||||
* which one is preferred, au_new_curbuf is set to it */
|
// If we know which one is preferred, au_new_curbuf is set to it.
|
||||||
EXTERN buf_T *au_new_curbuf INIT(= NULL);
|
EXTERN bufref_T au_new_curbuf INIT(= { NULL, 0 });
|
||||||
|
|
||||||
// When deleting a buffer/window and autocmd_busy is TRUE, do not free the
|
// When deleting a buffer/window and autocmd_busy is TRUE, do not free the
|
||||||
// buffer/window. but link it in the list starting with
|
// buffer/window. but link it in the list starting with
|
||||||
@@ -602,7 +602,10 @@ EXTERN buf_T *lastbuf INIT(= NULL); // last buffer
|
|||||||
EXTERN buf_T *curbuf INIT(= NULL); // currently active buffer
|
EXTERN buf_T *curbuf INIT(= NULL); // currently active buffer
|
||||||
|
|
||||||
// Iterates over all buffers in the buffer list.
|
// Iterates over all buffers in the buffer list.
|
||||||
# define FOR_ALL_BUFFERS(buf) for (buf_T *buf = firstbuf; buf != NULL; buf = buf->b_next)
|
#define FOR_ALL_BUFFERS(buf) \
|
||||||
|
for (buf_T *buf = firstbuf; buf != NULL; buf = buf->b_next)
|
||||||
|
#define FOR_ALL_BUFFERS_BACKWARDS(buf) \
|
||||||
|
for (buf_T *buf = lastbuf; buf != NULL; buf = buf->b_prev)
|
||||||
|
|
||||||
/* Flag that is set when switching off 'swapfile'. It means that all blocks
|
/* Flag that is set when switching off 'swapfile'. It means that all blocks
|
||||||
* are to be loaded into memory. Shouldn't be global... */
|
* are to be loaded into memory. Shouldn't be global... */
|
||||||
|
@@ -588,10 +588,13 @@ void getout(int exitval)
|
|||||||
/* Trigger BufUnload for buffers that are loaded */
|
/* Trigger BufUnload for buffers that are loaded */
|
||||||
FOR_ALL_BUFFERS(buf) {
|
FOR_ALL_BUFFERS(buf) {
|
||||||
if (buf->b_ml.ml_mfp != NULL) {
|
if (buf->b_ml.ml_mfp != NULL) {
|
||||||
apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname,
|
bufref_T bufref;
|
||||||
FALSE, buf);
|
set_bufref(&bufref, buf);
|
||||||
if (!buf_valid(buf)) /* autocmd may delete the buffer */
|
apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, false, buf);
|
||||||
|
if (!bufref_valid(&bufref)) {
|
||||||
|
// Autocmd deleted the buffer.
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
apply_autocmds(EVENT_VIMLEAVEPRE, NULL, NULL, FALSE, curbuf);
|
apply_autocmds(EVENT_VIMLEAVEPRE, NULL, NULL, FALSE, curbuf);
|
||||||
|
@@ -629,12 +629,12 @@ void free_all_mem(void)
|
|||||||
* were freed already. */
|
* were freed already. */
|
||||||
p_acd = false;
|
p_acd = false;
|
||||||
for (buf = firstbuf; buf != NULL; ) {
|
for (buf = firstbuf; buf != NULL; ) {
|
||||||
|
bufref_T bufref;
|
||||||
|
set_bufref(&bufref, buf);
|
||||||
nextbuf = buf->b_next;
|
nextbuf = buf->b_next;
|
||||||
close_buffer(NULL, buf, DOBUF_WIPE, false);
|
close_buffer(NULL, buf, DOBUF_WIPE, false);
|
||||||
if (buf_valid(buf))
|
// Didn't work, try next one.
|
||||||
buf = nextbuf; /* didn't work, try next one */
|
buf = bufref_valid(&bufref) ? nextbuf : firstbuf;
|
||||||
else
|
|
||||||
buf = firstbuf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free_cmdline_buf();
|
free_cmdline_buf();
|
||||||
|
@@ -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 bufref_T qf_last_bufref = { NULL, 0 };
|
||||||
|
|
||||||
// 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
|
||||||
|
&& bufref_valid(&qf_last_bufref)) {
|
||||||
|
buf = qf_last_bufref.br_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);
|
||||||
|
set_bufref(&qf_last_bufref, buf);
|
||||||
}
|
}
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -3717,8 +3734,9 @@ load_dummy_buffer (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
buf_T *newbuf;
|
buf_T *newbuf;
|
||||||
buf_T *newbuf_to_wipe = NULL;
|
bufref_T newbufref;
|
||||||
int failed = TRUE;
|
bufref_T newbuf_to_wipe;
|
||||||
|
int failed = true;
|
||||||
aco_save_T aco;
|
aco_save_T aco;
|
||||||
|
|
||||||
// Allocate a buffer without putting it in the buffer list.
|
// Allocate a buffer without putting it in the buffer list.
|
||||||
@@ -3726,6 +3744,7 @@ load_dummy_buffer (
|
|||||||
if (newbuf == NULL) {
|
if (newbuf == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
set_bufref(&newbufref, newbuf);
|
||||||
|
|
||||||
/* Init the options. */
|
/* Init the options. */
|
||||||
buf_copy_options(newbuf, BCO_ENTER | BCO_NOHELP);
|
buf_copy_options(newbuf, BCO_ENTER | BCO_NOHELP);
|
||||||
@@ -3745,6 +3764,7 @@ load_dummy_buffer (
|
|||||||
* work. */
|
* work. */
|
||||||
curbuf->b_flags &= ~BF_DUMMY;
|
curbuf->b_flags &= ~BF_DUMMY;
|
||||||
|
|
||||||
|
newbuf_to_wipe.br_buf = NULL;
|
||||||
if (readfile(fname, NULL,
|
if (readfile(fname, NULL,
|
||||||
(linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM,
|
(linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM,
|
||||||
NULL, READ_NEW | READ_DUMMY) == OK
|
NULL, READ_NEW | READ_DUMMY) == OK
|
||||||
@@ -3752,19 +3772,24 @@ load_dummy_buffer (
|
|||||||
&& !(curbuf->b_flags & BF_NEW)) {
|
&& !(curbuf->b_flags & BF_NEW)) {
|
||||||
failed = FALSE;
|
failed = FALSE;
|
||||||
if (curbuf != newbuf) {
|
if (curbuf != newbuf) {
|
||||||
/* Bloody autocommands changed the buffer! Can happen when
|
// Bloody autocommands changed the buffer! Can happen when
|
||||||
* using netrw and editing a remote file. Use the current
|
// using netrw and editing a remote file. Use the current
|
||||||
* buffer instead, delete the dummy one after restoring the
|
// buffer instead, delete the dummy one after restoring the
|
||||||
* window stuff. */
|
// window stuff.
|
||||||
newbuf_to_wipe = newbuf;
|
set_bufref(&newbuf_to_wipe, newbuf);
|
||||||
newbuf = curbuf;
|
newbuf = curbuf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* restore curwin/curbuf and a few other things */
|
// Restore curwin/curbuf and a few other things.
|
||||||
aucmd_restbuf(&aco);
|
aucmd_restbuf(&aco);
|
||||||
if (newbuf_to_wipe != NULL && buf_valid(newbuf_to_wipe))
|
if (newbuf_to_wipe.br_buf != NULL && bufref_valid(&newbuf_to_wipe)) {
|
||||||
wipe_buffer(newbuf_to_wipe, FALSE);
|
wipe_buffer(newbuf_to_wipe.br_buf, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add back the "dummy" flag, otherwise buflist_findname_file_id()
|
||||||
|
// won't skip it.
|
||||||
|
newbuf->b_flags |= BF_DUMMY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3775,8 +3800,9 @@ load_dummy_buffer (
|
|||||||
os_dirname(resulting_dir, MAXPATHL);
|
os_dirname(resulting_dir, MAXPATHL);
|
||||||
restore_start_dir(dirname_start);
|
restore_start_dir(dirname_start);
|
||||||
|
|
||||||
if (!buf_valid(newbuf))
|
if (!bufref_valid(&newbufref)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
if (failed) {
|
if (failed) {
|
||||||
wipe_dummy_buffer(newbuf, dirname_start);
|
wipe_dummy_buffer(newbuf, dirname_start);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@@ -3746,6 +3746,9 @@ char_u *did_set_spelllang(win_T *wp)
|
|||||||
char_u *ret_msg = NULL;
|
char_u *ret_msg = NULL;
|
||||||
char_u *spl_copy;
|
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
|
// We don't want to do this recursively. May happen when a language is
|
||||||
// not available and the SpellFileMissing autocommand opens a new buffer
|
// not available and the SpellFileMissing autocommand opens a new buffer
|
||||||
// in which 'spell' is set.
|
// in which 'spell' is set.
|
||||||
@@ -3824,7 +3827,7 @@ char_u *did_set_spelllang(win_T *wp)
|
|||||||
spell_load_lang(lang);
|
spell_load_lang(lang);
|
||||||
// SpellFileMissing autocommands may do anything, including
|
// SpellFileMissing autocommands may do anything, including
|
||||||
// destroying the buffer we are using...
|
// destroying the buffer we are using...
|
||||||
if (!buf_valid(wp->w_buffer)) {
|
if (!bufref_valid(&bufref)) {
|
||||||
ret_msg =
|
ret_msg =
|
||||||
(char_u *)"E797: SpellFileMissing autocommand deleted buffer";
|
(char_u *)"E797: SpellFileMissing autocommand deleted buffer";
|
||||||
goto theend;
|
goto theend;
|
||||||
@@ -13037,8 +13040,9 @@ void ex_spelldump(exarg_T *eap)
|
|||||||
set_option_value((char_u*)"spl", dummy, spl, OPT_LOCAL);
|
set_option_value((char_u*)"spl", dummy, spl, OPT_LOCAL);
|
||||||
xfree(spl);
|
xfree(spl);
|
||||||
|
|
||||||
if (!bufempty() || !buf_valid(curbuf))
|
if (!bufempty()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
spell_dump_compl(NULL, 0, NULL, eap->forceit ? DUMPFLAG_COUNT : 0);
|
spell_dump_compl(NULL, 0, NULL, eap->forceit ? DUMPFLAG_COUNT : 0);
|
||||||
|
|
||||||
|
@@ -416,14 +416,14 @@ static int included_patches[] = {
|
|||||||
// 2027 NA
|
// 2027 NA
|
||||||
// 2026 NA
|
// 2026 NA
|
||||||
// 2025 NA
|
// 2025 NA
|
||||||
// 2024,
|
2024,
|
||||||
// 2023,
|
2023,
|
||||||
// 2022,
|
2022,
|
||||||
// 2021,
|
2021,
|
||||||
// 2020 NA
|
// 2020 NA
|
||||||
2019,
|
2019,
|
||||||
// 2018,
|
2018,
|
||||||
// 2017,
|
2017,
|
||||||
// 2016 NA
|
// 2016 NA
|
||||||
2015,
|
2015,
|
||||||
2014,
|
2014,
|
||||||
|
@@ -1945,6 +1945,8 @@ int win_close(win_T *win, int free_buf)
|
|||||||
* Close the link to the buffer.
|
* Close the link to the buffer.
|
||||||
*/
|
*/
|
||||||
if (win->w_buffer != NULL) {
|
if (win->w_buffer != NULL) {
|
||||||
|
bufref_T bufref;
|
||||||
|
set_bufref(&bufref, curbuf);
|
||||||
win->w_closing = true;
|
win->w_closing = true;
|
||||||
close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, true);
|
close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, true);
|
||||||
if (win_valid_any_tab(win)) {
|
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
|
// Make sure curbuf is valid. It can become invalid if 'bufhidden' is
|
||||||
// "wipe".
|
// "wipe".
|
||||||
if (!buf_valid(curbuf)) {
|
if (!bufref_valid(&bufref)) {
|
||||||
curbuf = firstbuf;
|
curbuf = firstbuf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5401,32 +5403,30 @@ void restore_win(win_T *save_curwin, tabpage_T *save_curtab, int no_display)
|
|||||||
unblock_autocmds();
|
unblock_autocmds();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/// Make "buf" the current buffer.
|
||||||
* Make "buf" the current buffer. restore_buffer() MUST be called to undo.
|
///
|
||||||
* No autocommands will be executed. Use aucmd_prepbuf() if there are any.
|
/// 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)
|
void switch_buffer(bufref_T *save_curbuf, buf_T *buf)
|
||||||
{
|
{
|
||||||
block_autocmds();
|
block_autocmds();
|
||||||
*save_curbuf = curbuf;
|
set_bufref(save_curbuf, curbuf);
|
||||||
--curbuf->b_nwindows;
|
curbuf->b_nwindows--;
|
||||||
curbuf = buf;
|
curbuf = buf;
|
||||||
curwin->w_buffer = buf;
|
curwin->w_buffer = buf;
|
||||||
++curbuf->b_nwindows;
|
curbuf->b_nwindows++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/// Restore the current buffer after using switch_buffer().
|
||||||
* Restore the current buffer after using switch_buffer().
|
void restore_buffer(bufref_T *save_curbuf)
|
||||||
*/
|
|
||||||
void restore_buffer(buf_T *save_curbuf)
|
|
||||||
{
|
{
|
||||||
unblock_autocmds();
|
unblock_autocmds();
|
||||||
/* Check for valid buffer, just in case. */
|
// Check for valid buffer, just in case.
|
||||||
if (buf_valid(save_curbuf)) {
|
if (bufref_valid(save_curbuf)) {
|
||||||
--curbuf->b_nwindows;
|
curbuf->b_nwindows--;
|
||||||
curwin->w_buffer = save_curbuf;
|
curwin->w_buffer = save_curbuf->br_buf;
|
||||||
curbuf = save_curbuf;
|
curbuf = save_curbuf->br_buf;
|
||||||
++curbuf->b_nwindows;
|
curbuf->b_nwindows++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user