summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSergey Vlasov <sergey@vlasov.me>2024-01-25 23:07:00 +0100
committerChristian Brabandt <cb@256bit.org>2024-01-25 23:07:00 +0100
commit1f47db75fdc8c53c5c778b26ecfa0942ac801f22 (patch)
tree3e08bda69c9a77e744431b723f6e50fb74b06955 /src
parent92e90a1e102825aa9149262cacfc991264db05df (diff)
patch 9.1.0059: No event triggered before creating a windowv9.1.0059
Problem: No event is triggered before creating a window. (Sergey Vlasov) Solution: Add the WinNewPre event (Sergey Vlasov) fixes: #10635 closes: #12761 Signed-off-by: Sergey Vlasov <sergey@vlasov.me> Signed-off-by: Christian Brabandt <cb@256bit.org>
Diffstat (limited to 'src')
-rw-r--r--src/autocmd.c1
-rw-r--r--src/testdir/test_autocmd.vim86
-rw-r--r--src/version.c2
-rw-r--r--src/vim.h3
-rw-r--r--src/window.c14
5 files changed, 102 insertions, 4 deletions
diff --git a/src/autocmd.c b/src/autocmd.c
index 80ce8ca6c8..7e4a1b211f 100644
--- a/src/autocmd.c
+++ b/src/autocmd.c
@@ -188,6 +188,7 @@ static struct event_name
{"VimEnter", EVENT_VIMENTER},
{"VimLeave", EVENT_VIMLEAVE},
{"VimLeavePre", EVENT_VIMLEAVEPRE},
+ {"WinNewPre", EVENT_WINNEWPRE},
{"WinNew", EVENT_WINNEW},
{"WinClosed", EVENT_WINCLOSED},
{"WinEnter", EVENT_WINENTER},
diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index cecb55aaf9..be73c18197 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -270,6 +270,7 @@ func Test_win_tab_autocmd()
let g:record = []
augroup testing
+ au WinNewPre * call add(g:record, 'WinNewPre')
au WinNew * call add(g:record, 'WinNew')
au WinClosed * call add(g:record, 'WinClosed')
au WinEnter * call add(g:record, 'WinEnter')
@@ -286,8 +287,8 @@ func Test_win_tab_autocmd()
close
call assert_equal([
- \ 'WinLeave', 'WinNew', 'WinEnter',
- \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
+ \ 'WinNewPre', 'WinLeave', 'WinNew', 'WinEnter',
+ \ 'WinLeave', 'TabLeave', 'WinNewPre', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
\ 'WinLeave', 'TabLeave', 'WinClosed', 'TabClosed', 'WinEnter', 'TabEnter',
\ 'WinLeave', 'WinClosed', 'WinEnter'
\ ], g:record)
@@ -298,17 +299,96 @@ func Test_win_tab_autocmd()
bwipe somefile
call assert_equal([
- \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
+ \ 'WinLeave', 'TabLeave', 'WinNewPre', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
\ 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter',
\ 'WinClosed', 'TabClosed'
\ ], g:record)
+ let g:record = []
+ copen
+ help
+ tabnext
+ vnew
+
+ call assert_equal([
+ \ 'WinNewPre', 'WinLeave', 'WinNew', 'WinEnter',
+ \ 'WinNewPre', 'WinLeave', 'WinNew', 'WinEnter',
+ \ 'WinNewPre', 'WinLeave', 'WinNew', 'WinEnter'
+ \ ], g:record)
+
augroup testing
au!
augroup END
unlet g:record
endfunc
+func Test_WinNewPre()
+ " Test that the old window layout can be accessed before a new window is created.
+ let g:layouts_pre = []
+ let g:layouts_post = []
+ augroup testing
+ au WinNewPre * call add(g:layouts_pre, winlayout())
+ au WinNew * call add(g:layouts_post, winlayout())
+ augroup END
+ split
+ call assert_notequal(g:layouts_pre[0], g:layouts_post[0])
+ split
+ call assert_equal(g:layouts_pre[1], g:layouts_post[0])
+ call assert_notequal(g:layouts_pre[1], g:layouts_post[1])
+ tabnew
+ call assert_notequal(g:layouts_pre[2], g:layouts_post[1])
+ call assert_notequal(g:layouts_pre[2], g:layouts_post[2])
+ augroup testing
+ au!
+ augroup END
+ unlet g:layouts_pre
+ unlet g:layouts_post
+
+ " Test modifying window layout during WinNewPre throws.
+ let g:caught = 0
+ augroup testing
+ au!
+ au WinNewPre * split
+ augroup END
+ try
+ vnew
+ catch
+ let g:caught += 1
+ endtry
+ augroup testing
+ au!
+ au WinNewPre * tabnew
+ augroup END
+ try
+ vnew
+ catch
+ let g:caught += 1
+ endtry
+ augroup testing
+ au!
+ au WinNewPre * close
+ augroup END
+ try
+ vnew
+ catch
+ let g:caught += 1
+ endtry
+ augroup testing
+ au!
+ au WinNewPre * tabclose
+ augroup END
+ try
+ vnew
+ catch
+ let g:caught += 1
+ endtry
+ call assert_equal(4, g:caught)
+ augroup testing
+ au!
+ augroup END
+ unlet g:caught
+endfunc
+
func Test_WinResized()
CheckRunVimInTerminal
diff --git a/src/version.c b/src/version.c
index 10a70e3c01..841d0182fc 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 59,
+/**/
58,
/**/
57,
diff --git a/src/vim.h b/src/vim.h
index 0f52ba217d..fe239581af 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -1435,7 +1435,8 @@ enum auto_event
EVENT_VIMRESIZED, // after Vim window was resized
EVENT_WINENTER, // after entering a window
EVENT_WINLEAVE, // before leaving a window
- EVENT_WINNEW, // when entering a new window
+ EVENT_WINNEWPRE, // before creating a new window
+ EVENT_WINNEW, // after creating a new window
EVENT_WINCLOSED, // after closing a window
EVENT_VIMSUSPEND, // before Vim is suspended
EVENT_VIMRESUME, // after Vim is resumed
diff --git a/src/window.c b/src/window.c
index fda42e924c..5cb6c3cd9a 100644
--- a/src/window.c
+++ b/src/window.c
@@ -19,6 +19,7 @@ static void win_exchange(long);
static void win_rotate(int, int);
static void win_totop(int size, int flags);
static void win_equal_rec(win_T *next_curwin, int current, frame_T *topfr, int dir, int col, int row, int width, int height);
+static void trigger_winnewpre(void);
static void trigger_winclosed(win_T *win);
static win_T *win_free_mem(win_T *win, int *dirp, tabpage_T *tp);
static frame_T *win_altframe(win_T *win, tabpage_T *tp);
@@ -955,6 +956,8 @@ win_split_ins(
// Do not redraw here, curwin->w_buffer may be invalid.
++RedrawingDisabled;
+ trigger_winnewpre();
+
if (flags & WSP_TOP)
oldwin = firstwin;
else if (flags & WSP_BOT)
@@ -2887,6 +2890,14 @@ win_close(win_T *win, int free_buf)
}
static void
+trigger_winnewpre(void)
+{
+ window_layout_lock();
+ apply_autocmds(EVENT_WINNEWPRE, NULL, NULL, FALSE, NULL);
+ window_layout_unlock();
+}
+
+ static void
trigger_winclosed(win_T *win)
{
static int recursive = FALSE;
@@ -4477,6 +4488,9 @@ win_new_tabpage(int after)
newtp->tp_localdir = (tp->tp_localdir == NULL)
? NULL : vim_strsave(tp->tp_localdir);
+
+ trigger_winnewpre();
+
// Create a new empty window.
if (win_alloc_firstwin(tp->tp_curwin) == OK)
{