mirror of
https://github.com/neovim/neovim.git
synced 2026-05-23 21:30:11 +00:00
Problem: tests: flaky screendump Test_smoothscroll_incsearch()
Solution: Replace screendump test by WaitForAssert()
(Yasuhiro Matsumoto)
VerifyScreenDump fails consistently on the macos-15-intel CI runner.
Replace the dump comparisons with assertions that verify the actual
invariant under test: that the visible buffer view stays unchanged
across the four incremental-search keystrokes (i.e. skipcol is not
reset). Drop the now-unused dump files.
closes: vim/vim#20118
e25933014c
Co-authored-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
2146 lines
62 KiB
VimL
2146 lines
62 KiB
VimL
" Test for 'scroll', 'scrolloff', 'smoothscroll', etc.
|
||
|
||
source check.vim
|
||
source screendump.vim
|
||
source mouse.vim
|
||
|
||
func Test_reset_scroll()
|
||
let scr = &l:scroll
|
||
|
||
setlocal scroll=1
|
||
setlocal scroll&
|
||
call assert_equal(scr, &l:scroll)
|
||
|
||
setlocal scroll=1
|
||
setlocal scroll=0
|
||
call assert_equal(scr, &l:scroll)
|
||
|
||
try
|
||
execute 'setlocal scroll=' . (winheight(0) + 1)
|
||
" not reached
|
||
call assert_false(1)
|
||
catch
|
||
call assert_exception('E49:')
|
||
endtry
|
||
|
||
split
|
||
|
||
let scr = &l:scroll
|
||
|
||
setlocal scroll=1
|
||
setlocal scroll&
|
||
call assert_equal(scr, &l:scroll)
|
||
|
||
setlocal scroll=1
|
||
setlocal scroll=0
|
||
call assert_equal(scr, &l:scroll)
|
||
|
||
quit!
|
||
endfunc
|
||
|
||
func Test_scolloff_even_line_count()
|
||
new
|
||
resize 6
|
||
setlocal scrolloff=3
|
||
call setline(1, range(20))
|
||
normal 2j
|
||
call assert_equal(1, getwininfo(win_getid())[0].topline)
|
||
normal j
|
||
call assert_equal(1, getwininfo(win_getid())[0].topline)
|
||
normal j
|
||
call assert_equal(2, getwininfo(win_getid())[0].topline)
|
||
normal j
|
||
call assert_equal(3, getwininfo(win_getid())[0].topline)
|
||
|
||
bwipe!
|
||
endfunc
|
||
|
||
func Test_mouse_scroll_inactive_with_cursorbind()
|
||
for scb in [0, 1]
|
||
for so in [0, 1, 2]
|
||
let msg = $'scb={scb} so={so}'
|
||
|
||
new | only
|
||
let w1 = win_getid()
|
||
setlocal cursorbind
|
||
let &l:scb = scb
|
||
let &l:so = so
|
||
call setline(1, range(101, 109))
|
||
rightbelow vnew
|
||
let w2 = win_getid()
|
||
setlocal cursorbind
|
||
let &l:scb = scb
|
||
let &l:so = so
|
||
call setline(1, range(101, 109))
|
||
|
||
normal! $
|
||
call assert_equal(3, col('.', w1), msg)
|
||
call assert_equal(3, col('.', w2), msg)
|
||
call Ntest_setmouse(1, 1)
|
||
call feedkeys("\<ScrollWheelDown>", 'xt')
|
||
call assert_equal(4, line('w0', w1), msg)
|
||
call assert_equal(4 + so, line('.', w1), msg)
|
||
call assert_equal(1, line('w0', w2), msg)
|
||
call assert_equal(1, line('.', w2), msg)
|
||
call feedkeys("\<ScrollWheelDown>", 'xt')
|
||
call assert_equal(7, line('w0', w1), msg)
|
||
call assert_equal(7 + so, line('.', w1), msg)
|
||
call assert_equal(1, line('w0', w2), msg)
|
||
call assert_equal(1, line('.', w2), msg)
|
||
call feedkeys("\<ScrollWheelUp>", 'xt')
|
||
call assert_equal(4, line('w0', w1), msg)
|
||
call assert_equal(7 + so, line('.', w1), msg)
|
||
call assert_equal(1, line('w0', w2), msg)
|
||
call assert_equal(1, line('.', w2), msg)
|
||
call feedkeys("\<ScrollWheelUp>", 'xt')
|
||
call assert_equal(1, line('w0', w1), msg)
|
||
call assert_equal(7 + so, line('.', w1), msg)
|
||
call assert_equal(1, line('w0', w2), msg)
|
||
call assert_equal(1, line('.', w2), msg)
|
||
normal! 0
|
||
call assert_equal(1, line('.', w1), msg)
|
||
call assert_equal(1, col('.', w1), msg)
|
||
call assert_equal(1, line('.', w2), msg)
|
||
call assert_equal(1, col('.', w2), msg)
|
||
|
||
bwipe!
|
||
bwipe!
|
||
endfor
|
||
endfor
|
||
endfunc
|
||
|
||
func Test_CtrlE_CtrlY_stop_at_end()
|
||
enew
|
||
call setline(1, ['one', 'two'])
|
||
set number
|
||
exe "normal \<C-Y>"
|
||
call assert_equal([" 1 one "], ScreenLines(1, 10))
|
||
exe "normal \<C-E>\<C-E>\<C-E>"
|
||
call assert_equal([" 2 two "], ScreenLines(1, 10))
|
||
|
||
bwipe!
|
||
set nonumber
|
||
endfunc
|
||
|
||
func Test_smoothscroll_CtrlE_CtrlY()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
vim9script
|
||
setline(1, [
|
||
'line one',
|
||
'word '->repeat(20),
|
||
'line three',
|
||
'long word '->repeat(7),
|
||
'line',
|
||
'line',
|
||
'line',
|
||
])
|
||
set smoothscroll
|
||
:5
|
||
END
|
||
call writefile(lines, 'XSmoothScroll', 'D')
|
||
let buf = RunVimInTerminal('-S XSmoothScroll', #{rows: 12, cols: 40})
|
||
|
||
call term_sendkeys(buf, "\<C-E>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_1', {})
|
||
call term_sendkeys(buf, "\<C-E>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_2', {})
|
||
call term_sendkeys(buf, "\<C-E>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_3', {})
|
||
call term_sendkeys(buf, "\<C-E>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_4', {})
|
||
|
||
call term_sendkeys(buf, "\<C-Y>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_5', {})
|
||
call term_sendkeys(buf, "\<C-Y>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_6', {})
|
||
call term_sendkeys(buf, "\<C-Y>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_7', {})
|
||
call term_sendkeys(buf, "\<C-Y>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_8', {})
|
||
|
||
if has('folding')
|
||
call term_sendkeys(buf, ":set foldmethod=indent\<CR>")
|
||
" move the cursor so we can reuse the same dumps
|
||
call term_sendkeys(buf, "5G")
|
||
call term_sendkeys(buf, "\<C-E>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_1', {})
|
||
call term_sendkeys(buf, "\<C-E>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_2', {})
|
||
call term_sendkeys(buf, "7G")
|
||
call term_sendkeys(buf, "\<C-Y>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_7', {})
|
||
call term_sendkeys(buf, "\<C-Y>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_8', {})
|
||
endif
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
func Test_smoothscroll_multibyte()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
set scrolloff=0 smoothscroll
|
||
call setline(1, [repeat('ϛ', 45), repeat('2', 36)])
|
||
exe "normal G35l\<C-E>k"
|
||
END
|
||
call writefile(lines, 'XSmoothMultibyte', 'D')
|
||
let buf = RunVimInTerminal('-S XSmoothMultibyte', #{rows: 6, cols: 40})
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_multi_1', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
func Test_smoothscroll_number()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
vim9script
|
||
setline(1, [
|
||
'one ' .. 'word '->repeat(20),
|
||
'two ' .. 'long word '->repeat(7),
|
||
'line',
|
||
'line',
|
||
'line',
|
||
])
|
||
set smoothscroll
|
||
set splitkeep=topline
|
||
set number cpo+=n
|
||
:3
|
||
|
||
def g:DoRel()
|
||
set number relativenumber scrolloff=0
|
||
:%del
|
||
setline(1, [
|
||
'one',
|
||
'very long text '->repeat(12),
|
||
'three',
|
||
])
|
||
exe "normal 2Gzt\<C-E>"
|
||
enddef
|
||
END
|
||
call writefile(lines, 'XSmoothNumber', 'D')
|
||
let buf = RunVimInTerminal('-S XSmoothNumber', #{rows: 12, cols: 40})
|
||
|
||
call VerifyScreenDump(buf, 'Test_smooth_number_1', {})
|
||
call term_sendkeys(buf, "\<C-E>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_number_2', {})
|
||
call term_sendkeys(buf, "\<C-E>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_number_3', {})
|
||
|
||
call term_sendkeys(buf, ":set cpo-=n\<CR>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_number_4', {})
|
||
call term_sendkeys(buf, "\<C-Y>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_number_5', {})
|
||
call term_sendkeys(buf, "\<C-Y>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_number_6', {})
|
||
|
||
call term_sendkeys(buf, ":botright split\<CR>\<C-L>gg")
|
||
call VerifyScreenDump(buf, 'Test_smooth_number_7', {})
|
||
call term_sendkeys(buf, "\<C-E>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_number_8', {})
|
||
call term_sendkeys(buf, "\<C-E>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_number_9', {})
|
||
call term_sendkeys(buf, ":close\<CR>")
|
||
|
||
call term_sendkeys(buf, ":call DoRel()\<CR>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_number_10', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
func Test_smoothscroll_list()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
vim9script
|
||
set smoothscroll scrolloff=0
|
||
set list
|
||
setline(1, [
|
||
'one',
|
||
'very long text '->repeat(12),
|
||
'three',
|
||
])
|
||
exe "normal 2Gzt\<C-E>"
|
||
END
|
||
call writefile(lines, 'XSmoothList', 'D')
|
||
let buf = RunVimInTerminal('-S XSmoothList', #{rows: 8, cols: 40})
|
||
|
||
call VerifyScreenDump(buf, 'Test_smooth_list_1', {})
|
||
|
||
call term_sendkeys(buf, ":set listchars+=precedes:#\<CR>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_list_2', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
func Test_smoothscroll_diff_mode()
|
||
CheckScreendump
|
||
CheckFeature diff
|
||
|
||
let lines =<< trim END
|
||
vim9script
|
||
var text = 'just some text here'
|
||
setline(1, text)
|
||
set smoothscroll
|
||
diffthis
|
||
new
|
||
setline(1, text)
|
||
set smoothscroll
|
||
diffthis
|
||
END
|
||
call writefile(lines, 'XSmoothDiff', 'D')
|
||
let buf = RunVimInTerminal('-S XSmoothDiff', #{rows: 8})
|
||
|
||
call VerifyScreenDump(buf, 'Test_smooth_diff_1', {})
|
||
call term_sendkeys(buf, "\<C-Y>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_diff_1', {})
|
||
call term_sendkeys(buf, "\<C-E>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_diff_1', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
func Test_smoothscroll_diff_change_line_default()
|
||
CheckScreendump
|
||
CheckFeature diff
|
||
|
||
" Uses the new diffopt default with indent-heuristic and inline:char
|
||
let lines =<< trim END
|
||
set diffopt=internal,filler,closeoff,indent-heuristic,inline:char,followwrap smoothscroll
|
||
call setline(1, repeat(' abc', &columns))
|
||
call setline(2, 'bar')
|
||
call setline(3, repeat(' abc', &columns))
|
||
vnew
|
||
call setline(1, repeat(' abc', &columns))
|
||
call setline(2, 'foo')
|
||
call setline(3, 'bar')
|
||
call setline(4, repeat(' abc', &columns))
|
||
windo exe "normal! 2gg5\<C-E>"
|
||
windo diffthis
|
||
END
|
||
call writefile(lines, 'XSmoothDiffChangeLine', 'D')
|
||
let buf = RunVimInTerminal('-S XSmoothDiffChangeLine', #{rows: 20, columns: 55})
|
||
|
||
call VerifyScreenDump(buf, 'Test_smooth_diff_change_line_1', {})
|
||
call term_sendkeys(buf, "Abar")
|
||
call VerifyScreenDump(buf, 'Test_smooth_diff_change_line_2', {})
|
||
call term_sendkeys(buf, "\<Esc>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_diff_change_line_3a', {})
|
||
call term_sendkeys(buf, "yyp")
|
||
call VerifyScreenDump(buf, 'Test_smooth_diff_change_line_4', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
func Test_smoothscroll_diff_change_line()
|
||
CheckScreendump
|
||
CheckFeature diff
|
||
|
||
" Uses the old diffopt default
|
||
let lines =<< trim END
|
||
set diffopt=internal,filler,closeoff,followwrap,inline:simple smoothscroll
|
||
call setline(1, repeat(' abc', &columns))
|
||
call setline(2, 'bar')
|
||
call setline(3, repeat(' abc', &columns))
|
||
vnew
|
||
call setline(1, repeat(' abc', &columns))
|
||
call setline(2, 'foo')
|
||
call setline(3, 'bar')
|
||
call setline(4, repeat(' abc', &columns))
|
||
windo exe "normal! 2gg5\<C-E>"
|
||
windo diffthis
|
||
END
|
||
call writefile(lines, 'XSmoothDiffChangeLine', 'D')
|
||
let buf = RunVimInTerminal('-S XSmoothDiffChangeLine', #{rows: 20, columns: 55})
|
||
|
||
call VerifyScreenDump(buf, 'Test_smooth_diff_change_line_1', {})
|
||
call term_sendkeys(buf, "Abar")
|
||
call VerifyScreenDump(buf, 'Test_smooth_diff_change_line_2', {})
|
||
call term_sendkeys(buf, "\<Esc>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_diff_change_line_3', {})
|
||
call term_sendkeys(buf, "yyp")
|
||
call VerifyScreenDump(buf, 'Test_smooth_diff_change_line_4', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
func Test_smoothscroll_wrap_scrolloff_zero()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
vim9script
|
||
setline(1, ['Line' .. (' with some text'->repeat(7))]->repeat(7))
|
||
set smoothscroll scrolloff=0
|
||
:3
|
||
END
|
||
call writefile(lines, 'XSmoothWrap', 'D')
|
||
let buf = RunVimInTerminal('-S XSmoothWrap', #{rows: 8, cols: 40})
|
||
|
||
call VerifyScreenDump(buf, 'Test_smooth_wrap_1', {})
|
||
|
||
" moving cursor down - whole bottom line shows
|
||
call term_sendkeys(buf, "j")
|
||
call VerifyScreenDump(buf, 'Test_smooth_wrap_2', {})
|
||
|
||
call term_sendkeys(buf, "\<C-E>j")
|
||
call VerifyScreenDump(buf, 'Test_smooth_wrap_3', {})
|
||
|
||
call term_sendkeys(buf, "G")
|
||
call VerifyScreenDump(buf, 'Test_smooth_wrap_4', {})
|
||
|
||
call term_sendkeys(buf, "4\<C-Y>G")
|
||
call VerifyScreenDump(buf, 'Test_smooth_wrap_4', {})
|
||
|
||
" moving cursor up right after the <<< marker - no need to show whole line
|
||
call term_sendkeys(buf, "2gj3l2k")
|
||
call VerifyScreenDump(buf, 'Test_smooth_wrap_5', {})
|
||
|
||
" moving cursor up where the <<< marker is - whole top line shows
|
||
call term_sendkeys(buf, "2j02k")
|
||
call VerifyScreenDump(buf, 'Test_smooth_wrap_6', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
func Test_smoothscroll_wrap_long_line()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
vim9script
|
||
setline(1, ['one', 'two', 'Line' .. (' with lots of text'->repeat(30)) .. ' end', 'four'])
|
||
set smoothscroll scrolloff=0
|
||
normal 3G10|zt
|
||
END
|
||
call writefile(lines, 'XSmoothWrap', 'D')
|
||
let buf = RunVimInTerminal('-S XSmoothWrap', #{rows: 6, cols: 40})
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_1', {})
|
||
|
||
" scrolling up, cursor moves screen line down
|
||
call term_sendkeys(buf, "\<C-E>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_2', {})
|
||
call term_sendkeys(buf, "5\<C-E>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_3', {})
|
||
|
||
" scrolling down, cursor moves screen line up
|
||
call term_sendkeys(buf, "5\<C-Y>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_4', {})
|
||
call term_sendkeys(buf, "\<C-Y>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_5', {})
|
||
|
||
" 'scrolloff' set to 1, scrolling up, cursor moves screen line down
|
||
call term_sendkeys(buf, ":set scrolloff=1\<CR>")
|
||
call term_sendkeys(buf, "10|\<C-E>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_6', {})
|
||
|
||
" 'scrolloff' set to 1, scrolling down, cursor moves screen line up
|
||
call term_sendkeys(buf, "\<C-E>")
|
||
call term_sendkeys(buf, "gjgj")
|
||
call term_sendkeys(buf, "\<C-Y>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_7', {})
|
||
|
||
" 'scrolloff' set to 2, scrolling up, cursor moves screen line down
|
||
call term_sendkeys(buf, ":set scrolloff=2\<CR>")
|
||
call term_sendkeys(buf, "10|\<C-E>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_8', {})
|
||
|
||
" 'scrolloff' set to 2, scrolling down, cursor moves screen line up
|
||
call term_sendkeys(buf, "\<C-E>")
|
||
call term_sendkeys(buf, "gj")
|
||
call term_sendkeys(buf, "\<C-Y>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_9', {})
|
||
|
||
" 'scrolloff' set to 0, move cursor down one line.
|
||
" Cursor should move properly, and since this is a really long line, it will
|
||
" be put on top of the screen.
|
||
call term_sendkeys(buf, ":set scrolloff=0\<CR>")
|
||
call term_sendkeys(buf, "0j")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_10', {})
|
||
|
||
" Test zt/zz/zb that they work properly when a long line is above it
|
||
call term_sendkeys(buf, "zt")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_11', {})
|
||
call term_sendkeys(buf, "zz")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_12', {})
|
||
call term_sendkeys(buf, "zb")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_13', {})
|
||
|
||
" Repeat the step and move the cursor down again.
|
||
" This time, use a shorter long line that is barely long enough to span more
|
||
" than one window. Note that the cursor is at the bottom this time because
|
||
" Vim prefers to do so if we are scrolling a few lines only.
|
||
call term_sendkeys(buf, ":call setline(1, ['one', 'two', 'Line' .. (' with lots of text'->repeat(10)) .. ' end', 'four'])\<CR>")
|
||
" Currently visible lines were replaced, test that the lines and cursor
|
||
" are correctly displayed.
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_14', {})
|
||
call term_sendkeys(buf, "3Gzt")
|
||
call term_sendkeys(buf, "j")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_15', {})
|
||
|
||
" Repeat the step but this time start it when the line is smooth-scrolled by
|
||
" one line. This tests that the offset calculation is still correct and
|
||
" still end up scrolling down to the next line with cursor at bottom of
|
||
" screen.
|
||
call term_sendkeys(buf, "3Gzt")
|
||
call term_sendkeys(buf, "\<C-E>j")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_16', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
func Test_smoothscroll_one_long_line()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
vim9script
|
||
setline(1, 'with lots of text '->repeat(7))
|
||
set smoothscroll scrolloff=0
|
||
END
|
||
call writefile(lines, 'XSmoothOneLong', 'D')
|
||
let buf = RunVimInTerminal('-S XSmoothOneLong', #{rows: 6, cols: 40})
|
||
call VerifyScreenDump(buf, 'Test_smooth_one_long_1', {})
|
||
|
||
call term_sendkeys(buf, "\<C-E>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_one_long_2', {})
|
||
|
||
call term_sendkeys(buf, "0")
|
||
call VerifyScreenDump(buf, 'Test_smooth_one_long_1', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
func Test_smoothscroll_long_line_showbreak()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
vim9script
|
||
# a line that spans four screen lines
|
||
setline(1, 'with lots of text in one line '->repeat(6))
|
||
set smoothscroll scrolloff=0
|
||
&showbreak = '+++ '
|
||
END
|
||
call writefile(lines, 'XSmoothLongShowbreak', 'D')
|
||
let buf = RunVimInTerminal('-S XSmoothLongShowbreak', #{rows: 6, cols: 40})
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_showbreak_1', {})
|
||
|
||
call term_sendkeys(buf, "\<C-E>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_showbreak_2', {})
|
||
|
||
call term_sendkeys(buf, "0")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_showbreak_1', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
" Check that 'smoothscroll' marker is drawn over double-width char correctly.
|
||
" Run with multiple encodings.
|
||
func Test_smoothscroll_marker_over_double_width()
|
||
" Run this in a separate Vim instance to avoid messing up.
|
||
let after =<< trim [CODE]
|
||
scriptencoding utf-8
|
||
call setline(1, 'a'->repeat(&columns) .. '口'->repeat(10))
|
||
setlocal smoothscroll
|
||
redraw
|
||
exe "norm \<C-E>"
|
||
redraw
|
||
" Check the chars one by one. Don't check the whole line concatenated.
|
||
call assert_equal('<', screenstring(1, 1))
|
||
call assert_equal('<', screenstring(1, 2))
|
||
call assert_equal('<', screenstring(1, 3))
|
||
call assert_equal(' ', screenstring(1, 4))
|
||
call assert_equal('口', screenstring(1, 5))
|
||
call assert_equal('口', screenstring(1, 7))
|
||
call assert_equal('口', screenstring(1, 9))
|
||
call assert_equal('口', screenstring(1, 11))
|
||
call assert_equal('口', screenstring(1, 13))
|
||
call assert_equal('口', screenstring(1, 15))
|
||
call writefile(v:errors, 'Xresult')
|
||
qall!
|
||
[CODE]
|
||
|
||
let encodings = ['utf-8', 'cp932', 'cp936', 'cp949', 'cp950']
|
||
if !has('win32')
|
||
let encodings += ['euc-jp']
|
||
endif
|
||
if has('nvim')
|
||
let encodings = ['utf-8']
|
||
endif
|
||
for enc in encodings
|
||
let msg = 'enc=' .. enc
|
||
if RunVim([], after, $'--clean --cmd "set encoding={enc}"')
|
||
call assert_equal([], readfile('Xresult'), msg)
|
||
endif
|
||
call delete('Xresult')
|
||
endfor
|
||
endfunc
|
||
|
||
" Same as the test above, but check the text actually shown on screen.
|
||
" Only run with UTF-8 encoding.
|
||
func Test_smoothscroll_marker_over_double_width_dump()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
call setline(1, 'a'->repeat(&columns) .. '口'->repeat(10))
|
||
setlocal smoothscroll
|
||
END
|
||
call writefile(lines, 'XSmoothMarkerOverDoubleWidth', 'D')
|
||
let buf = RunVimInTerminal('-S XSmoothMarkerOverDoubleWidth', #{rows: 6, cols: 40})
|
||
call VerifyScreenDump(buf, 'Test_smooth_marker_over_double_width_1', {})
|
||
|
||
call term_sendkeys(buf, "\<C-E>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_marker_over_double_width_2', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
func s:check_col_calc(win_col, win_line, buf_col)
|
||
call assert_equal(a:win_col, wincol())
|
||
call assert_equal(a:win_line, winline())
|
||
call assert_equal(a:buf_col, col('.'))
|
||
endfunc
|
||
|
||
" Test that if the current cursor is on a smooth scrolled line, we correctly
|
||
" reposition it. Also check that we don't miscalculate the values by checking
|
||
" the consistency between wincol() and col('.') as they are calculated
|
||
" separately in code.
|
||
func Test_smoothscroll_cursor_position()
|
||
call NewWindow(10, 20)
|
||
setl smoothscroll wrap
|
||
call setline(1, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||
|
||
call s:check_col_calc(1, 1, 1)
|
||
exe "normal \<C-E>"
|
||
|
||
" Move down another line to avoid blocking the <<< display
|
||
call s:check_col_calc(1, 2, 41)
|
||
exe "normal \<C-Y>"
|
||
call s:check_col_calc(1, 3, 41)
|
||
|
||
" Test "g0/g<Home>"
|
||
exe "normal gg\<C-E>"
|
||
norm $gkg0
|
||
call s:check_col_calc(4, 1, 24)
|
||
|
||
" Test moving the cursor behind the <<< display with 'virtualedit'
|
||
set virtualedit=all
|
||
exe "normal \<C-E>gkh"
|
||
call s:check_col_calc(3, 2, 23)
|
||
set virtualedit&
|
||
|
||
normal gg3l
|
||
exe "normal \<C-E>"
|
||
|
||
" Move down only 1 line when we are out of the range of the <<< display
|
||
call s:check_col_calc(4, 1, 24)
|
||
exe "normal \<C-Y>"
|
||
call s:check_col_calc(4, 2, 24)
|
||
normal ggg$
|
||
exe "normal \<C-E>"
|
||
call s:check_col_calc(20, 1, 40)
|
||
exe "normal \<C-Y>"
|
||
call s:check_col_calc(20, 2, 40)
|
||
normal gg
|
||
|
||
" Test number, where we have indented lines
|
||
setl number
|
||
call s:check_col_calc(5, 1, 1)
|
||
exe "normal \<C-E>"
|
||
|
||
" Move down only 1 line when the <<< display is on the number column
|
||
call s:check_col_calc(5, 1, 17)
|
||
exe "normal \<C-Y>"
|
||
call s:check_col_calc(5, 2, 17)
|
||
normal ggg$
|
||
exe "normal \<C-E>"
|
||
call s:check_col_calc(20, 1, 32)
|
||
exe "normal \<C-Y>"
|
||
call s:check_col_calc(20, 2, 32)
|
||
normal gg
|
||
|
||
setl numberwidth=1
|
||
|
||
" Move down another line when numberwidth is too short to cover the whole
|
||
" <<< display
|
||
call s:check_col_calc(3, 1, 1)
|
||
exe "normal \<C-E>"
|
||
call s:check_col_calc(3, 2, 37)
|
||
exe "normal \<C-Y>"
|
||
call s:check_col_calc(3, 3, 37)
|
||
normal ggl
|
||
|
||
" Only move 1 line down when we are just past the <<< display
|
||
call s:check_col_calc(4, 1, 2)
|
||
exe "normal \<C-E>"
|
||
call s:check_col_calc(4, 1, 20)
|
||
exe "normal \<C-Y>"
|
||
call s:check_col_calc(4, 2, 20)
|
||
normal gg
|
||
setl numberwidth&
|
||
|
||
" Test number + showbreak, so test that the additional indentation works
|
||
setl number showbreak=+++
|
||
call s:check_col_calc(5, 1, 1)
|
||
exe "normal \<C-E>"
|
||
call s:check_col_calc(8, 1, 17)
|
||
exe "normal \<C-Y>"
|
||
call s:check_col_calc(8, 2, 17)
|
||
normal gg
|
||
|
||
" Test number + cpo+=n mode, where wrapped lines aren't indented
|
||
setl number cpo+=n showbreak=
|
||
call s:check_col_calc(5, 1, 1)
|
||
exe "normal \<C-E>"
|
||
call s:check_col_calc(1, 2, 37)
|
||
exe "normal \<C-Y>"
|
||
call s:check_col_calc(1, 3, 37)
|
||
normal gg
|
||
|
||
" Test list + listchars "precedes", where there is always 1 overlap
|
||
" regardless of number and cpo-=n.
|
||
setl number list listchars=precedes:< cpo-=n
|
||
call s:check_col_calc(5, 1, 1)
|
||
exe "normal 3|\<C-E>h"
|
||
call s:check_col_calc(6, 1, 18)
|
||
norm h
|
||
call s:check_col_calc(5, 2, 17)
|
||
normal gg
|
||
|
||
bwipe!
|
||
endfunc
|
||
|
||
func Test_smoothscroll_cursor_scrolloff()
|
||
call NewWindow(10, 20)
|
||
setl smoothscroll wrap
|
||
setl scrolloff=3
|
||
|
||
" 120 chars are 6 screen lines
|
||
call setline(1, "abcdefghijklmnopqrstABCDEFGHIJKLMNOPQRSTabcdefghijklmnopqrstABCDEFGHIJKLMNOPQRSTabcdefghijklmnopqrstABCDEFGHIJKLMNOPQRST")
|
||
call setline(2, "below")
|
||
|
||
call s:check_col_calc(1, 1, 1)
|
||
|
||
" CTRL-E shows "<<<DEFG...", cursor move four lines down
|
||
exe "normal \<C-E>"
|
||
call s:check_col_calc(1, 4, 81)
|
||
|
||
" cursor on start of second line, "gk" moves into first line, skipcol doesn't
|
||
" change
|
||
exe "normal G0gk"
|
||
call s:check_col_calc(1, 5, 101)
|
||
|
||
" move cursor left one window width worth, scrolls one screen line
|
||
exe "normal 20h"
|
||
call s:check_col_calc(1, 5, 81)
|
||
|
||
" move cursor left one window width worth, scrolls one screen line
|
||
exe "normal 20h"
|
||
call s:check_col_calc(1, 4, 61)
|
||
|
||
" cursor on last line, "gk" should not cause a scroll
|
||
set scrolloff=0
|
||
normal G0
|
||
call s:check_col_calc(1, 7, 1)
|
||
normal gk
|
||
call s:check_col_calc(1, 6, 101)
|
||
|
||
bwipe!
|
||
endfunc
|
||
|
||
|
||
" Test that mouse picking is still accurate when we have smooth scrolled lines
|
||
func Test_smoothscroll_mouse_pos()
|
||
CheckNotGui
|
||
CheckUnix
|
||
|
||
let save_mouse = &mouse
|
||
"let save_term = &term
|
||
"let save_ttymouse = &ttymouse
|
||
set mouse=a "term=xterm ttymouse=xterm2
|
||
|
||
call NewWindow(10, 20)
|
||
setl smoothscroll wrap
|
||
" First line will wrap to 3 physical lines. 2nd/3rd lines are short lines.
|
||
call setline(1, ["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", "line 2", "line 3"])
|
||
|
||
func s:check_mouse_click(row, col, buf_row, buf_col)
|
||
call MouseLeftClick(a:row, a:col)
|
||
|
||
call assert_equal(a:col, wincol())
|
||
call assert_equal(a:row, winline())
|
||
call assert_equal(a:buf_row, line('.'))
|
||
call assert_equal(a:buf_col, col('.'))
|
||
endfunc
|
||
|
||
" Check that clicking without scroll works first.
|
||
call s:check_mouse_click(3, 5, 1, 45)
|
||
call s:check_mouse_click(4, 1, 2, 1)
|
||
call s:check_mouse_click(4, 6, 2, 6)
|
||
call s:check_mouse_click(5, 1, 3, 1)
|
||
call s:check_mouse_click(5, 6, 3, 6)
|
||
|
||
" Smooth scroll, and checks that this didn't mess up mouse clicking
|
||
exe "normal \<C-E>"
|
||
call s:check_mouse_click(2, 5, 1, 45)
|
||
call s:check_mouse_click(3, 1, 2, 1)
|
||
call s:check_mouse_click(3, 6, 2, 6)
|
||
call s:check_mouse_click(4, 1, 3, 1)
|
||
call s:check_mouse_click(4, 6, 3, 6)
|
||
|
||
exe "normal \<C-E>"
|
||
call s:check_mouse_click(1, 5, 1, 45)
|
||
call s:check_mouse_click(2, 1, 2, 1)
|
||
call s:check_mouse_click(2, 6, 2, 6)
|
||
call s:check_mouse_click(3, 1, 3, 1)
|
||
call s:check_mouse_click(3, 6, 3, 6)
|
||
|
||
" Make a new first line 11 physical lines tall so it's taller than window
|
||
" height, to test overflow calculations with really long lines wrapping.
|
||
normal gg
|
||
call setline(1, "12345678901234567890"->repeat(11))
|
||
exe "normal 6\<C-E>"
|
||
call s:check_mouse_click(5, 1, 1, 201)
|
||
call s:check_mouse_click(6, 1, 2, 1)
|
||
call s:check_mouse_click(7, 1, 3, 1)
|
||
|
||
let &mouse = save_mouse
|
||
"let &term = save_term
|
||
"let &ttymouse = save_ttymouse
|
||
bwipe!
|
||
endfunc
|
||
|
||
" this was dividing by zero
|
||
func Test_smoothscroll_zero_width()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
winsize 0 0
|
||
vsplit
|
||
vsplit
|
||
vsplit
|
||
vsplit
|
||
vsplit
|
||
sil norm H
|
||
set wrap
|
||
set smoothscroll
|
||
set number
|
||
END
|
||
call writefile(lines, 'XSmoothScrollZero', 'D')
|
||
let buf = RunVimInTerminal('-u NONE -i NONE -n -m -X -Z -e -s -S XSmoothScrollZero', #{rows: 6, cols: 60, wait_for_ruler: 0})
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_zero_1', {})
|
||
|
||
call term_sendkeys(buf, ":sil norm \<C-V>\<C-W>\<C-V>\<C-N>\<CR>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_zero_2', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
" this was unnecessarily inserting lines
|
||
func Test_smoothscroll_ins_lines()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
set wrap
|
||
set smoothscroll
|
||
set scrolloff=0
|
||
set conceallevel=2
|
||
call setline(1, [
|
||
\'line one' .. 'with lots of text in one line '->repeat(2),
|
||
\'line two',
|
||
\'line three',
|
||
\'line four',
|
||
\'line five'
|
||
\])
|
||
END
|
||
call writefile(lines, 'XSmoothScrollInsLines', 'D')
|
||
let buf = RunVimInTerminal('-S XSmoothScrollInsLines', #{rows: 6, cols: 40})
|
||
|
||
call term_sendkeys(buf, "\<C-E>gjgk")
|
||
call VerifyScreenDump(buf, 'Test_smooth_ins_lines', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
" this placed the cursor in the command line
|
||
func Test_smoothscroll_cursormoved_line()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
set smoothscroll
|
||
call setline(1, [
|
||
\'',
|
||
\'_'->repeat(&lines * &columns),
|
||
\(('_')->repeat(&columns - 2) .. 'xxx')->repeat(2)
|
||
\])
|
||
autocmd CursorMoved * eval [line('w0'), line('w$')]
|
||
call search('xxx')
|
||
END
|
||
call writefile(lines, 'XSmoothCursorMovedLine', 'D')
|
||
let buf = RunVimInTerminal('-S XSmoothCursorMovedLine', #{rows: 6})
|
||
|
||
call VerifyScreenDump(buf, 'Test_smooth_cursormoved_line', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
func Test_smoothscroll_eob()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
set smoothscroll
|
||
call setline(1, ['']->repeat(100))
|
||
norm G
|
||
END
|
||
call writefile(lines, 'XSmoothEob', 'D')
|
||
let buf = RunVimInTerminal('-S XSmoothEob', #{rows: 10})
|
||
|
||
" does not scroll halfway when scrolling to end of buffer
|
||
call VerifyScreenDump(buf, 'Test_smooth_eob_1', {})
|
||
|
||
" cursor is not placed below window
|
||
call term_sendkeys(buf, ":call setline(92, 'a'->repeat(100))\<CR>\<C-L>\<C-B>G")
|
||
call VerifyScreenDump(buf, 'Test_smooth_eob_2', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
" skipcol should not reset when doing incremental search on the same word
|
||
func Test_smoothscroll_incsearch()
|
||
CheckRunVimInTerminal
|
||
|
||
let lines =<< trim END
|
||
set smoothscroll number scrolloff=0 incsearch
|
||
call setline(1, repeat([''], 20))
|
||
call setline(11, repeat('a', 100))
|
||
call setline(14, 'bbbb')
|
||
END
|
||
call writefile(lines, 'XSmoothIncsearch', 'D')
|
||
let buf = RunVimInTerminal('-S XSmoothIncsearch', #{rows: 8, cols: 40})
|
||
let g:test_is_flaky = 1
|
||
|
||
call term_sendkeys(buf, "/b")
|
||
call WaitForAssert({-> assert_match('^/b\s*$', term_getline(buf, 8))}, 1000)
|
||
let view1 = map(range(1, 7), {_, i -> term_getline(buf, i)})
|
||
|
||
call term_sendkeys(buf, "b")
|
||
call WaitForAssert({-> assert_match('^/bb\s*$', term_getline(buf, 8))}, 1000)
|
||
call assert_equal(view1, map(range(1, 7), {_, i -> term_getline(buf, i)}))
|
||
|
||
call term_sendkeys(buf, "b")
|
||
call WaitForAssert({-> assert_match('^/bbb\s*$', term_getline(buf, 8))}, 1000)
|
||
call assert_equal(view1, map(range(1, 7), {_, i -> term_getline(buf, i)}))
|
||
|
||
call term_sendkeys(buf, "b")
|
||
call WaitForAssert({-> assert_match('^/bbbb\s*$', term_getline(buf, 8))}, 1000)
|
||
call assert_equal(view1, map(range(1, 7), {_, i -> term_getline(buf, i)}))
|
||
|
||
call term_sendkeys(buf, "\<CR>")
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
" Test scrolling multiple lines and stopping at non-zero skipcol.
|
||
func Test_smoothscroll_multi_skipcol()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
setlocal cursorline scrolloff=0 smoothscroll
|
||
call setline(1, repeat([''], 8))
|
||
call setline(3, repeat('a', 50))
|
||
call setline(4, repeat('a', 50))
|
||
call setline(7, 'bbb')
|
||
call setline(8, 'ccc')
|
||
redraw
|
||
END
|
||
call writefile(lines, 'XSmoothMultiSkipcol', 'D')
|
||
let buf = RunVimInTerminal('-S XSmoothMultiSkipcol', #{rows: 10, cols: 40})
|
||
call VerifyScreenDump(buf, 'Test_smooth_multi_skipcol_1', {})
|
||
|
||
call term_sendkeys(buf, "3\<C-E>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_multi_skipcol_2', {})
|
||
|
||
call term_sendkeys(buf, "2\<C-E>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_multi_skipcol_3', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
" this was dividing by zero bug in scroll_cursor_bot
|
||
func Test_smoothscroll_zero_width_scroll_cursor_bot_noruler()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
set noruler
|
||
silent normal yy
|
||
silent normal 19p
|
||
set cpoptions+=n
|
||
vsplit
|
||
vertical resize 0
|
||
set foldcolumn=1
|
||
set number
|
||
set smoothscroll
|
||
silent normal 20G
|
||
END
|
||
call writefile(lines, 'XSmoothScrollZeroBot', 'D')
|
||
let buf = RunVimInTerminal('-u NONE -S XSmoothScrollZeroBot', #{rows: 19})
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_zero_bot', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
func Test_smoothscroll_zero_width_scroll_cursor_bot_ruler()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
set ruler
|
||
silent normal yy
|
||
silent normal 19p
|
||
set cpoptions+=n
|
||
vsplit
|
||
vertical resize 0
|
||
set foldcolumn=1
|
||
set number
|
||
set smoothscroll
|
||
silent normal 20G
|
||
END
|
||
call writefile(lines, 'XSmoothScrollZeroBot', 'D')
|
||
let buf = RunVimInTerminal('-u NONE -S XSmoothScrollZeroBot', #{rows: 19})
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_zero_bot_ruler', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
" scroll_cursor_top() should reset skipcol when it changes topline
|
||
func Test_smoothscroll_cursor_top_noruler()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
set smoothscroll scrolloff=2 noruler
|
||
new | 11resize | wincmd j
|
||
call setline(1, ['line1', 'line2', 'line3'->repeat(20), 'line4'])
|
||
exe "norm G3\<C-E>k"
|
||
END
|
||
call writefile(lines, 'XSmoothScrollCursorTop', 'D')
|
||
let buf = RunVimInTerminal('-u NONE -S XSmoothScrollCursorTop', #{rows: 12, cols: 40})
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_cursor_top', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
func Test_smoothscroll_cursor_top_ruler()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
set smoothscroll scrolloff=2 ruler
|
||
new | 11resize | wincmd j
|
||
call setline(1, ['line1', 'line2', 'line3'->repeat(20), 'line4'])
|
||
exe "norm G3\<C-E>k"
|
||
END
|
||
call writefile(lines, 'XSmoothScrollCursorTop', 'D')
|
||
let buf = RunVimInTerminal('-u NONE -S XSmoothScrollCursorTop', #{rows: 12, cols: 40})
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_cursor_ru_top', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
" Division by zero, shouldn't crash
|
||
func Test_smoothscroll_crash()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
20 new
|
||
vsp
|
||
put =repeat('aaaa', 20)
|
||
set nu fdc=1 smoothscroll cpo+=n
|
||
vert resize 0
|
||
exe "norm! 0\<c-e>"
|
||
END
|
||
call writefile(lines, 'XSmoothScrollCrash', 'D')
|
||
let buf = RunVimInTerminal('-u NONE -S XSmoothScrollCrash', #{rows: 12, cols: 40})
|
||
call term_sendkeys(buf, "2\<C-E>\<C-L>")
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
func Test_smoothscroll_insert_bottom_noruler()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
call setline(1, repeat([repeat('A very long line ...', 10)], 5))
|
||
set wrap smoothscroll scrolloff=0 noruler
|
||
END
|
||
call writefile(lines, 'XSmoothScrollInsertBottom', 'D')
|
||
let buf = RunVimInTerminal('-u NONE -S XSmoothScrollInsertBottom', #{rows: 9, cols: 40})
|
||
call term_sendkeys(buf, "Go123456789\<CR>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_insert_bottom', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
func Test_smoothscroll_insert_bottom_ruler()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
call setline(1, repeat([repeat('A very long line ...', 10)], 5))
|
||
set wrap smoothscroll scrolloff=0 ruler
|
||
END
|
||
call writefile(lines, 'XSmoothScrollInsertBottom', 'D')
|
||
let buf = RunVimInTerminal('-u NONE -S XSmoothScrollInsertBottom', #{rows: 9, cols: 40})
|
||
call term_sendkeys(buf, "Go123456789\<CR>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_insert_bottom_ruler', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
func Test_smoothscroll_in_qf_window_noruler()
|
||
CheckFeature quickfix
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
set nocompatible display=lastline noruler
|
||
copen 5
|
||
setlocal number smoothscroll
|
||
let g:l = [{'text': 'foo'}] + repeat([{'text': join(range(30))}], 10)
|
||
call setqflist(g:l, 'r')
|
||
normal! G
|
||
wincmd t
|
||
let g:l1 = [{'text': join(range(1000))}]
|
||
END
|
||
call writefile(lines, 'XSmoothScrollInQfWindow', 'D')
|
||
let buf = RunVimInTerminal('-u NONE -S XSmoothScrollInQfWindow', #{rows: 20, cols: 60})
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_1', {})
|
||
|
||
call term_sendkeys(buf, ":call setqflist([], 'r')\<CR>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_2', {})
|
||
|
||
call term_sendkeys(buf, ":call setqflist(g:l, 'r')\<CR>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_3', {})
|
||
|
||
call term_sendkeys(buf, ":call setqflist(g:l1, 'r')\<CR>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_4', {})
|
||
|
||
call term_sendkeys(buf, "\<C-W>b$\<C-W>t")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_5', {})
|
||
|
||
call term_sendkeys(buf, ":call setqflist([], 'r')\<CR>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_2', {})
|
||
|
||
call term_sendkeys(buf, ":call setqflist(g:l1, 'r')\<CR>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_4', {})
|
||
|
||
call term_sendkeys(buf, "\<C-W>b$\<C-W>t")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_5', {})
|
||
|
||
call term_sendkeys(buf, ":call setqflist(g:l, 'r')\<CR>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_3', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
func Test_smoothscroll_in_qf_window_ruler()
|
||
CheckFeature quickfix
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
set nocompatible display=lastline ruler
|
||
copen 5
|
||
setlocal number smoothscroll
|
||
let g:l = [{'text': 'foo'}] + repeat([{'text': join(range(30))}], 10)
|
||
call setqflist(g:l, 'r')
|
||
normal! G
|
||
wincmd t
|
||
let g:l1 = [{'text': join(range(1000))}]
|
||
END
|
||
call writefile(lines, 'XSmoothScrollInQfWindow', 'D')
|
||
let buf = RunVimInTerminal('-u NONE -S XSmoothScrollInQfWindow', #{rows: 20, cols: 60})
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_ru_1', {})
|
||
|
||
call term_sendkeys(buf, ":call setqflist([], 'r')\<CR>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_ru_2', {})
|
||
|
||
call term_sendkeys(buf, ":call setqflist(g:l, 'r')\<CR>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_ru_3', {})
|
||
|
||
call term_sendkeys(buf, ":call setqflist(g:l1, 'r')\<CR>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_ru_4', {})
|
||
|
||
call term_sendkeys(buf, "\<C-W>b$\<C-W>t")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_ru_5', {})
|
||
|
||
call term_sendkeys(buf, ":call setqflist([], 'r')\<CR>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_ru_2', {})
|
||
|
||
call term_sendkeys(buf, ":call setqflist(g:l1, 'r')\<CR>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_ru_4', {})
|
||
|
||
call term_sendkeys(buf, "\<C-W>b$\<C-W>t")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_ru_5', {})
|
||
|
||
call term_sendkeys(buf, ":call setqflist(g:l, 'r')\<CR>")
|
||
call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_ru_3', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
func Test_smoothscroll_in_zero_width_window()
|
||
set cpo+=n number smoothscroll
|
||
set winwidth=99999 winminwidth=0
|
||
|
||
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_smoothscroll_textoff_small_winwidth()
|
||
set smoothscroll number
|
||
call setline(1, 'llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch')
|
||
vsplit
|
||
|
||
let textoff = getwininfo(win_getid())[0].textoff
|
||
execute 'vertical resize' textoff + 1
|
||
redraw
|
||
call assert_equal(0, winsaveview().skipcol)
|
||
execute "normal! 0\<C-E>"
|
||
redraw
|
||
call assert_equal(1, winsaveview().skipcol)
|
||
execute 'vertical resize' textoff - 1
|
||
" This caused a signed integer overflow.
|
||
redraw
|
||
call assert_equal(1, winsaveview().skipcol)
|
||
execute 'vertical resize' textoff
|
||
" This caused an infinite loop.
|
||
redraw
|
||
call assert_equal(1, winsaveview().skipcol)
|
||
|
||
%bw!
|
||
set smoothscroll& number&
|
||
endfunc
|
||
|
||
func Test_smoothscroll_page()
|
||
call NewWindow(10, 40)
|
||
setlocal smoothscroll
|
||
call setline(1, 'abcde '->repeat(150))
|
||
|
||
exe "norm! \<C-F>"
|
||
call assert_equal(400, winsaveview().skipcol)
|
||
exe "norm! \<C-F>"
|
||
call assert_equal(800, winsaveview().skipcol)
|
||
exe "norm! \<C-F>"
|
||
call assert_equal(880, winsaveview().skipcol)
|
||
exe "norm! \<C-B>"
|
||
call assert_equal(480, winsaveview().skipcol)
|
||
exe "norm! \<C-B>"
|
||
call assert_equal(80, winsaveview().skipcol)
|
||
exe "norm! \<C-B>"
|
||
call assert_equal(0, winsaveview().skipcol)
|
||
|
||
" Half-page scrolling does not go beyond end of buffer and moves the cursor.
|
||
" Even with 'nostartofline', the correct amount of lines is scrolled.
|
||
setl nostartofline
|
||
exe "norm! 15|\<C-D>"
|
||
call assert_equal(200, winsaveview().skipcol)
|
||
call assert_equal(215, col('.'))
|
||
exe "norm! \<C-D>"
|
||
call assert_equal(400, winsaveview().skipcol)
|
||
call assert_equal(415, col('.'))
|
||
exe "norm! \<C-D>"
|
||
call assert_equal(520, winsaveview().skipcol)
|
||
call assert_equal(615, col('.'))
|
||
exe "norm! \<C-D>"
|
||
call assert_equal(520, winsaveview().skipcol)
|
||
call assert_equal(815, col('.'))
|
||
exe "norm! \<C-D>"
|
||
call assert_equal(520, winsaveview().skipcol)
|
||
call assert_equal(895, col('.'))
|
||
exe "norm! \<C-U>"
|
||
call assert_equal(320, winsaveview().skipcol)
|
||
call assert_equal(695, col('.'))
|
||
exe "norm! \<C-U>"
|
||
call assert_equal(120, winsaveview().skipcol)
|
||
call assert_equal(495, col('.'))
|
||
exe "norm! \<C-U>"
|
||
call assert_equal(0, winsaveview().skipcol)
|
||
call assert_equal(295, col('.'))
|
||
exe "norm! \<C-U>"
|
||
call assert_equal(0, winsaveview().skipcol)
|
||
call assert_equal(95, col('.'))
|
||
exe "norm! \<C-U>"
|
||
call assert_equal(0, winsaveview().skipcol)
|
||
call assert_equal(15, col('.'))
|
||
|
||
bwipe!
|
||
endfunc
|
||
|
||
func Test_smoothscroll_next_topline()
|
||
call NewWindow(10, 40)
|
||
setlocal smoothscroll
|
||
call setline(1, ['abcde '->repeat(150)]->repeat(2))
|
||
|
||
" Scrolling a screenline that causes the cursor to move to the next buffer
|
||
" line should not skip part of that line to bring the cursor into view.
|
||
exe "norm! 22\<C-E>"
|
||
call assert_equal(880, winsaveview().skipcol)
|
||
exe "norm! \<C-E>"
|
||
redraw
|
||
call assert_equal(0, winsaveview().skipcol)
|
||
|
||
" Also when scrolling back.
|
||
exe "norm! G\<C-Y>"
|
||
redraw
|
||
call assert_equal(880, winsaveview().skipcol)
|
||
|
||
" Cursor in correct place when not in the first screenline of a buffer line.
|
||
exe "norm! gg4gj20\<C-D>\<C-D>"
|
||
redraw
|
||
call assert_equal(2, line('w0'))
|
||
|
||
" Cursor does not end up above topline, adjusting topline later.
|
||
setlocal nu cpo+=n
|
||
exe "norm! G$g013\<C-Y>"
|
||
redraw
|
||
call assert_equal(2, line('.'))
|
||
call assert_equal(0, winsaveview().skipcol)
|
||
|
||
set cpo-=n
|
||
bwipe!
|
||
endfunc
|
||
|
||
func Test_smoothscroll_long_line_zb()
|
||
call NewWindow(10, 40)
|
||
call setline(1, 'abcde '->repeat(150))
|
||
|
||
" Also works without 'smoothscroll' when last line of buffer doesn't fit.
|
||
" Used to set topline to buffer line count plus one, causing an empty screen.
|
||
norm zb
|
||
redraw
|
||
call assert_equal(1, winsaveview().topline)
|
||
|
||
" Moving cursor to bottom works on line that doesn't fit with 'smoothscroll'.
|
||
" Skipcol was adjusted later for cursor being on not visible part of line.
|
||
setlocal smoothscroll
|
||
norm zb
|
||
redraw
|
||
call assert_equal(520, winsaveview().skipcol)
|
||
|
||
bwipe!
|
||
endfunc
|
||
|
||
func Test_smooth_long_scrolloff_noruler()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
set smoothscroll scrolloff=3
|
||
set noruler
|
||
call setline(1, ['one', 'two long '->repeat(100), 'three', 'four', 'five', 'six'])
|
||
END
|
||
call writefile(lines, 'XSmoothLongScrolloff', 'D')
|
||
let buf = RunVimInTerminal('-u NONE -S XSmoothLongScrolloff', #{rows: 8, cols: 40})
|
||
call term_sendkeys(buf, ":norm j721|\<CR>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_1', {})
|
||
|
||
call term_sendkeys(buf, "gj")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_2', {})
|
||
|
||
call term_sendkeys(buf, "gj")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_3', {})
|
||
|
||
call term_sendkeys(buf, "gj")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_4', {})
|
||
|
||
call term_sendkeys(buf, "gj")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_5', {})
|
||
|
||
call term_sendkeys(buf, "gj")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_6', {})
|
||
|
||
call term_sendkeys(buf, "gk")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_7', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
func Test_smooth_long_scrolloff_ruler()
|
||
CheckScreendump
|
||
|
||
let lines =<< trim END
|
||
set smoothscroll scrolloff=3 ruler
|
||
call setline(1, ['one', 'two long '->repeat(100), 'three', 'four', 'five', 'six'])
|
||
END
|
||
call writefile(lines, 'XSmoothLongScrolloff', 'D')
|
||
let buf = RunVimInTerminal('-u NONE -S XSmoothLongScrolloff', #{rows: 8, cols: 40})
|
||
call term_sendkeys(buf, ":norm j721|\<CR>")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_ru_1', {})
|
||
|
||
call term_sendkeys(buf, "gj")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_ru_2', {})
|
||
|
||
call term_sendkeys(buf, "gj")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_ru_3', {})
|
||
|
||
call term_sendkeys(buf, "gj")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_ru_4', {})
|
||
|
||
call term_sendkeys(buf, "gj")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_ru_5', {})
|
||
|
||
call term_sendkeys(buf, "gj")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_ru_6', {})
|
||
|
||
call term_sendkeys(buf, "gk")
|
||
call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_ru_7', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
func Test_smoothscroll_listchars_eol()
|
||
call NewWindow(10, 40)
|
||
setlocal list listchars=eol:$ scrolloff=0 smoothscroll
|
||
call setline(1, repeat('-', 40))
|
||
call append(1, repeat(['foobar'], 10))
|
||
|
||
normal! G
|
||
call assert_equal(2, line('w0'))
|
||
call assert_equal(0, winsaveview().skipcol)
|
||
|
||
exe "normal! \<C-Y>"
|
||
call assert_equal(1, line('w0'))
|
||
call assert_equal(40, winsaveview().skipcol)
|
||
|
||
exe "normal! \<C-Y>"
|
||
call assert_equal(1, line('w0'))
|
||
call assert_equal(0, winsaveview().skipcol)
|
||
|
||
exe "normal! \<C-Y>"
|
||
call assert_equal(1, line('w0'))
|
||
call assert_equal(0, winsaveview().skipcol)
|
||
|
||
exe "normal! \<C-E>"
|
||
call assert_equal(1, line('w0'))
|
||
call assert_equal(40, winsaveview().skipcol)
|
||
|
||
exe "normal! \<C-E>"
|
||
call assert_equal(2, line('w0'))
|
||
call assert_equal(0, winsaveview().skipcol)
|
||
|
||
for ve in ['', 'all', 'onemore']
|
||
let &virtualedit = ve
|
||
normal! gg
|
||
call assert_equal(1, line('w0'))
|
||
call assert_equal(0, winsaveview().skipcol)
|
||
|
||
exe "normal! \<C-E>"
|
||
redraw " redrawing should not cause another scroll
|
||
call assert_equal(1, line('w0'))
|
||
call assert_equal(40, winsaveview().skipcol)
|
||
|
||
exe "normal! \<C-E>"
|
||
redraw
|
||
call assert_equal(2, line('w0'))
|
||
call assert_equal(0, winsaveview().skipcol)
|
||
|
||
if ve != 'all'
|
||
call assert_equal([0, 2, 1, 0], getpos('.'))
|
||
endif
|
||
endfor
|
||
|
||
set virtualedit&
|
||
bwipe!
|
||
endfunc
|
||
|
||
" scrolloffpad contract:
|
||
" - augment scrolloff only under EOF pressure (insufficient real lines below);
|
||
" - do not change explicit "z" viewport placement command semantics;
|
||
" - current scope is EOF-only, so BOF behavior remains unchanged.
|
||
func Test_scrolloffpad_zb_keeps_bottom_command_semantics()
|
||
new
|
||
resize 12
|
||
setlocal scrolloff=10
|
||
call setline(1, map(range(1, 300), 'printf("line %d", v:val)'))
|
||
|
||
setlocal scrolloffpad=0
|
||
normal! gg150Gzb
|
||
let baseline = [line('.'), line('w$'), winline()]
|
||
|
||
setlocal scrolloffpad=1
|
||
normal! gg150Gzb
|
||
call assert_equal(baseline, [line('.'), line('w$'), winline()])
|
||
|
||
bwipe!
|
||
endfunc
|
||
|
||
func Test_scrolloffpad_zminus_keeps_bottom_beginline_semantics()
|
||
new
|
||
resize 12
|
||
setlocal scrolloff=10
|
||
call setline(1, map(range(1, 300), 'printf(" line %d", v:val)'))
|
||
|
||
setlocal scrolloffpad=0
|
||
normal! gg150Gz-
|
||
let baseline = [line('.'), line('w$'), winline(), col('.')]
|
||
call assert_equal(match(getline('.'), '\S') + 1, col('.'))
|
||
|
||
setlocal scrolloffpad=1
|
||
normal! gg150Gz-
|
||
call assert_equal(baseline, [line('.'), line('w$'), winline(), col('.')])
|
||
call assert_equal(match(getline('.'), '\S') + 1, col('.'))
|
||
|
||
bwipe!
|
||
endfunc
|
||
|
||
func Test_scrolloffpad_zb_is_one_shot_then_scrolloff_reapplies()
|
||
new
|
||
resize 12
|
||
setlocal scrolloff=10
|
||
call setline(1, map(range(1, 300), 'printf("line %d", v:val)'))
|
||
|
||
let after_zb = {}
|
||
let after_j = {}
|
||
for sop in [0, 1]
|
||
let &l:scrolloffpad = sop
|
||
normal! gg150Gzb
|
||
let after_zb[sop] = [line('.'), line('w$'), winline(), winsaveview().topline]
|
||
|
||
normal! j
|
||
let after_j[sop] = [line('.'), line('w$'), winline(), winsaveview().topline]
|
||
call assert_notequal(after_zb[sop][3], after_j[sop][3])
|
||
call assert_true(line('.') < line('w$'))
|
||
endfor
|
||
call assert_equal(after_zb[0], after_zb[1])
|
||
call assert_equal(after_j[0], after_j[1])
|
||
|
||
bwipe!
|
||
endfunc
|
||
|
||
func Test_scrolloffpad_has_no_mid_buffer_effect()
|
||
new
|
||
resize 12
|
||
setlocal scrolloff=10 scrolloffpad=0
|
||
call setline(1, map(range(1, 500), 'printf("line %d", v:val)'))
|
||
|
||
normal! gg150G
|
||
let topline_without_pad = winsaveview().topline
|
||
|
||
setlocal scrolloffpad=1
|
||
normal! gg150G
|
||
let topline_with_pad = winsaveview().topline
|
||
|
||
call assert_equal(topline_without_pad, topline_with_pad)
|
||
|
||
bwipe!
|
||
endfunc
|
||
|
||
func Test_scrolloffpad_changes_eof_pressure_only()
|
||
new
|
||
resize 12
|
||
setlocal scrolloff=10 scrolloffpad=0
|
||
call setline(1, map(range(1, 200), 'printf("line %d", v:val)'))
|
||
|
||
normal! ggG
|
||
let view_without_pad = winsaveview()
|
||
let cursor_without_pad = line('.')
|
||
let row_without_pad = winline()
|
||
|
||
setlocal scrolloffpad=1
|
||
normal! ggG
|
||
let view_with_pad = winsaveview()
|
||
let row_with_pad = winline()
|
||
|
||
call assert_equal(line('$'), line('.'))
|
||
call assert_equal(cursor_without_pad, line('.'))
|
||
call assert_notequal(view_without_pad.topline, view_with_pad.topline)
|
||
call assert_true(row_with_pad < row_without_pad)
|
||
|
||
bwipe!
|
||
endfunc
|
||
|
||
func Test_scrolloffpad_large_scrolloff_no_overflow()
|
||
new
|
||
resize 12
|
||
call setline(1, map(range(1, 200), 'printf("line %d", v:val)'))
|
||
setlocal scrolloff=2147483647 scrolloffpad=0
|
||
|
||
normal! ggG
|
||
let view_without_pad = winsaveview()
|
||
let row_without_pad = winline()
|
||
|
||
setlocal scrolloffpad=1
|
||
normal! ggG
|
||
let view_with_pad = winsaveview()
|
||
let row_with_pad = winline()
|
||
|
||
call assert_equal(line('$'), line('.'))
|
||
call assert_notequal(view_without_pad.topline, view_with_pad.topline)
|
||
call assert_true(row_with_pad < row_without_pad)
|
||
|
||
bwipe!
|
||
endfunc
|
||
|
||
func Test_scrolloffpad_boolean_gate_values()
|
||
new
|
||
resize 12
|
||
setlocal scrolloff=10
|
||
call setline(1, map(range(1, 200), 'printf("line %d", v:val)'))
|
||
|
||
let views = {}
|
||
let rows = {}
|
||
for sop in [0, 1, 2]
|
||
let &l:scrolloffpad = sop
|
||
normal! ggG
|
||
let views[sop] = winsaveview()
|
||
let rows[sop] = winline()
|
||
call assert_equal(line('$'), line('.'))
|
||
endfor
|
||
|
||
call assert_equal(views[1].topline, views[2].topline)
|
||
call assert_equal(rows[1], rows[2])
|
||
call assert_notequal(views[0].topline, views[1].topline)
|
||
call assert_true(rows[1] < rows[0])
|
||
|
||
bwipe!
|
||
endfunc
|
||
|
||
func Test_scrolloffpad_requires_scrolloff_nonzero()
|
||
new
|
||
resize 12
|
||
call setline(1, map(range(1, 200), 'printf("line %d", v:val)'))
|
||
|
||
let states = {}
|
||
for so in [0, 10]
|
||
let states[so] = {}
|
||
for sop in [0, 1]
|
||
let &l:scrolloff = so
|
||
let &l:scrolloffpad = sop
|
||
normal! ggG
|
||
let states[so][sop] = [line('.'), line('w0'), line('w$'), winline()]
|
||
call assert_equal(line('$'), line('.'))
|
||
endfor
|
||
endfor
|
||
|
||
call assert_equal(states[0][0], states[0][1])
|
||
call assert_notequal(states[10][0], states[10][1])
|
||
call assert_true(states[10][1][3] < states[10][0][3])
|
||
|
||
bwipe!
|
||
endfunc
|
||
|
||
func Test_scrolloffpad_search_to_eof()
|
||
new
|
||
resize 12
|
||
setlocal scrolloff=10
|
||
call setline(1, map(range(1, 200), 'printf("line %d", v:val)'))
|
||
call setline(line('$'), 'EOF TARGET')
|
||
|
||
let states = {}
|
||
for sop in [0, 1]
|
||
let &l:scrolloffpad = sop
|
||
normal! gg
|
||
call assert_true(search('EOF TARGET') > 0)
|
||
let states[sop] = [line('.'), line('w0'), line('w$'), winline()]
|
||
call assert_equal(line('$'), line('.'))
|
||
endfor
|
||
|
||
call assert_notequal(states[0], states[1])
|
||
call assert_true(states[1][3] < states[0][3])
|
||
|
||
bwipe!
|
||
endfunc
|
||
|
||
func Test_scrolloffpad_paging_to_eof()
|
||
new
|
||
resize 12
|
||
setlocal scrolloff=10
|
||
call setline(1, map(range(1, 240), 'printf("line %d", v:val)'))
|
||
|
||
let states = {}
|
||
for sop in [0, 1]
|
||
let &l:scrolloffpad = sop
|
||
normal! gg
|
||
|
||
let prev = -1
|
||
for _ in range(1, 200)
|
||
execute "normal! \<C-D>"
|
||
if line('.') == prev
|
||
break
|
||
endif
|
||
let prev = line('.')
|
||
endfor
|
||
|
||
let states[sop] = [line('.'), line('w0'), line('w$'), winline()]
|
||
call assert_equal(line('$'), line('w$'))
|
||
endfor
|
||
|
||
call assert_notequal(states[0], states[1])
|
||
call assert_true(states[1][3] < states[0][3])
|
||
|
||
bwipe!
|
||
endfunc
|
||
|
||
func Test_scrolloffpad_autocmd_append_at_eof()
|
||
let states = {}
|
||
for sop in [0, 1]
|
||
new
|
||
resize 12
|
||
setlocal scrolloff=10
|
||
let &l:scrolloffpad = sop
|
||
call setline(1, map(range(1, 120), 'printf("line %d", v:val)'))
|
||
|
||
let b:scrolloffpad_appended = 0
|
||
augroup ScrolloffpadAppendAtEof
|
||
autocmd!
|
||
autocmd CursorMoved <buffer> if b:scrolloffpad_appended == 0 && line('.') == line('$') | call append('$', 'appended') | let b:scrolloffpad_appended = 1 | endif
|
||
augroup END
|
||
|
||
normal! ggG
|
||
doautocmd <nomodeline> CursorMoved
|
||
let states[sop] = [
|
||
\ line('.'),
|
||
\ line('$'),
|
||
\ line('w0'),
|
||
\ line('w$'),
|
||
\ winline(),
|
||
\ b:scrolloffpad_appended,
|
||
\ ]
|
||
|
||
call assert_equal(1, b:scrolloffpad_appended)
|
||
call assert_equal(states[sop][1] - 1, states[sop][0])
|
||
|
||
augroup ScrolloffpadAppendAtEof
|
||
autocmd!
|
||
augroup END
|
||
bwipe!
|
||
endfor
|
||
|
||
call assert_notequal(states[0], states[1])
|
||
call assert_true(states[1][4] < states[0][4])
|
||
|
||
endfunc
|
||
|
||
func Test_scrolloffpad_eof_no_reverse_scroll_on_j()
|
||
new
|
||
resize 20
|
||
setlocal scrolloff=20 scrolloffpad=1
|
||
call setline(1, map(range(1, 80), 'printf("line %d", v:val)'))
|
||
|
||
normal! gg
|
||
let prev_topline = winsaveview().topline
|
||
for lnum in range(2, line('$'))
|
||
normal! j
|
||
let cur_topline = winsaveview().topline
|
||
call assert_true(
|
||
\ cur_topline >= prev_topline,
|
||
\ printf('topline moved backwards at line %d: %d -> %d',
|
||
\ lnum, prev_topline, cur_topline))
|
||
let prev_topline = cur_topline
|
||
endfor
|
||
|
||
bwipe!
|
||
endfunc
|
||
|
||
func Test_scrolloffpad_bof_unchanged()
|
||
new
|
||
resize 12
|
||
setlocal scrolloff=10 scrolloffpad=0
|
||
call setline(1, map(range(1, 200), 'printf("line %d", v:val)'))
|
||
|
||
normal! Ggg
|
||
let view_without_pad = winsaveview()
|
||
let w0_without_pad = line('w0')
|
||
|
||
setlocal scrolloffpad=1
|
||
normal! Ggg
|
||
let view_with_pad = winsaveview()
|
||
let w0_with_pad = line('w0')
|
||
|
||
call assert_equal(1, w0_without_pad)
|
||
call assert_equal(1, w0_with_pad)
|
||
call assert_equal(view_without_pad.topline, view_with_pad.topline)
|
||
|
||
bwipe!
|
||
endfunc
|
||
|
||
func Test_scrolloffpad_mouse_drag_uses_drag_scrolloff()
|
||
CheckFeature mouse
|
||
|
||
let save_mouse = &mouse
|
||
set mouse=a
|
||
|
||
new
|
||
resize 20
|
||
call setline(1, map(range(1, 240), 'printf("line %d", v:val)'))
|
||
setlocal scrolloff=50
|
||
|
||
let after_drag = {}
|
||
for sop in [0, 1]
|
||
let &l:scrolloffpad = sop
|
||
normal! gg160Gzt
|
||
normal! v
|
||
call Ntest_setmouse(2, 1)
|
||
call feedkeys("\<LeftMouse>", 'xt')
|
||
call Ntest_setmouse(3, 1)
|
||
call feedkeys("\<LeftDrag>", 'xt')
|
||
let after_drag[sop] = [winsaveview().topline, line('.'), winline()]
|
||
call feedkeys("\<Esc>", 'xt')
|
||
endfor
|
||
|
||
call assert_equal(after_drag[0], after_drag[1])
|
||
|
||
bwipe!
|
||
let &mouse = save_mouse
|
||
endfunc
|
||
|
||
func Test_scrolloffpad_basic()
|
||
CheckScreendump
|
||
CheckRunVimInTerminal
|
||
|
||
let save_termwinsize = &termwinsize
|
||
set termwinsize=
|
||
|
||
let lines =<< trim END
|
||
set scrolloff=10
|
||
set scrolloffpad=5
|
||
enew!
|
||
call setline(1, map(range(1, 100), 'printf("line %d", v:val)'))
|
||
normal! gg
|
||
END
|
||
call writefile(lines, 'XScrolloffpadBasic', 'D')
|
||
|
||
let buf = RunVimInTerminal('-S XScrolloffpadBasic', {'rows': 20, 'cols': 78})
|
||
|
||
" Enabled: scrolloffpad > 0, expect EOF centering/padding
|
||
call term_sendkeys(buf, "\<Esc>:\<C-U>normal! G\<CR>")
|
||
call term_sendkeys(buf, "\<C-L>")
|
||
call TermWait(buf)
|
||
call VerifyScreenDump(buf, 'Test_scrolloffpad_basic_1', {})
|
||
|
||
" Beginning-of-file is unchanged (Top)
|
||
call term_sendkeys(buf, "\<Esc>:\<C-U>normal! gg\<CR>")
|
||
call term_sendkeys(buf, "\<C-L>")
|
||
call TermWait(buf)
|
||
call VerifyScreenDump(buf, 'Test_scrolloffpad_basic_2', {})
|
||
|
||
" Gating: disable scrolloffpad, then go to EOF again
|
||
" Expect normal EOF behavior (no extra centering/padding)
|
||
call term_sendkeys(buf, "\<Esc>:\<C-U>set scrolloffpad=0\<CR>")
|
||
call term_sendkeys(buf, "\<Esc>:\<C-U>normal! G\<CR>")
|
||
call term_sendkeys(buf, "\<C-L>")
|
||
call TermWait(buf)
|
||
call VerifyScreenDump(buf, 'Test_scrolloffpad_basic_3', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
let &termwinsize = save_termwinsize
|
||
endfunc
|
||
|
||
func Test_scrolloffpad_smoothscroll()
|
||
CheckScreendump
|
||
CheckRunVimInTerminal
|
||
|
||
let save_termwinsize = &termwinsize
|
||
set termwinsize=
|
||
|
||
let lines =<< trim END
|
||
set smoothscroll scrolloff=10 scrolloffpad=1
|
||
enew!
|
||
call setline(1, map(range(1, 100), 'printf("line %d", v:val)'))
|
||
normal! gg
|
||
END
|
||
call writefile(lines, 'XScrolloffpadSmoothscroll', 'D')
|
||
|
||
let buf = RunVimInTerminal('-S XScrolloffpadSmoothscroll', #{rows: 20, cols: 78})
|
||
|
||
call term_sendkeys(buf, "\<Esc>:\<C-U>normal! G\<CR>")
|
||
call term_sendkeys(buf, "\<C-L>")
|
||
call TermWait(buf)
|
||
call VerifyScreenDump(buf, 'Test_scrolloffpad_smoothscroll_1', {})
|
||
|
||
call term_sendkeys(buf, "\<Esc>:\<C-U>call setline(line('$'), repeat('LONG ', 30))\<CR>")
|
||
call term_sendkeys(buf, "\<Esc>:\<C-U>normal! 41|\<CR>")
|
||
call term_sendkeys(buf, "\<C-L>")
|
||
call TermWait(buf)
|
||
call VerifyScreenDump(buf, 'Test_scrolloffpad_smoothscroll_2', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
let &termwinsize = save_termwinsize
|
||
endfunc
|
||
|
||
func Test_scrolloffpad_insert_eof()
|
||
let save_so = &scrolloff
|
||
let save_sop = &scrolloffpad
|
||
|
||
set scrolloff=10 scrolloffpad=1
|
||
enew!
|
||
call setline(1, map(range(1, 200), 'printf("line %d", v:val)'))
|
||
normal! G
|
||
|
||
let topline_before = winsaveview().topline
|
||
call feedkeys("i\<Esc>", 'xt')
|
||
call assert_equal(topline_before, winsaveview().topline)
|
||
|
||
exe "normal! \<C-E>"
|
||
let topline_after = winsaveview().topline
|
||
call feedkeys("i\<Esc>", 'xt')
|
||
call assert_equal(topline_after, winsaveview().topline)
|
||
|
||
let &scrolloff = save_so
|
||
let &scrolloffpad = save_sop
|
||
bwipe!
|
||
endfunc
|
||
|
||
func Test_scrolloffpad_in_diff_mode()
|
||
CheckFeature diff
|
||
|
||
let save_so = &scrolloff
|
||
let save_sop = &scrolloffpad
|
||
let save_splitright = &splitright
|
||
|
||
set nosplitright
|
||
set scrolloff=10
|
||
set scrolloffpad=0
|
||
|
||
enew
|
||
call setline(1, map(range(1, 100), {_, v -> 'line ' .. v}))
|
||
diffthis
|
||
|
||
vnew
|
||
call setline(1, map(range(1, 100), {_, v -> 'line ' .. v}))
|
||
" Make buffers minimally different to avoid diff folding everything.
|
||
call setline(50, 'DIFF LINE 50')
|
||
diffthis
|
||
|
||
windo normal! zR
|
||
windo normal! gg
|
||
wincmd =
|
||
|
||
let rows_without = []
|
||
let rows_with = []
|
||
let near_states = []
|
||
let eof_states = []
|
||
for sop in [0, 1]
|
||
let &scrolloffpad = sop
|
||
|
||
" Near EOF with real text visible in both windows.
|
||
windo normal! 99G
|
||
for w in range(1, winnr('$'))
|
||
execute w .. 'wincmd w'
|
||
let state = [line('.'), line('w0'), line('w$'), winline()]
|
||
call assert_equal(99, state[0])
|
||
call assert_equal(100, state[2])
|
||
if sop == 0
|
||
call add(near_states, state)
|
||
endif
|
||
endfor
|
||
call assert_equal(near_states[0], near_states[1])
|
||
|
||
" EOF in both windows: scrolloffpad should raise the cursor row.
|
||
windo normal! G
|
||
for w in range(1, winnr('$'))
|
||
execute w .. 'wincmd w'
|
||
let state = [line('.'), line('w0'), line('w$'), winline()]
|
||
call assert_equal(line('$'), state[0])
|
||
if sop == 0
|
||
call add(eof_states, state)
|
||
call add(rows_without, state[3])
|
||
else
|
||
call add(rows_with, state[3])
|
||
endif
|
||
endfor
|
||
call assert_equal(eof_states[0], eof_states[1])
|
||
endfor
|
||
|
||
call assert_true(rows_with[0] < rows_without[0])
|
||
call assert_true(rows_with[1] < rows_without[1])
|
||
|
||
windo diffoff
|
||
%bwipe!
|
||
let &scrolloff = save_so
|
||
let &scrolloffpad = save_sop
|
||
let &splitright = save_splitright
|
||
endfunc
|
||
|
||
func Test_scrolloffpad_diff_eof_filler_behavior()
|
||
CheckFeature diff
|
||
|
||
let save_so = &scrolloff
|
||
let save_sop = &scrolloffpad
|
||
let save_diffopt = &diffopt
|
||
let save_splitright = &splitright
|
||
|
||
set diffopt+=filler
|
||
set scrolloff=10
|
||
set scrolloffpad=0
|
||
set nosplitright
|
||
|
||
20new
|
||
call setline(1, map(range(1, 100), {_, v -> 'left ' .. v}))
|
||
diffthis
|
||
let short_wid = win_getid()
|
||
|
||
vnew
|
||
call setline(1, map(range(1, 120), {_, v -> 'right ' .. v}))
|
||
diffthis
|
||
let long_wid = win_getid()
|
||
|
||
call assert_true(win_gotoid(short_wid))
|
||
let short_height = winheight(0)
|
||
call assert_true(win_gotoid(long_wid))
|
||
let long_height = winheight(0)
|
||
call assert_equal(short_height, long_height)
|
||
call assert_equal(20, short_height)
|
||
|
||
let ordered_diff_wids = [long_wid, short_wid]
|
||
let states = {}
|
||
for sop in [0, 1]
|
||
execute 'set scrolloffpad=' .. sop
|
||
for wid in ordered_diff_wids
|
||
call assert_true(win_gotoid(wid))
|
||
normal! gg
|
||
endfor
|
||
for wid in ordered_diff_wids
|
||
call assert_true(win_gotoid(wid))
|
||
normal! G
|
||
endfor
|
||
|
||
call assert_true(win_gotoid(short_wid))
|
||
let short_view = winsaveview()
|
||
let short_state = [
|
||
\ line('.'),
|
||
\ line('$'),
|
||
\ winline(),
|
||
\ short_view.topline,
|
||
\ short_view.topfill,
|
||
\ diff_filler(line('$') + 1),
|
||
\ ]
|
||
call assert_equal(short_state[1], short_state[0])
|
||
call assert_true(short_state[5] > 0)
|
||
|
||
call assert_true(win_gotoid(long_wid))
|
||
let long_view = winsaveview()
|
||
let long_state = [
|
||
\ line('.'),
|
||
\ line('$'),
|
||
\ winline(),
|
||
\ long_view.topline,
|
||
\ long_view.topfill,
|
||
\ ]
|
||
call assert_true(long_state[0] > 0 && long_state[0] <= long_state[1])
|
||
call assert_equal(short_state[0], long_state[0])
|
||
|
||
let states[sop] = [short_state, long_state]
|
||
endfor
|
||
|
||
let short_without = states[0][0]
|
||
let short_with = states[1][0]
|
||
" Environment/layout can shift direction of movement; require only that
|
||
" scrolloffpad changes the short-window viewport state under EOF filler.
|
||
call assert_true(short_with[2] != short_without[2]
|
||
\ || short_with[3] != short_without[3]
|
||
\ || short_with[4] != short_without[4])
|
||
|
||
windo diffoff
|
||
call assert_true(win_gotoid(short_wid))
|
||
only!
|
||
%bwipe!
|
||
let &scrolloff = save_so
|
||
let &scrolloffpad = save_sop
|
||
let &diffopt = save_diffopt
|
||
let &splitright = save_splitright
|
||
endfunc
|
||
|
||
func Test_scrolloffpad_with_folds()
|
||
CheckScreendump
|
||
CheckRunVimInTerminal
|
||
CheckFeature folding
|
||
|
||
let save_termwinsize = &termwinsize
|
||
set termwinsize=
|
||
|
||
let lines =<< trim END
|
||
set scrolloff=10
|
||
set scrolloffpad=1
|
||
|
||
enew
|
||
call setline(1, map(range(1, 120), {_, v -> 'line ' . v}))
|
||
|
||
" Create a large fold near the end of the file.
|
||
" Fold lines 60-110, leaving 111-120 visible after the fold.
|
||
set foldmethod=manual
|
||
set foldenable
|
||
normal! gg
|
||
normal! 60G
|
||
normal! zf50j
|
||
normal! gg
|
||
END
|
||
call writefile(lines, 'XScrolloffpadFolds', 'D')
|
||
|
||
let buf = RunVimInTerminal('-S XScrolloffpadFolds', #{rows: 20, cols: 78})
|
||
|
||
" Case 1: Jump to end-of-file
|
||
" With folds present, scrolloffpad should still
|
||
" keep the cursor positioned with padding below EOF
|
||
call term_sendkeys(buf, "\<Esc>:\<C-U>normal! G\<CR>")
|
||
call term_sendkeys(buf, "\<C-L>")
|
||
call TermWait(buf)
|
||
call VerifyScreenDump(buf, 'Test_scrolloffpad_folds_1', {})
|
||
|
||
" Case 2: Move to the folded line to ensure the fold is actually in view
|
||
call term_sendkeys(buf, "\<Esc>:\<C-U>normal! 60G\<CR>")
|
||
call term_sendkeys(buf, "\<C-L>")
|
||
call TermWait(buf)
|
||
call VerifyScreenDump(buf, 'Test_scrolloffpad_folds_2', {})
|
||
|
||
" Case 3: Close the fold explicitly and go to EOF again
|
||
" Behavior should remain stable with closed folds
|
||
call term_sendkeys(buf, "\<Esc>:\<C-U>normal! zc\<CR>")
|
||
call term_sendkeys(buf, "\<Esc>:\<C-U>normal! G\<CR>")
|
||
call term_sendkeys(buf, "\<C-L>")
|
||
call TermWait(buf)
|
||
call VerifyScreenDump(buf, 'Test_scrolloffpad_folds_3', {})
|
||
|
||
call StopVimInTerminal(buf)
|
||
let &termwinsize = save_termwinsize
|
||
endfunc
|
||
|
||
" Resizing to "textoff" after 'smoothscroll' skips part of a wrapped line must
|
||
" not crash.
|
||
func Test_smoothscroll_textoff_showbreak()
|
||
CheckOption smoothscroll
|
||
CheckRunVimInTerminal
|
||
|
||
let donefile = 'XTest_crash_textoff_showbreak_done'
|
||
defer delete(donefile)
|
||
let lines =<< trim END
|
||
set noswapfile
|
||
|
||
set scrolloff=0
|
||
set lines=12 columns=40
|
||
|
||
call setline(1, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
|
||
set number wrap smoothscroll showbreak=>
|
||
vsplit
|
||
|
||
let textoff = getwininfo(win_getid())[0].textoff
|
||
execute "normal! 0\<C-E>"
|
||
redraw
|
||
execute 'vertical resize' textoff
|
||
redraw
|
||
call writefile(['done'], 'XTest_crash_textoff_showbreak_done')
|
||
END
|
||
call writefile(lines, 'XTest_crash_textoff_showbreak', 'D')
|
||
|
||
let buf = 0
|
||
let buf = term_start([GetVimProg(), '--clean'], #{term_rows: 24, term_cols: 80})
|
||
call TermWait(buf, 200)
|
||
call term_sendkeys(buf, ":source XTest_crash_textoff_showbreak\<CR>")
|
||
call WaitForAssert({-> assert_true(filereadable(donefile))})
|
||
let status = term_getstatus(buf)
|
||
call assert_equal('running', status)
|
||
call assert_true(filereadable(donefile))
|
||
call StopVimInTerminal(buf)
|
||
endfunc
|
||
|
||
" vim: shiftwidth=2 sts=2 expandtab
|