aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/buffer.c12
-rw-r--r--src/nvim/window.c9
-rw-r--r--test/old/testdir/test_autocmd.vim12
3 files changed, 30 insertions, 3 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 2ceed20768..f6c7229485 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -1584,6 +1584,7 @@ void set_curbuf(buf_T *buf, int action, bool update_jumplist)
int unload = (action == DOBUF_UNLOAD || action == DOBUF_DEL
|| action == DOBUF_WIPE);
OptInt old_tw = curbuf->b_p_tw;
+ const int last_winid = get_last_winid();
if (update_jumplist) {
setpcmark();
@@ -1612,7 +1613,11 @@ void set_curbuf(buf_T *buf, int action, bool update_jumplist)
if (prevbuf == curwin->w_buffer) {
reset_synblock(curwin);
}
- if (unload) {
+ // autocommands may have opened a new window
+ // with prevbuf, grr
+ if (unload
+ || (last_winid != get_last_winid()
+ && strchr("wdu", prevbuf->b_p_bh[0]) != NULL)) {
close_windows(prevbuf, false);
}
if (bufref_valid(&prevbufref) && !aborting()) {
@@ -1642,6 +1647,11 @@ void set_curbuf(buf_T *buf, int action, bool update_jumplist)
// If curwin->w_buffer is null, enter_buffer() will make it valid again
bool valid = buf_valid(buf);
if ((valid && buf != curbuf && !aborting()) || curwin->w_buffer == NULL) {
+ // autocommands changed curbuf and we will move to another
+ // buffer soon, so decrement curbuf->b_nwindows
+ if (curbuf != NULL && prevbuf != curbuf) {
+ curbuf->b_nwindows--;
+ }
// If the buffer is not valid but curwin->w_buffer is NULL we must
// enter some buffer. Using the last one is hopefully OK.
if (!valid) {
diff --git a/src/nvim/window.c b/src/nvim/window.c
index efaeeaa4c1..b631cbe7c8 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -4946,12 +4946,12 @@ win_T *buf_jump_open_tab(buf_T *buf)
return NULL;
}
+static int last_win_id = LOWEST_WIN_ID - 1;
+
/// @param hidden allocate a window structure and link it in the window if
// false.
win_T *win_alloc(win_T *after, bool hidden)
{
- static int last_win_id = LOWEST_WIN_ID - 1;
-
// allocate window structure and linesizes arrays
win_T *new_wp = xcalloc(1, sizeof(win_T));
@@ -7451,6 +7451,11 @@ skip:
return NULL; // no error
}
+int get_last_winid(void)
+{
+ return last_win_id;
+}
+
void win_get_tabwin(handle_T id, int *tabnr, int *winnr)
{
*tabnr = 0;
diff --git a/test/old/testdir/test_autocmd.vim b/test/old/testdir/test_autocmd.vim
index 6901627c17..4d88573a1f 100644
--- a/test/old/testdir/test_autocmd.vim
+++ b/test/old/testdir/test_autocmd.vim
@@ -3868,4 +3868,16 @@ func Test_autocmd_invalidates_undo_on_textchanged()
call StopVimInTerminal(buf)
endfunc
+func Test_autocmd_creates_new_buffer_on_bufleave()
+ e a.txt
+ e b.txt
+ setlocal bufhidden=wipe
+ autocmd BufLeave <buffer> diffsplit c.txt
+ bn
+ call assert_equal(1, winnr('$'))
+ call assert_equal('a.txt', bufname('%'))
+ bw a.txt
+ bw c.txt
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab