diff options
-rw-r--r-- | src/nvim/buffer.c | 10 | ||||
-rw-r--r-- | src/nvim/buffer_defs.h | 2 | ||||
-rw-r--r-- | src/nvim/ex_getln.c | 1 | ||||
-rw-r--r-- | src/nvim/testdir/test_autocmd.vim | 11 | ||||
-rw-r--r-- | src/nvim/window.c | 14 |
5 files changed, 26 insertions, 12 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 78426568b4..628e398fd4 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -466,6 +466,7 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i // When the buffer is no longer in a window, trigger BufWinLeave if (buf->b_nwindows == 1) { buf->b_locked++; + buf->b_locked_split++; if (apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname, false, buf) && !bufref_valid(&bufref)) { // Autocommands deleted the buffer. @@ -473,6 +474,7 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i return false; } buf->b_locked--; + buf->b_locked_split--; if (abort_if_last && last_nonfloat(win)) { // Autocommands made this the only window. emsg(_(e_auabort)); @@ -483,6 +485,7 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i // BufHidden if (!unload_buf) { buf->b_locked++; + buf->b_locked_split++; if (apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname, false, buf) && !bufref_valid(&bufref)) { // Autocommands deleted the buffer. @@ -490,6 +493,7 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i return false; } buf->b_locked--; + buf->b_locked_split--; if (abort_if_last && last_nonfloat(win)) { // Autocommands made this the only window. emsg(_(e_auabort)); @@ -678,6 +682,7 @@ void buf_freeall(buf_T *buf, int flags) // Make sure the buffer isn't closed by autocommands. buf->b_locked++; + buf->b_locked_split++; bufref_T bufref; set_bufref(&bufref, buf); @@ -703,6 +708,7 @@ void buf_freeall(buf_T *buf, int flags) return; } buf->b_locked--; + buf->b_locked_split--; // If the buffer was in curwin and the window has changed, go back to that // window, if it still exists. This avoids that ":edit x" triggering a @@ -1466,8 +1472,8 @@ void set_curbuf(buf_T *buf, int action) set_bufref(&prevbufref, prevbuf); set_bufref(&newbufref, buf); - // Autocommands may delete the current buffer and/or the buffer we want to go - // to. In those cases don't close the buffer. + // Autocommands may delete the current buffer and/or the buffer we want to + // go to. In those cases don't close the buffer. if (!apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf) || (bufref_valid(&prevbufref) && bufref_valid(&newbufref) && !aborting())) { diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 4917a628ff..baa0d1f102 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -532,6 +532,8 @@ struct file_buffer { int b_flags; // various BF_ flags int b_locked; // Buffer is being closed or referenced, don't // let autocommands wipe it out. + int b_locked_split; // Buffer is being closed, don't allow opening + // a new window with it. int b_ro_locked; // Non-zero when the buffer can't be changed. // Used for FileChangedRO diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 91e93a236a..b7d75855d6 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -6376,6 +6376,7 @@ static int open_cmdwin(void) // Create a window for the command-line buffer. if (win_split((int)p_cwh, WSP_BOT) == FAIL) { beep_flush(); + ga_clear(&winsizes); return K_IGNORE; } cmdwin_type = get_cmdline_type(); diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index b80b564470..7320750cab 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -2717,17 +2717,14 @@ endfunc " Fuzzer found some strange combination that caused a crash. func Test_autocmd_normal_mess() - " TODO: why does this hang on Windows? - CheckNotMSWindows - augroup aucmd_normal_test au BufLeave,BufWinLeave,BufHidden,BufUnload,BufDelete,BufWipeout * norm 7q/qc augroup END " Nvim has removed :open - " o4 - e4 + " call assert_fails('o4', 'E1159') + call assert_fails('e4', 'E1159') silent! H - e xx + call assert_fails('e xx', 'E1159') normal G augroup aucmd_normal_test @@ -2749,7 +2746,7 @@ func Test_autocmd_vimgrep() au QuickfixCmdPre,BufNew,BufDelete,BufReadCmd * sb au QuickfixCmdPre,BufNew,BufDelete,BufReadCmd * q9 augroup END - " TODO: if this is executed directly valgrind reports errors + %bwipe! call assert_fails('lv?a?', 'E926:') augroup aucmd_vimgrep diff --git a/src/nvim/window.c b/src/nvim/window.c index d1cc5f245a..f68cfe4c9c 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -72,6 +72,9 @@ typedef enum { WEE_TRIGGER_LEAVE_AUTOCMDS = 0x10, } wee_flags_T; +static char e_cannot_split_window_when_closing_buffer[] + = N_("E1159: Cannot split a window when closing the buffer"); + static char *m_onlyone = N_("Already only one window"); /// When non-zero splitting a window is forbidden. Used to avoid that nasty @@ -946,6 +949,10 @@ static int check_split_disallowed(void) emsg(_("E242: Can't split a window while closing another")); return FAIL; } + if (curwin->w_buffer->b_locked_split) { + emsg(_(e_cannot_split_window_when_closing_buffer)); + return FAIL; + } return OK; } @@ -966,6 +973,10 @@ static int check_split_disallowed(void) */ int win_split(int size, int flags) { + if (check_split_disallowed() == FAIL) { + return FAIL; + } + // When the ":tab" modifier was used open a new tab page instead. if (may_open_tabpage() == OK) { return OK; @@ -977,9 +988,6 @@ int win_split(int size, int flags) emsg(_("E442: Can't split topleft and botright at the same time")); return FAIL; } - if (check_split_disallowed() == FAIL) { - return FAIL; - } // When creating the help window make a snapshot of the window layout. // Otherwise clear the snapshot, it's now invalid. |