0
0
mirror of https://github.com/vim/vim.git synced 2025-07-24 10:45:12 -04:00

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: #10635
closes: #12761

Signed-off-by: Sergey Vlasov <sergey@vlasov.me>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Sergey Vlasov 2024-01-25 23:07:00 +01:00 committed by Christian Brabandt
parent 92e90a1e10
commit 1f47db75fd
No known key found for this signature in database
GPG Key ID: F3F92DA383FDDE09
9 changed files with 119 additions and 7 deletions

View File

@ -1,4 +1,4 @@
*autocmd.txt* For Vim version 9.1. Last change: 2024 Jan 23
*autocmd.txt* For Vim version 9.1. Last change: 2024 Jan 25
VIM REFERENCE MANUAL by Bram Moolenaar
@ -381,6 +381,7 @@ Name triggered by ~
|CursorMoved| the cursor was moved in Normal mode
|CursorMovedI| the cursor was moved in Insert mode
|WinNewPre| before creating a new window
|WinNew| after creating a new window
|TabNew| after creating a new tab page
|WinClosed| after closing a window
@ -1390,6 +1391,18 @@ WinLeave Before leaving a window. If the window to be
WinLeave autocommands (but not for ":new").
Not used for ":qa" or ":q" when exiting Vim.
*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 When a new window was created. Not done for
the first window, when Vim has just started.

View File

@ -5785,6 +5785,7 @@ WinClosed autocmd.txt /*WinClosed*
WinEnter autocmd.txt /*WinEnter*
WinLeave autocmd.txt /*WinLeave*
WinNew autocmd.txt /*WinNew*
WinNewPre autocmd.txt /*WinNewPre*
WinResized autocmd.txt /*WinResized*
WinResized-event windows.txt /*WinResized-event*
WinScrolled autocmd.txt /*WinScrolled*

View File

@ -4667,7 +4667,6 @@ GUI:
Autocommands:
9 Add WinNewPre - before creating a new window. #10635
9 When triggering WinNew provide the window ID somehow. #10633
9 Rework the code from FEAT_OSFILETYPE for autocmd-osfiletypes to use
'filetype'. Only for when the current buffer is known.

View File

@ -11,6 +11,7 @@
" 2024 Jan 14 by Vim Project (TermResponseAll autocommand)
" 2024 Jan 15 by Vim Project (:hi ctermfont attribute)
" 2024 Jan 23 by Vim Project (add :[23]match commands)
" 2024 Jan 25 by Vim Project (WinNewPre autocommand)
" Version: 9.0-25
" URL: http://www.drchip.org/astronaut/vim/index.html#SYNTAX_VIM
" Automatically generated keyword lists: {{{1
@ -76,7 +77,7 @@ syn keyword vimErrSetting contained bioskey biosk conskey consk autoprint beauti
" AutoCmd Events {{{2
syn case ignore
syn keyword vimAutoEvent contained BufAdd BufDelete BufFilePost BufHidden BufNew BufRead BufReadPost BufUnload BufWinLeave BufWrite BufWritePost CmdlineChanged CmdlineLeave CmdwinEnter ColorScheme CompleteChanged CompleteDonePre CursorHoldI CursorMovedI DiffUpdated DirChanged DirChangedPre EncodingChanged ExitPre FileAppendCmd FileAppendPost FileAppendPre FileChangedRO FileChangedShell FileChangedShellPost FileEncoding FileExplorer FileReadCmd FileReadPost FileReadPre FileType FileWriteCmd FileWritePost FileWritePre FilterReadPost FilterReadPre FilterWritePost FilterWritePre FocusGained FocusLost FuncUndefined GUIEnter GUIFailed InsertChange InsertCharPre InsertEnter InsertLeave InsertLeavePre MenuPopup ModeChanged OptionSet QuickFixCmdPost QuickFixCmdPre QuitPre RemoteReply SafeState SafeStateAgain SessionLoadPost ShellCmdPost ShellFilterPost SigUSR1 SourceCmd SourcePost SourcePre SpellFileMissing StdinReadPost StdinReadPre SwapExists Syntax TabClosed TabEnter TabLeave TabNew TermChanged TerminalOpen TerminalWinOpen TermResponse TermResponseAll TextChanged TextChangedI TextChangedP TextChangedT TextYankPost User VimEnter VimLeave VimLeavePre VimResized VimResume VimSuspend WinClosed WinEnter WinLeave WinNew WinResized WinScrolled
syn keyword vimAutoEvent contained BufAdd BufDelete BufFilePost BufHidden BufNew BufRead BufReadPost BufUnload BufWinLeave BufWrite BufWritePost CmdlineChanged CmdlineLeave CmdwinEnter ColorScheme CompleteChanged CompleteDonePre CursorHoldI CursorMovedI DiffUpdated DirChanged DirChangedPre EncodingChanged ExitPre FileAppendCmd FileAppendPost FileAppendPre FileChangedRO FileChangedShell FileChangedShellPost FileEncoding FileExplorer FileReadCmd FileReadPost FileReadPre FileType FileWriteCmd FileWritePost FileWritePre FilterReadPost FilterReadPre FilterWritePost FilterWritePre FocusGained FocusLost FuncUndefined GUIEnter GUIFailed InsertChange InsertCharPre InsertEnter InsertLeave InsertLeavePre MenuPopup ModeChanged OptionSet QuickFixCmdPost QuickFixCmdPre QuitPre RemoteReply SafeState SafeStateAgain SessionLoadPost ShellCmdPost ShellFilterPost SigUSR1 SourceCmd SourcePost SourcePre SpellFileMissing StdinReadPost StdinReadPre SwapExists Syntax TabClosed TabEnter TabLeave TabNew TermChanged TerminalOpen TerminalWinOpen TermResponse TermResponseAll TextChanged TextChangedI TextChangedP TextChangedT TextYankPost User VimEnter VimLeave VimLeavePre VimResized VimResume VimSuspend WinClosed WinEnter WinLeave WinNewPre WinNew WinResized WinScrolled
syn keyword vimAutoEvent contained BufCreate BufEnter BufFilePre BufLeave BufNewFile BufReadCmd BufReadPre BufWinEnter BufWipeout BufWriteCmd BufWritePre CmdlineEnter CmdUndefined CmdwinLeave ColorSchemePre CompleteDone CursorHold CursorMoved
" Highlight commonly used Groupnames {{{2

View File

@ -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},

View File

@ -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

View File

@ -704,6 +704,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
59,
/**/
58,
/**/

View File

@ -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

View File

@ -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)
@ -2886,6 +2889,14 @@ win_close(win_T *win, int free_buf)
return OK;
}
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)
{
@ -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)
{