diff options
author | Grzegorz Milka <grzegorzmilka@gmail.com> | 2016-10-23 00:25:16 +0200 |
---|---|---|
committer | Grzegorz Milka <grzegorzmilka@gmail.com> | 2016-10-23 00:37:13 +0200 |
commit | c5c8a821341b71ae29786c97df7930a9581f7ab7 (patch) | |
tree | 8d7745d92badd0aa8c64662b5ad15b1ae69d2c3d | |
parent | d7b942b54e4bae5510549ceffb3280e89871cff5 (diff) | |
download | rneovim-c5c8a821341b71ae29786c97df7930a9581f7ab7.tar.gz rneovim-c5c8a821341b71ae29786c97df7930a9581f7ab7.tar.bz2 rneovim-c5c8a821341b71ae29786c97df7930a9581f7ab7.zip |
vim-patch:7.4.2309
Problem: Crash when doing tabnext in a BufUnload autocmd. (Dominique Pelle)
Solution: When detecting that the tab page changed, don't just abort but
delete the window where w_buffer is NULL.
https://github.com/vim/vim/commit/11fbc2866ccc11b4dd1726abdaf582a78ef3f743
-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. */ |