mirror of
https://github.com/neovim/neovim.git
synced 2026-04-26 09:14:15 +00:00
vim-patch:9.1.0059: No event triggered before creating a window
Problem: No event is triggered before creating a window.
(Sergey Vlasov)
Solution: Add the WinNewPre event (Sergey Vlasov)
fixes: vim/vim#10635
closes: vim/vim#12761
1f47db75fd
Not sure if this should be triggered before creating a floating window,
as its use case is related to window layout.
Co-authored-by: Sergey Vlasov <sergey@vlasov.me>
This commit is contained in:
@@ -1232,6 +1232,18 @@ WinLeave Before leaving a window. If the window to be
|
|||||||
WinLeave autocommands (but not for ":new").
|
WinLeave autocommands (but not for ":new").
|
||||||
Not used for ":qa" or ":q" when exiting Vim.
|
Not used for ":qa" or ":q" when exiting Vim.
|
||||||
Before WinClosed.
|
Before WinClosed.
|
||||||
|
*WinNewPre*
|
||||||
|
WinNewPre Before creating a new window. Triggered
|
||||||
|
before commands that modify window layout by
|
||||||
|
creating a split or new tab page. Not done for
|
||||||
|
the first window, when Vim has just started.
|
||||||
|
It is not allowed to modify window layout
|
||||||
|
while executing commands for the WinNewPre
|
||||||
|
event.
|
||||||
|
Most useful to store current window layout
|
||||||
|
and compare it with the new layout after the
|
||||||
|
Window has been created.
|
||||||
|
|
||||||
*WinNew*
|
*WinNew*
|
||||||
WinNew When a new window was created. Not done for
|
WinNew When a new window was created. Not done for
|
||||||
the first window, when Vim has just started.
|
the first window, when Vim has just started.
|
||||||
|
|||||||
@@ -2580,7 +2580,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
|VimResized|,
|
|VimResized|,
|
||||||
|VimResume|,
|
|VimResume|,
|
||||||
|VimSuspend|,
|
|VimSuspend|,
|
||||||
|WinNew|
|
|WinNew|,
|
||||||
|
|WinNewPre|
|
||||||
|
|
||||||
*'expandtab'* *'et'* *'noexpandtab'* *'noet'*
|
*'expandtab'* *'et'* *'noexpandtab'* *'noet'*
|
||||||
'expandtab' 'et' boolean (default off)
|
'expandtab' 'et' boolean (default off)
|
||||||
|
|||||||
1
runtime/lua/vim/_meta/api_keysets.lua
generated
1
runtime/lua/vim/_meta/api_keysets.lua
generated
@@ -218,6 +218,7 @@ error('Cannot require a meta file')
|
|||||||
--- |'WinEnter'
|
--- |'WinEnter'
|
||||||
--- |'WinLeave'
|
--- |'WinLeave'
|
||||||
--- |'WinNew'
|
--- |'WinNew'
|
||||||
|
--- |'WinNewPre'
|
||||||
--- |'WinResized'
|
--- |'WinResized'
|
||||||
--- |'WinScrolled'
|
--- |'WinScrolled'
|
||||||
|
|
||||||
|
|||||||
3
runtime/lua/vim/_meta/options.lua
generated
3
runtime/lua/vim/_meta/options.lua
generated
@@ -2258,7 +2258,8 @@ vim.go.ei = vim.go.eventignore
|
|||||||
--- `VimResized`,
|
--- `VimResized`,
|
||||||
--- `VimResume`,
|
--- `VimResume`,
|
||||||
--- `VimSuspend`,
|
--- `VimSuspend`,
|
||||||
--- `WinNew`
|
--- `WinNew`,
|
||||||
|
--- `WinNewPre`
|
||||||
---
|
---
|
||||||
--- @type string
|
--- @type string
|
||||||
vim.o.eventignorewin = ""
|
vim.o.eventignorewin = ""
|
||||||
|
|||||||
@@ -138,7 +138,8 @@ return {
|
|||||||
WinClosed = true, -- after closing a window
|
WinClosed = true, -- after closing a window
|
||||||
WinEnter = true, -- after entering a window
|
WinEnter = true, -- after entering a window
|
||||||
WinLeave = true, -- before leaving a window
|
WinLeave = true, -- before leaving a window
|
||||||
WinNew = false, -- when entering a new window
|
WinNewPre = false, -- before creating a new window
|
||||||
|
WinNew = false, -- after creating a new window
|
||||||
WinResized = true, -- after a window was resized
|
WinResized = true, -- after a window was resized
|
||||||
WinScrolled = true, -- after a window was scrolled or resized
|
WinScrolled = true, -- after a window was scrolled or resized
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1127,6 +1127,8 @@ win_T *win_split_ins(int size, int flags, win_T *new_wp, int dir, frame_T *to_fl
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trigger_winnewpre();
|
||||||
|
|
||||||
win_T *oldwin;
|
win_T *oldwin;
|
||||||
if (flags & WSP_TOP) {
|
if (flags & WSP_TOP) {
|
||||||
oldwin = firstwin;
|
oldwin = firstwin;
|
||||||
@@ -3069,6 +3071,13 @@ int win_close(win_T *win, bool free_buf, bool force)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void trigger_winnewpre(void)
|
||||||
|
{
|
||||||
|
window_layout_lock();
|
||||||
|
apply_autocmds(EVENT_WINNEWPRE, NULL, NULL, false, NULL);
|
||||||
|
window_layout_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
static void do_autocmd_winclosed(win_T *win)
|
static void do_autocmd_winclosed(win_T *win)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
@@ -4380,6 +4389,8 @@ int win_new_tabpage(int after, char *filename)
|
|||||||
|
|
||||||
curtab = newtp;
|
curtab = newtp;
|
||||||
|
|
||||||
|
trigger_winnewpre();
|
||||||
|
|
||||||
// Create a new empty window.
|
// Create a new empty window.
|
||||||
if (win_alloc_firstwin(old_curtab->tp_curwin) == OK) {
|
if (win_alloc_firstwin(old_curtab->tp_curwin) == OK) {
|
||||||
// Make the new Tab page the new topframe.
|
// Make the new Tab page the new topframe.
|
||||||
|
|||||||
@@ -277,6 +277,7 @@ func Test_win_tab_autocmd()
|
|||||||
let g:record = []
|
let g:record = []
|
||||||
|
|
||||||
augroup testing
|
augroup testing
|
||||||
|
au WinNewPre * call add(g:record, 'WinNewPre')
|
||||||
au WinNew * call add(g:record, 'WinNew')
|
au WinNew * call add(g:record, 'WinNew')
|
||||||
au WinClosed * call add(g:record, 'WinClosed')
|
au WinClosed * call add(g:record, 'WinClosed')
|
||||||
au WinEnter * call add(g:record, 'WinEnter')
|
au WinEnter * call add(g:record, 'WinEnter')
|
||||||
@@ -293,8 +294,8 @@ func Test_win_tab_autocmd()
|
|||||||
close
|
close
|
||||||
|
|
||||||
call assert_equal([
|
call assert_equal([
|
||||||
\ 'WinLeave', 'WinNew', 'WinEnter',
|
\ 'WinNewPre', 'WinLeave', 'WinNew', 'WinEnter',
|
||||||
\ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
|
\ 'WinLeave', 'TabLeave', 'WinNewPre', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
|
||||||
\ 'WinLeave', 'TabLeave', 'WinClosed', 'TabClosed', 'WinEnter', 'TabEnter',
|
\ 'WinLeave', 'TabLeave', 'WinClosed', 'TabClosed', 'WinEnter', 'TabEnter',
|
||||||
\ 'WinLeave', 'WinClosed', 'WinEnter'
|
\ 'WinLeave', 'WinClosed', 'WinEnter'
|
||||||
\ ], g:record)
|
\ ], g:record)
|
||||||
@@ -305,17 +306,96 @@ func Test_win_tab_autocmd()
|
|||||||
bwipe somefile
|
bwipe somefile
|
||||||
|
|
||||||
call assert_equal([
|
call assert_equal([
|
||||||
\ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
|
\ 'WinLeave', 'TabLeave', 'WinNewPre', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
|
||||||
\ 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter',
|
\ 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter',
|
||||||
\ 'WinClosed', 'TabClosed'
|
\ 'WinClosed', 'TabClosed'
|
||||||
\ ], g:record)
|
\ ], 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
|
augroup testing
|
||||||
au!
|
au!
|
||||||
augroup END
|
augroup END
|
||||||
unlet g:record
|
unlet g:record
|
||||||
endfunc
|
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()
|
func Test_WinResized()
|
||||||
CheckRunVimInTerminal
|
CheckRunVimInTerminal
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user