summaryrefslogtreecommitdiffstats
path: root/src/testdir
diff options
context:
space:
mode:
authorSean Dewar <6256228+seandewar@users.noreply.github.com>2024-02-20 20:28:15 +0100
committerChristian Brabandt <cb@256bit.org>2024-02-20 20:35:41 +0100
commit0fd44a5ad81ade342cb54d8984965bdedd2272c8 (patch)
tree5216a619a29fec38045aa617717ced39b7d55685 /src/testdir
parent15935e7f54f0e00782a55ebc39a68e4cd94c2571 (diff)
patch 9.1.0116: win_split_ins may not check available roomv9.1.0116
Problem: win_split_ins has no check for E36 when moving an existing window Solution: check for room and fix the issues in f_win_splitmove() (Sean Dewar) win_split_ins has no check for E36 when moving an existing window, allowing for layouts with many overlapping zero-sized windows to be created (which may also cause drawing issues with tablines and such). f_win_splitmove also has some bugs. So check for room and fix the issues in f_win_splitmove. Handle failure in the two relevant win_split_ins callers by restoring the original layout, and factor the common logic into win_splitmove. Don't check for room when opening an autocommand window, as it's a temporary window that's rarely interacted with or drawn anyhow, and is rather important for some autocommands. Issues fixed in f_win_splitmove: - Error if splitting is disallowed. - Fix heap-use-after-frees if autocommands fired from switching to "targetwin" close "wp" or "oldwin". - Fix splitting the wrong window if autocommands fired from switching to "targetwin" switch to a different window. - Ensure -1 is returned for all errors. Also handle allocation failure a bit earlier in make_snapshot (callers, except win_splitmove, don't really care if a snapshot can't be made, so just ignore the return value). Note: Test_smoothscroll_in_zero_width_window failed after these changes with E36, as it was using the previous behaviour to create a zero-width window. I've fixed the test such that it fails with UBSAN as expected when v9.0.1367 is reverted (and simplified it too). related: #14042 Signed-off-by: Sean Dewar <6256228+seandewar@users.noreply.github.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
Diffstat (limited to 'src/testdir')
-rw-r--r--src/testdir/test_window_cmd.vim154
1 files changed, 141 insertions, 13 deletions
diff --git a/src/testdir/test_window_cmd.vim b/src/testdir/test_window_cmd.vim
index 6b7dccbb00..c898a233af 100644
--- a/src/testdir/test_window_cmd.vim
+++ b/src/testdir/test_window_cmd.vim
@@ -290,6 +290,16 @@ func Test_window_split_no_room()
for s in range(1, hor_split_count) | split | endfor
call assert_fails('split', 'E36:')
+ botright vsplit
+ wincmd |
+ let layout = winlayout()
+ let restcmd = winrestcmd()
+ call assert_fails('wincmd J', 'E36:')
+ call assert_fails('wincmd K', 'E36:')
+ call assert_equal(layout, winlayout())
+ call assert_equal(restcmd, winrestcmd())
+ only
+
" N vertical windows need >= 2*(N - 1) + 1 columns:
" - 1 column + 1 separator for each window (except last window)
" - 1 column for the last window which does not have separator
@@ -302,7 +312,35 @@ func Test_window_split_no_room()
for s in range(1, ver_split_count) | vsplit | endfor
call assert_fails('vsplit', 'E36:')
+ split
+ wincmd |
+ let layout = winlayout()
+ let restcmd = winrestcmd()
+ call assert_fails('wincmd H', 'E36:')
+ call assert_fails('wincmd L', 'E36:')
+ call assert_equal(layout, winlayout())
+ call assert_equal(restcmd, winrestcmd())
+
+ " Check that the last statusline isn't lost.
+ set laststatus=0
+ let restcmd = winrestcmd()
+ wincmd j
+ call setwinvar(winnr('k'), '&statusline', '@#')
+ let last_stl_row = win_screenpos(0)[0] - 1
+ redraw
+ call assert_equal('@#|', GetScreenStr(last_stl_row))
+ call assert_equal('~ |', GetScreenStr(&lines - &cmdheight))
+ call assert_fails('wincmd H', 'E36:')
+ call assert_fails('wincmd L', 'E36:')
+ call assert_equal(layout, winlayout())
+ call assert_equal(restcmd, winrestcmd())
+ call setwinvar(winnr('k'), '&statusline', '=-')
+ redraw
+ call assert_equal('=-|', GetScreenStr(last_stl_row))
+ call assert_equal('~ |', GetScreenStr(&lines - &cmdheight))
+
%bw!
+ set laststatus&
endfunc
func Test_window_exchange()
@@ -1097,6 +1135,44 @@ func Test_win_splitmove()
tabnew
call assert_fails('call win_splitmove(1, win_getid(1, 1))', 'E957:')
tabclose
+
+ split
+ augroup WinSplitMove
+ au!
+ au WinEnter * ++once call win_gotoid(win_getid(winnr('#')))
+ augroup END
+ call assert_fails('call win_splitmove(winnr(), winnr("#"))', 'E855:')
+
+ augroup WinSplitMove
+ au!
+ au WinLeave * ++once quit
+ augroup END
+ call assert_fails('call win_splitmove(winnr(), winnr("#"))', 'E855:')
+
+ split
+ split
+ augroup WinSplitMove
+ au!
+ au WinEnter * ++once let s:triggered = v:true
+ \| call assert_fails('call win_splitmove(winnr("$"), winnr())', 'E242:')
+ augroup END
+ quit
+ call assert_equal(v:true, s:triggered)
+ unlet! s:triggered
+
+ new
+ augroup WinSplitMove
+ au!
+ au BufHidden * ++once let s:triggered = v:true
+ \| call assert_fails('call win_splitmove(winnr("#"), winnr())', 'E1159:')
+ augroup END
+ hide
+ call assert_equal(v:true, s:triggered)
+ unlet! s:triggered
+
+ au! WinSplitMove
+ augroup! WinSplitMove
+ %bw!
endfunc
" Test for the :only command
@@ -2061,23 +2137,75 @@ func Test_new_help_window_on_error()
endfunc
func Test_smoothscroll_in_zero_width_window()
- let save_lines = &lines
- let save_columns = &columns
+ set cpo+=n number smoothscroll
+ set winwidth=99999 winminwidth=0
- winsize 0 24
- set cpo+=n
- exe "noremap 0 \<C-W>n\<C-W>L"
- norm 000000
- set number smoothscroll
- exe "norm \<C-Y>"
+ vsplit
+ call assert_equal(0, winwidth(winnr('#')))
+ call win_execute(win_getid(winnr('#')), "norm! \<C-Y>")
+
+ only!
+ set winwidth& winminwidth&
+ set cpo-=n nonumber nosmoothscroll
+endfunc
+
+func Test_splitmove_flatten_frame()
+ split
+ vsplit
+
+ wincmd L
+ let layout = winlayout()
+ wincmd K
+ wincmd L
+ call assert_equal(winlayout(), layout)
only!
- let &lines = save_lines
- let &columns = save_columns
- set cpo-=n
- unmap 0
- set nonumber nosmoothscroll
endfunc
+func Test_splitmove_autocmd_window_no_room()
+ " Open as many windows as possible
+ while v:true
+ try
+ split
+ catch /E36:/
+ break
+ endtry
+ endwhile
+ while v:true
+ try
+ vsplit
+ catch /E36:/
+ break
+ endtry
+ endwhile
+
+ wincmd j
+ vsplit
+ call assert_fails('wincmd H', 'E36:')
+ call assert_fails('wincmd J', 'E36:')
+ call assert_fails('wincmd K', 'E36:')
+ call assert_fails('wincmd L', 'E36:')
+
+ edit unload me
+ enew
+ bunload! unload\ me
+ augroup SplitMoveAucmdWin
+ au!
+ au BufEnter * ++once let s:triggered = v:true
+ \| call assert_equal('autocmd', win_gettype())
+ augroup END
+ let layout = winlayout()
+ let restcmd = winrestcmd()
+ " bufload opening the autocommand window shouldn't give E36.
+ call bufload('unload me')
+ call assert_equal(v:true, s:triggered)
+ call assert_equal(winlayout(), layout)
+ call assert_equal(winrestcmd(), restcmd)
+
+ unlet! s:triggered
+ au! SplitMoveAucmdWin
+ augroup! SplitMoveAucmdWin
+ %bw!
+endfunc
" vim: shiftwidth=2 sts=2 expandtab