aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/buffer.c10
-rw-r--r--src/nvim/buffer_defs.h2
-rw-r--r--src/nvim/ex_getln.c1
-rw-r--r--src/nvim/testdir/test_autocmd.vim11
-rw-r--r--src/nvim/window.c14
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.