diff options
-rw-r--r-- | src/nvim/testdir/test_tabpage.vim | 14 | ||||
-rw-r--r-- | src/nvim/version.c | 2 | ||||
-rw-r--r-- | src/nvim/window.c | 32 |
3 files changed, 37 insertions, 11 deletions
diff --git a/src/nvim/testdir/test_tabpage.vim b/src/nvim/testdir/test_tabpage.vim index f1c41e967b..7bdea0b186 100644 --- a/src/nvim/testdir/test_tabpage.vim +++ b/src/nvim/testdir/test_tabpage.vim @@ -218,4 +218,18 @@ function Test_tabpage_with_tab_modifier() bw! endfunction +func Test_tabnext_on_buf_unload() + " This once caused a crash + new + tabedit + tabfirst + au BufUnload <buffer> tabnext + q + + while tabpagenr('$') > 1 + quit + endwhile +endfunc + + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/version.c b/src/nvim/version.c index fffd8e79de..f0f6f6a3cb 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -132,7 +132,7 @@ static int included_patches[] = { // 2312, // 2311, // 2310 NA - // 2309, + 2309, // 2308 NA // 2307, // 2306, diff --git a/src/nvim/window.c b/src/nvim/window.c index c4e48a9732..2fb1fbede9 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -1935,7 +1935,7 @@ int win_close(win_T *win, int free_buf) if (win->w_buffer != NULL) { win->w_closing = true; close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, true); - if (win_valid(win)) { + if (win_valid_any_tab(win)) { win->w_closing = false; } @@ -1955,11 +1955,19 @@ int win_close(win_T *win, int free_buf) curwin->w_buffer = curbuf; getout(0); } - /* Autocommands may have closed the window already, or closed the only - * other window or moved to another tab page. */ - else if (!win_valid(win) || last_window() || curtab != prev_curtab - || close_last_window_tabpage(win, free_buf, prev_curtab)) + // Autocommands may have moved to another tab page. + if (curtab != prev_curtab && win_valid_any_tab(win) + && win->w_buffer == NULL) { + // Need to close the window anyway, since the buffer is NULL. + win_close_othertab(win, false, prev_curtab); return FAIL; + } + // Autocommands may have closed the window already, or closed the only + // other window or moved to another tab page. + if (!win_valid(win) || last_window() + || close_last_window_tabpage(win, free_buf, prev_curtab)) { + return FAIL; + } // let terminal buffers know that this window dimensions may be ignored win->w_closing = true; @@ -2036,12 +2044,16 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) tabpage_T *ptp = NULL; int free_tp = FALSE; - assert(win->w_buffer); // to avoid np dereference warning in next line - if (win->w_closing || win->w_buffer->b_closing) - return; /* window is already being closed */ + // Get here with win->w_buffer == NULL when win_close() detects the tab page + // changed. + if (win->w_closing || (win->w_buffer != NULL && win->w_buffer->b_closing)) { + return; // window is already being closed + } - /* Close the link to the buffer. */ - close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, FALSE); + if (win->w_buffer != NULL) { + // Close the link to the buffer. + close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, FALSE); + } /* Careful: Autocommands may have closed the tab page or made it the * current tab page. */ |