diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/buffer.c | 4 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 2 | ||||
-rw-r--r-- | src/nvim/testdir/test_autocmd.vim | 17 | ||||
-rw-r--r-- | src/nvim/window.c | 58 |
4 files changed, 53 insertions, 28 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 4ca752e747..bf592a626d 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -590,6 +590,10 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last) // Remove the buffer from the list. if (wipe_buf) { + // Do not wipe out the buffer if it is used in a window. + if (buf->b_nwindows > 0) { + return false; + } if (buf->b_sfname != buf->b_ffname) { XFREE_CLEAR(buf->b_sfname); } else { diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 0dbc9d6b14..20325509c4 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -6839,7 +6839,7 @@ void tabpage_close_other(tabpage_T *tp, int forceit) // Autocommands may delete the tab page under our fingers and we may // fail to close a window with a modified buffer. - if (!valid_tabpage(tp) || tp->tp_firstwin == wp) { + if (!valid_tabpage(tp) || tp->tp_lastwin == wp) { break; } } diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index d4005e41e8..76c69ad10b 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -2611,4 +2611,21 @@ func Test_autocmd_closing_cmdwin() only endfunc +func Test_bufwipeout_changes_window() + " This should not crash, but we don't have any expectations about what + " happens, changing window in BufWipeout has unpredictable results. + tabedit + let g:window_id = win_getid() + topleft new + setlocal bufhidden=wipe + autocmd BufWipeout <buffer> call win_gotoid(g:window_id) + tabprevious + +tabclose + + unlet g:window_id + au! BufWipeout + %bwipe! +endfunc + + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/window.c b/src/nvim/window.c index fa71a08b94..02b297bcef 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2350,6 +2350,30 @@ void entering_window(win_T *const win) } } +void win_init_empty(win_T *wp) +{ + redraw_later(wp, NOT_VALID); + wp->w_lines_valid = 0; + wp->w_cursor.lnum = 1; + wp->w_curswant = wp->w_cursor.col = 0; + wp->w_cursor.coladd = 0; + wp->w_pcmark.lnum = 1; // pcmark not cleared but set to line 1 + wp->w_pcmark.col = 0; + wp->w_prev_pcmark.lnum = 0; + wp->w_prev_pcmark.col = 0; + wp->w_topline = 1; + wp->w_topfill = 0; + wp->w_botline = 2; + wp->w_s = &wp->w_buffer->b_s; +} + +/// Init the current window "curwin". +/// Called when a new file is being edited. +void curwin_init(void) +{ + win_init_empty(curwin); +} + /// Closes all windows for buffer `buf` unless there is only one non-floating window. /// /// @param keep_curwin don't close `curwin` @@ -2867,6 +2891,13 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) for (ptp = first_tabpage; ptp != NULL && ptp != tp; ptp = ptp->tp_next) { } if (ptp == NULL || tp == curtab) { + // If the buffer was removed from the window we have to give it any + // buffer. + if (win_valid_any_tab(win) && win->w_buffer == NULL) { + win->w_buffer = firstbuf; + firstbuf->b_nwindows++; + win_init_empty(win); + } return; } @@ -3793,33 +3824,6 @@ void close_others(int message, int forceit) } } - -/* - * Init the current window "curwin". - * Called when a new file is being edited. - */ -void curwin_init(void) -{ - win_init_empty(curwin); -} - -void win_init_empty(win_T *wp) -{ - redraw_later(wp, NOT_VALID); - wp->w_lines_valid = 0; - wp->w_cursor.lnum = 1; - wp->w_curswant = wp->w_cursor.col = 0; - wp->w_cursor.coladd = 0; - wp->w_pcmark.lnum = 1; // pcmark not cleared but set to line 1 - wp->w_pcmark.col = 0; - wp->w_prev_pcmark.lnum = 0; - wp->w_prev_pcmark.col = 0; - wp->w_topline = 1; - wp->w_topfill = 0; - wp->w_botline = 2; - wp->w_s = &wp->w_buffer->b_s; -} - /* * Allocate the first window and put an empty buffer in it. * Called from main(). |