aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Dewar <6256228+seandewar@users.noreply.github.com>2024-02-24 23:18:50 +0000
committerSean Dewar <6256228+seandewar@users.noreply.github.com>2024-03-08 23:24:04 +0000
commit24dfa47e4f4ca41d0c5f8c1c0f851602362c81d3 (patch)
treee4992e2be9104db0ccd7b6c89448f4897b7c8f5f
parent66f331fef7ad3df480bd02f1705e176d1a07c785 (diff)
downloadrneovim-24dfa47e4f4ca41d0c5f8c1c0f851602362c81d3.tar.gz
rneovim-24dfa47e4f4ca41d0c5f8c1c0f851602362c81d3.tar.bz2
rneovim-24dfa47e4f4ca41d0c5f8c1c0f851602362c81d3.zip
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) https://github.com/vim/vim/commit/96cc4aef3d47d0fd70e68908af3d48a0dce8ea70 Partial as WinNewPre has not been ported yet (it currently has problems anyway).
-rw-r--r--runtime/doc/builtin.txt8
-rw-r--r--runtime/doc/windows.txt30
-rw-r--r--runtime/lua/vim/_meta/vimfn.lua8
-rw-r--r--src/nvim/eval.lua8
-rw-r--r--src/nvim/window.c4
-rw-r--r--test/old/testdir/test_window_cmd.vim18
6 files changed, 47 insertions, 29 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index c5f3946871..4b1ccc0c5c 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -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.
diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt
index b71e7c80ab..4791e73929 100644
--- a/runtime/doc/windows.txt
+++ b/runtime/doc/windows.txt
@@ -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.
diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua
index ac25547212..ee68f669f8 100644
--- a/runtime/lua/vim/_meta/vimfn.lua
+++ b/runtime/lua/vim/_meta/vimfn.lua
@@ -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.
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index b7120d5dd5..febd022254 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -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.
diff --git a/src/nvim/window.c b/src/nvim/window.c
index cfa28bbc1f..b1135d59fc 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -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) {
diff --git a/test/old/testdir/test_window_cmd.vim b/test/old/testdir/test_window_cmd.vim
index 99a713d2ed..fc379c198d 100644
--- a/test/old/testdir/test_window_cmd.vim
+++ b/test/old/testdir/test_window_cmd.vim
@@ -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:')