mirror of
https://github.com/neovim/neovim.git
synced 2026-04-30 03:04:13 +00:00
Merge pull request #37422 from zeertzjq/vim-9.1.0059
vim-patch:9.1.{0059,0117,0671,1043,partial:1110}: WinNewPre
This commit is contained in:
@@ -1232,6 +1232,20 @@ 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.
|
||||
Before WinClosed.
|
||||
*WinNewPre*
|
||||
WinNewPre Before creating a new window. Triggered
|
||||
before commands that modify window layout by
|
||||
creating a split.
|
||||
Not done when creating tab pages and for the
|
||||
first window, as the window structure is not
|
||||
initialized yet and so is generally not safe.
|
||||
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.
|
||||
|
||||
@@ -2580,7 +2580,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
|VimResized|,
|
||||
|VimResume|,
|
||||
|VimSuspend|,
|
||||
|WinNew|
|
||||
|WinNew|,
|
||||
|WinNewPre|
|
||||
|
||||
*'expandtab'* *'et'* *'noexpandtab'* *'noet'*
|
||||
'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'
|
||||
--- |'WinLeave'
|
||||
--- |'WinNew'
|
||||
--- |'WinNewPre'
|
||||
--- |'WinResized'
|
||||
--- |'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`,
|
||||
--- `VimResume`,
|
||||
--- `VimSuspend`,
|
||||
--- `WinNew`
|
||||
--- `WinNew`,
|
||||
--- `WinNewPre`
|
||||
---
|
||||
--- @type string
|
||||
vim.o.eventignorewin = ""
|
||||
|
||||
@@ -138,7 +138,8 @@ return {
|
||||
WinClosed = true, -- after closing a window
|
||||
WinEnter = true, -- after entering 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
|
||||
WinScrolled = true, -- after a window was scrolled or resized
|
||||
},
|
||||
|
||||
@@ -1127,6 +1127,10 @@ win_T *win_split_ins(int size, int flags, win_T *new_wp, int dir, frame_T *to_fl
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (new_wp == NULL) {
|
||||
trigger_winnewpre();
|
||||
}
|
||||
|
||||
win_T *oldwin;
|
||||
if (flags & WSP_TOP) {
|
||||
oldwin = firstwin;
|
||||
@@ -3069,6 +3073,13 @@ int win_close(win_T *win, bool free_buf, bool force)
|
||||
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)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
@@ -4351,6 +4362,10 @@ void free_tabpage(tabpage_T *tp)
|
||||
///
|
||||
/// It will edit the current buffer, like after :split.
|
||||
///
|
||||
/// Does not trigger WinNewPre, since the window structures
|
||||
/// are not completely setup yet and could cause dereferencing
|
||||
/// NULL pointers
|
||||
///
|
||||
/// @param after Put new tabpage after tabpage "after", or after the current
|
||||
/// tabpage in case of 0.
|
||||
/// @param filename Will be passed to apply_autocmds().
|
||||
|
||||
BIN
test/old/testdir/crash/nullpointer
Normal file
BIN
test/old/testdir/crash/nullpointer
Normal file
Binary file not shown.
@@ -276,7 +276,9 @@ endfunc
|
||||
func Test_win_tab_autocmd()
|
||||
let g:record = []
|
||||
|
||||
defer CleanUpTestAuGroup()
|
||||
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')
|
||||
@@ -293,7 +295,7 @@ func Test_win_tab_autocmd()
|
||||
close
|
||||
|
||||
call assert_equal([
|
||||
\ 'WinLeave', 'WinNew', 'WinEnter',
|
||||
\ 'WinNewPre', 'WinLeave', 'WinNew', 'WinEnter',
|
||||
\ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
|
||||
\ 'WinLeave', 'TabLeave', 'WinClosed', 'TabClosed', 'WinEnter', 'TabEnter',
|
||||
\ 'WinLeave', 'WinClosed', 'WinEnter'
|
||||
@@ -310,10 +312,81 @@ func Test_win_tab_autocmd()
|
||||
\ '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)
|
||||
|
||||
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
|
||||
defer CleanUpTestAuGroup()
|
||||
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])
|
||||
" not triggered for tabnew
|
||||
tabnew
|
||||
call assert_equal(2, len(g:layouts_pre))
|
||||
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
|
||||
unlet g:record
|
||||
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)
|
||||
unlet g:caught
|
||||
endfunc
|
||||
|
||||
func Test_WinResized()
|
||||
@@ -2820,7 +2893,8 @@ endfunc
|
||||
|
||||
func Test_autocmd_nested()
|
||||
let g:did_nested = 0
|
||||
augroup Testing
|
||||
defer CleanUpTestAuGroup()
|
||||
augroup testing
|
||||
au WinNew * edit somefile
|
||||
au BufNew * let g:did_nested = 1
|
||||
augroup END
|
||||
@@ -2830,7 +2904,7 @@ func Test_autocmd_nested()
|
||||
bwipe! somefile
|
||||
|
||||
" old nested argument still works
|
||||
augroup Testing
|
||||
augroup testing
|
||||
au!
|
||||
au WinNew * nested edit somefile
|
||||
au BufNew * let g:did_nested = 1
|
||||
@@ -4378,6 +4452,38 @@ func Test_BufEnter_botline()
|
||||
set hidden&vim
|
||||
endfunc
|
||||
|
||||
" those commands caused null pointer access, see #15464
|
||||
func Test_WinNewPre_crash()
|
||||
defer CleanUpTestAuGroup()
|
||||
let _cmdheight=&cmdheight
|
||||
augroup testing
|
||||
au!
|
||||
autocmd WinNewPre * redraw
|
||||
augroup END
|
||||
tabnew
|
||||
tabclose
|
||||
augroup testing
|
||||
au!
|
||||
autocmd WinNewPre * wincmd t
|
||||
augroup END
|
||||
tabnew
|
||||
tabclose
|
||||
augroup testing
|
||||
au!
|
||||
autocmd WinNewPre * wincmd b
|
||||
augroup END
|
||||
tabnew
|
||||
tabclose
|
||||
augroup testing
|
||||
au!
|
||||
autocmd WinNewPre * set cmdheight+=1
|
||||
augroup END
|
||||
tabnew
|
||||
tabclose
|
||||
let &cmdheight=_cmdheight
|
||||
endfunc
|
||||
|
||||
|
||||
" This was using freed memory
|
||||
func Test_autocmd_BufWinLeave_with_vsp()
|
||||
new
|
||||
|
||||
@@ -191,52 +191,49 @@ func Test_crash1_3()
|
||||
let buf = RunVimInTerminal('sh', #{cmd: 'sh'})
|
||||
|
||||
let file = 'crash/poc_ex_substitute'
|
||||
let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'\<cr>"
|
||||
let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
|
||||
let args = printf(cmn_args, vim, file)
|
||||
call term_sendkeys(buf, args)
|
||||
call TermWait(buf, 150)
|
||||
call s:RunCommandAndWait(buf, args)
|
||||
|
||||
let file = 'crash/poc_uaf_exec_instructions'
|
||||
let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'\<cr>"
|
||||
let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
|
||||
let args = printf(cmn_args, vim, file)
|
||||
call term_sendkeys(buf, args)
|
||||
call TermWait(buf, 150)
|
||||
call s:RunCommandAndWait(buf, args)
|
||||
|
||||
let file = 'crash/poc_uaf_check_argument_types'
|
||||
let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'\<cr>"
|
||||
let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
|
||||
let args = printf(cmn_args, vim, file)
|
||||
call term_sendkeys(buf, args)
|
||||
call TermWait(buf, 150)
|
||||
call s:RunCommandAndWait(buf, args)
|
||||
|
||||
let file = 'crash/double_free'
|
||||
let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'\<cr>"
|
||||
let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
|
||||
let args = printf(cmn_args, vim, file)
|
||||
call term_sendkeys(buf, args)
|
||||
call TermWait(buf, 50)
|
||||
call s:RunCommandAndWait(buf, args)
|
||||
|
||||
let file = 'crash/dialog_changed_uaf'
|
||||
let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'\<cr>"
|
||||
let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
|
||||
let args = printf(cmn_args, vim, file)
|
||||
call term_sendkeys(buf, args)
|
||||
call TermWait(buf, 150)
|
||||
call s:RunCommandAndWait(buf, args)
|
||||
|
||||
let file = 'crash/nullpointer'
|
||||
let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
|
||||
let args = printf(cmn_args, vim, file)
|
||||
call s:RunCommandAndWait(buf, args)
|
||||
|
||||
let file = 'crash/heap_overflow3'
|
||||
let cmn_args = "%s -u NONE -i NONE -n -X -m -n -e -s -S %s -c ':qa!'"
|
||||
let args = printf(cmn_args, vim, file)
|
||||
call term_sendkeys(buf, args)
|
||||
call TermWait(buf, 150)
|
||||
call s:RunCommandAndWait(buf, args)
|
||||
|
||||
let file = 'crash/heap_overflow_glob2regpat'
|
||||
let cmn_args = "%s -u NONE -i NONE -n -X -m -n -e -s -S %s -c ':qa!'"
|
||||
let args = printf(cmn_args, vim, file)
|
||||
call term_sendkeys(buf, args)
|
||||
call TermWait(buf, 50)
|
||||
call s:RunCommandAndWait(buf, args)
|
||||
|
||||
let file = 'crash/nullptr_regexp_nfa'
|
||||
let cmn_args = "%s -u NONE -i NONE -n -X -m -n -e -s -S %s -c ':qa!'"
|
||||
let args = printf(cmn_args, vim, file)
|
||||
call term_sendkeys(buf, args)
|
||||
call TermWait(buf, 50)
|
||||
call s:RunCommandAndWait(buf, args)
|
||||
|
||||
" clean up
|
||||
exe buf .. "bw!"
|
||||
|
||||
@@ -1043,8 +1043,7 @@ func Test_win_splitmove()
|
||||
let s:triggered = []
|
||||
augroup WinSplitMove
|
||||
au!
|
||||
" Nvim: WinNewPre not ported yet. Also needs full port of v9.1.0117 to pass.
|
||||
" au WinNewPre * let s:triggered += ['WinNewPre']
|
||||
au WinNewPre * let s:triggered += ['WinNewPre']
|
||||
au WinNew * let s:triggered += ['WinNew', win_getid()]
|
||||
au WinClosed * let s:triggered += ['WinClosed', str2nr(expand('<afile>'))]
|
||||
augroup END
|
||||
|
||||
Reference in New Issue
Block a user