diff options
-rw-r--r-- | src/nvim/buffer.c | 12 | ||||
-rw-r--r-- | src/nvim/window.c | 9 | ||||
-rw-r--r-- | test/old/testdir/test_autocmd.vim | 12 |
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 |