vim-patch:partial:9.1.0117: Stop split-moving from firing WinNew and WinNewPre autocommands

Problem:  win_splitmove fires WinNewPre and possibly WinNew when moving
          windows, even though no new windows are created.
Solution: don't fire WinNew and WinNewPre when inserting an existing
          window, even if it isn't the current window. Improve the
          accuracy of related documentation. (Sean Dewar)

96cc4aef3d

Partial as WinNewPre has not been ported yet (it currently has problems anyway).
This commit is contained in:
Sean Dewar 2024-02-24 23:18:50 +00:00
parent 66f331fef7
commit 24dfa47e4f
No known key found for this signature in database
GPG Key ID: 08CC2C83AD41B581
6 changed files with 47 additions and 29 deletions

View File

@ -8901,10 +8901,10 @@ win_screenpos({nr}) *win_screenpos()*
tabpage.
win_splitmove({nr}, {target} [, {options}]) *win_splitmove()*
Move the window {nr} to a new split of the window {target}.
This is similar to moving to {target}, creating a new window
using |:split| but having the same contents as window {nr}, and
then closing {nr}.
Temporarily switch to window {target}, then move window {nr}
to a new split adjacent to {target}.
Unlike commands such as |:split|, no new windows are created
(the |window-ID| of window {nr} is unchanged after the move).
Both {nr} and {target} can be window numbers or |window-ID|s.
Both must be in the current tab page.

View File

@ -502,35 +502,33 @@ horizontally split windows. CTRL-W H does it the other way around.
*CTRL-W_K*
CTRL-W K Move the current window to be at the very top, using the full
width of the screen. This works like closing the current
window and then creating another one with ":topleft split",
except that the current window contents is used for the new
window.
width of the screen. This works like `:topleft split`, except
it is applied to the current window and no new window is
created.
*CTRL-W_J*
CTRL-W J Move the current window to be at the very bottom, using the
full width of the screen. This works like closing the current
window and then creating another one with ":botright split",
except that the current window contents is used for the new
window.
full width of the screen. This works like `:botright split`,
except it is applied to the current window and no new window
is created.
*CTRL-W_H*
CTRL-W H Move the current window to be at the far left, using the
full height of the screen. This works like closing the
current window and then creating another one with
`:vert topleft split`, except that the current window contents
is used for the new window.
full height of the screen. This works like
`:vert topleft split`, except it is applied to the current
window and no new window is created.
*CTRL-W_L*
CTRL-W L Move the current window to be at the far right, using the full
height of the screen. This works like closing the
current window and then creating another one with
`:vert botright split`, except that the current window
contents is used for the new window.
height of the screen. This works like `:vert botright split`,
except it is applied to the current window and no new window
is created.
*CTRL-W_T*
CTRL-W T Move the current window to a new tab page. This fails if
there is only one window in the current tab page.
This works like `:tab split`, except the previous window is
closed.
When a count is specified the new tab page will be opened
before the tab page with this index. Otherwise it comes after
the current tab page.

View File

@ -10598,10 +10598,10 @@ function vim.fn.win_move_statusline(nr, offset) end
--- @return any
function vim.fn.win_screenpos(nr) end
--- Move the window {nr} to a new split of the window {target}.
--- This is similar to moving to {target}, creating a new window
--- using |:split| but having the same contents as window {nr}, and
--- then closing {nr}.
--- Temporarily switch to window {target}, then move window {nr}
--- to a new split adjacent to {target}.
--- Unlike commands such as |:split|, no new windows are created
--- (the |window-ID| of window {nr} is unchanged after the move).
---
--- Both {nr} and {target} can be window numbers or |window-ID|s.
--- Both must be in the current tab page.

View File

@ -12699,10 +12699,10 @@ M.funcs = {
args = { 2, 3 },
base = 1,
desc = [=[
Move the window {nr} to a new split of the window {target}.
This is similar to moving to {target}, creating a new window
using |:split| but having the same contents as window {nr}, and
then closing {nr}.
Temporarily switch to window {target}, then move window {nr}
to a new split adjacent to {target}.
Unlike commands such as |:split|, no new windows are created
(the |window-ID| of window {nr} is unchanged after the move).
Both {nr} and {target} can be window numbers or |window-ID|s.
Both must be in the current tab page.

View File

@ -987,6 +987,8 @@ int win_split(int size, int flags)
/// When "new_wp" is NULL: split the current window in two.
/// When "new_wp" is not NULL: insert this window at the far
/// top/left/right/bottom.
/// On failure, if "new_wp" was not NULL, no changes will have been made to the
/// window layout or sizes.
/// @return NULL for failure, or pointer to new window
win_T *win_split_ins(int size, int flags, win_T *new_wp, int dir)
{
@ -1494,7 +1496,7 @@ win_T *win_split_ins(int size, int flags, win_T *new_wp, int dir)
if (!(flags & WSP_NOENTER)) {
// make the new window the current window
win_enter_ext(wp, WEE_TRIGGER_NEW_AUTOCMDS | WEE_TRIGGER_ENTER_AUTOCMDS
win_enter_ext(wp, (new_wp == NULL ? WEE_TRIGGER_NEW_AUTOCMDS : 0) | WEE_TRIGGER_ENTER_AUTOCMDS
| WEE_TRIGGER_LEAVE_AUTOCMDS);
}
if (vertical) {

View File

@ -1066,6 +1066,19 @@ func Test_win_splitmove()
leftabove split b
leftabove vsplit c
leftabove split d
" win_splitmove doesn't actually create or close any windows, so expect an
" unchanged winid and no WinNew/WinClosed events, like :wincmd H/J/K/L.
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 WinNew * let s:triggered += ['WinNew', win_getid()]
au WinClosed * let s:triggered += ['WinClosed', str2nr(expand('<afile>'))]
augroup END
let winid = win_getid()
call assert_equal(0, win_splitmove(winnr(), winnr('l')))
call assert_equal(bufname(winbufnr(1)), 'c')
call assert_equal(bufname(winbufnr(2)), 'd')
@ -1088,6 +1101,11 @@ func Test_win_splitmove()
call assert_equal(bufname(winbufnr(3)), 'a')
call assert_equal(bufname(winbufnr(4)), 'd')
call assert_fails('call win_splitmove(winnr(), winnr("k"), v:_null_dict)', 'E1297:')
call assert_equal([], s:triggered)
call assert_equal(winid, win_getid())
unlet! s:triggered
au! WinSplitMove
only | bd
call assert_fails('call win_splitmove(winnr(), 123)', 'E957:')