neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

test_scroll_opt.vim (44327B)


      1 " Test for 'scroll', 'scrolloff', 'smoothscroll', etc.
      2 
      3 source check.vim
      4 source screendump.vim
      5 source mouse.vim
      6 
      7 func Test_reset_scroll()
      8  let scr = &l:scroll
      9 
     10  setlocal scroll=1
     11  setlocal scroll&
     12  call assert_equal(scr, &l:scroll)
     13 
     14  setlocal scroll=1
     15  setlocal scroll=0
     16  call assert_equal(scr, &l:scroll)
     17 
     18  try
     19    execute 'setlocal scroll=' . (winheight(0) + 1)
     20    " not reached
     21    call assert_false(1)
     22  catch
     23    call assert_exception('E49:')
     24  endtry
     25 
     26  split
     27 
     28  let scr = &l:scroll
     29 
     30  setlocal scroll=1
     31  setlocal scroll&
     32  call assert_equal(scr, &l:scroll)
     33 
     34  setlocal scroll=1
     35  setlocal scroll=0
     36  call assert_equal(scr, &l:scroll)
     37 
     38  quit!
     39 endfunc
     40 
     41 func Test_scolloff_even_line_count()
     42  new
     43  resize 6
     44  setlocal scrolloff=3
     45  call setline(1, range(20))
     46  normal 2j
     47  call assert_equal(1, getwininfo(win_getid())[0].topline)
     48  normal j
     49  call assert_equal(1, getwininfo(win_getid())[0].topline)
     50  normal j
     51  call assert_equal(2, getwininfo(win_getid())[0].topline)
     52  normal j
     53  call assert_equal(3, getwininfo(win_getid())[0].topline)
     54 
     55  bwipe!
     56 endfunc
     57 
     58 func Test_mouse_scroll_inactive_with_cursorbind()
     59  for scb in [0, 1]
     60    for so in [0, 1, 2]
     61      let msg = $'scb={scb} so={so}'
     62 
     63      new | only
     64      let w1 = win_getid()
     65      setlocal cursorbind
     66      let &l:scb = scb
     67      let &l:so = so
     68      call setline(1, range(101, 109))
     69      rightbelow vnew
     70      let w2 = win_getid()
     71      setlocal cursorbind
     72      let &l:scb = scb
     73      let &l:so = so
     74      call setline(1, range(101, 109))
     75 
     76      normal! $
     77      call assert_equal(3, col('.', w1), msg)
     78      call assert_equal(3, col('.', w2), msg)
     79      call Ntest_setmouse(1, 1)
     80      call feedkeys("\<ScrollWheelDown>", 'xt')
     81      call assert_equal(4, line('w0', w1), msg)
     82      call assert_equal(4 + so, line('.', w1), msg)
     83      call assert_equal(1, line('w0', w2), msg)
     84      call assert_equal(1, line('.', w2), msg)
     85      call feedkeys("\<ScrollWheelDown>", 'xt')
     86      call assert_equal(7, line('w0', w1), msg)
     87      call assert_equal(7 + so, line('.', w1), msg)
     88      call assert_equal(1, line('w0', w2), msg)
     89      call assert_equal(1, line('.', w2), msg)
     90      call feedkeys("\<ScrollWheelUp>", 'xt')
     91      call assert_equal(4, line('w0', w1), msg)
     92      call assert_equal(7 + so, line('.', w1), msg)
     93      call assert_equal(1, line('w0', w2), msg)
     94      call assert_equal(1, line('.', w2), msg)
     95      call feedkeys("\<ScrollWheelUp>", 'xt')
     96      call assert_equal(1, line('w0', w1), msg)
     97      call assert_equal(7 + so, line('.', w1), msg)
     98      call assert_equal(1, line('w0', w2), msg)
     99      call assert_equal(1, line('.', w2), msg)
    100      normal! 0
    101      call assert_equal(1, line('.', w1), msg)
    102      call assert_equal(1, col('.', w1), msg)
    103      call assert_equal(1, line('.', w2), msg)
    104      call assert_equal(1, col('.', w2), msg)
    105 
    106      bwipe!
    107      bwipe!
    108    endfor
    109  endfor
    110 endfunc
    111 
    112 func Test_CtrlE_CtrlY_stop_at_end()
    113  enew
    114  call setline(1, ['one', 'two'])
    115  set number
    116  exe "normal \<C-Y>"
    117  call assert_equal(["  1 one   "], ScreenLines(1, 10))
    118  exe "normal \<C-E>\<C-E>\<C-E>"
    119  call assert_equal(["  2 two   "], ScreenLines(1, 10))
    120 
    121  bwipe!
    122  set nonumber
    123 endfunc
    124 
    125 func Test_smoothscroll_CtrlE_CtrlY()
    126  CheckScreendump
    127 
    128  let lines =<< trim END
    129      vim9script
    130      setline(1, [
    131        'line one',
    132        'word '->repeat(20),
    133        'line three',
    134        'long word '->repeat(7),
    135        'line',
    136        'line',
    137        'line',
    138      ])
    139      set smoothscroll
    140      :5
    141  END
    142  call writefile(lines, 'XSmoothScroll', 'D')
    143  let buf = RunVimInTerminal('-S XSmoothScroll', #{rows: 12, cols: 40})
    144 
    145  call term_sendkeys(buf, "\<C-E>")
    146  call VerifyScreenDump(buf, 'Test_smoothscroll_1', {})
    147  call term_sendkeys(buf, "\<C-E>")
    148  call VerifyScreenDump(buf, 'Test_smoothscroll_2', {})
    149  call term_sendkeys(buf, "\<C-E>")
    150  call VerifyScreenDump(buf, 'Test_smoothscroll_3', {})
    151  call term_sendkeys(buf, "\<C-E>")
    152  call VerifyScreenDump(buf, 'Test_smoothscroll_4', {})
    153 
    154  call term_sendkeys(buf, "\<C-Y>")
    155  call VerifyScreenDump(buf, 'Test_smoothscroll_5', {})
    156  call term_sendkeys(buf, "\<C-Y>")
    157  call VerifyScreenDump(buf, 'Test_smoothscroll_6', {})
    158  call term_sendkeys(buf, "\<C-Y>")
    159  call VerifyScreenDump(buf, 'Test_smoothscroll_7', {})
    160  call term_sendkeys(buf, "\<C-Y>")
    161  call VerifyScreenDump(buf, 'Test_smoothscroll_8', {})
    162 
    163  if has('folding')
    164    call term_sendkeys(buf, ":set foldmethod=indent\<CR>")
    165    " move the cursor so we can reuse the same dumps
    166    call term_sendkeys(buf, "5G")
    167    call term_sendkeys(buf, "\<C-E>")
    168    call VerifyScreenDump(buf, 'Test_smoothscroll_1', {})
    169    call term_sendkeys(buf, "\<C-E>")
    170    call VerifyScreenDump(buf, 'Test_smoothscroll_2', {})
    171    call term_sendkeys(buf, "7G")
    172    call term_sendkeys(buf, "\<C-Y>")
    173    call VerifyScreenDump(buf, 'Test_smoothscroll_7', {})
    174    call term_sendkeys(buf, "\<C-Y>")
    175    call VerifyScreenDump(buf, 'Test_smoothscroll_8', {})
    176  endif
    177 
    178  call StopVimInTerminal(buf)
    179 endfunc
    180 
    181 func Test_smoothscroll_multibyte()
    182  CheckScreendump
    183 
    184  let lines =<< trim END
    185      set scrolloff=0 smoothscroll
    186      call setline(1, [repeat('ϛ', 45), repeat('2', 36)])
    187      exe "normal G35l\<C-E>k"
    188  END
    189  call writefile(lines, 'XSmoothMultibyte', 'D')
    190  let buf = RunVimInTerminal('-S XSmoothMultibyte', #{rows: 6, cols: 40})
    191  call VerifyScreenDump(buf, 'Test_smoothscroll_multi_1', {})
    192 
    193  call StopVimInTerminal(buf)
    194 endfunc
    195 
    196 func Test_smoothscroll_number()
    197  CheckScreendump
    198 
    199  let lines =<< trim END
    200      vim9script
    201      setline(1, [
    202        'one ' .. 'word '->repeat(20),
    203        'two ' .. 'long word '->repeat(7),
    204        'line',
    205        'line',
    206        'line',
    207      ])
    208      set smoothscroll
    209      set splitkeep=topline
    210      set number cpo+=n
    211      :3
    212 
    213      def g:DoRel()
    214        set number relativenumber scrolloff=0
    215        :%del
    216        setline(1, [
    217          'one',
    218          'very long text '->repeat(12),
    219          'three',
    220        ])
    221        exe "normal 2Gzt\<C-E>"
    222      enddef
    223  END
    224  call writefile(lines, 'XSmoothNumber', 'D')
    225  let buf = RunVimInTerminal('-S XSmoothNumber', #{rows: 12, cols: 40})
    226 
    227  call VerifyScreenDump(buf, 'Test_smooth_number_1', {})
    228  call term_sendkeys(buf, "\<C-E>")
    229  call VerifyScreenDump(buf, 'Test_smooth_number_2', {})
    230  call term_sendkeys(buf, "\<C-E>")
    231  call VerifyScreenDump(buf, 'Test_smooth_number_3', {})
    232 
    233  call term_sendkeys(buf, ":set cpo-=n\<CR>")
    234  call VerifyScreenDump(buf, 'Test_smooth_number_4', {})
    235  call term_sendkeys(buf, "\<C-Y>")
    236  call VerifyScreenDump(buf, 'Test_smooth_number_5', {})
    237  call term_sendkeys(buf, "\<C-Y>")
    238  call VerifyScreenDump(buf, 'Test_smooth_number_6', {})
    239 
    240  call term_sendkeys(buf, ":botright split\<CR>\<C-L>gg")
    241  call VerifyScreenDump(buf, 'Test_smooth_number_7', {})
    242  call term_sendkeys(buf, "\<C-E>")
    243  call VerifyScreenDump(buf, 'Test_smooth_number_8', {})
    244  call term_sendkeys(buf, "\<C-E>")
    245  call VerifyScreenDump(buf, 'Test_smooth_number_9', {})
    246  call term_sendkeys(buf, ":close\<CR>")
    247 
    248  call term_sendkeys(buf, ":call DoRel()\<CR>")
    249  call VerifyScreenDump(buf, 'Test_smooth_number_10', {})
    250 
    251  call StopVimInTerminal(buf)
    252 endfunc
    253 
    254 func Test_smoothscroll_list()
    255  CheckScreendump
    256 
    257  let lines =<< trim END
    258      vim9script
    259      set smoothscroll scrolloff=0
    260      set list
    261      setline(1, [
    262        'one',
    263        'very long text '->repeat(12),
    264        'three',
    265      ])
    266      exe "normal 2Gzt\<C-E>"
    267  END
    268  call writefile(lines, 'XSmoothList', 'D')
    269  let buf = RunVimInTerminal('-S XSmoothList', #{rows: 8, cols: 40})
    270 
    271  call VerifyScreenDump(buf, 'Test_smooth_list_1', {})
    272 
    273  call term_sendkeys(buf, ":set listchars+=precedes:#\<CR>")
    274  call VerifyScreenDump(buf, 'Test_smooth_list_2', {})
    275 
    276  call StopVimInTerminal(buf)
    277 endfunc
    278 
    279 func Test_smoothscroll_diff_mode()
    280  CheckScreendump
    281  CheckFeature diff
    282 
    283  let lines =<< trim END
    284      vim9script
    285      var text = 'just some text here'
    286      setline(1, text)
    287      set smoothscroll
    288      diffthis
    289      new
    290      setline(1, text)
    291      set smoothscroll
    292      diffthis
    293  END
    294  call writefile(lines, 'XSmoothDiff', 'D')
    295  let buf = RunVimInTerminal('-S XSmoothDiff', #{rows: 8})
    296 
    297  call VerifyScreenDump(buf, 'Test_smooth_diff_1', {})
    298  call term_sendkeys(buf, "\<C-Y>")
    299  call VerifyScreenDump(buf, 'Test_smooth_diff_1', {})
    300  call term_sendkeys(buf, "\<C-E>")
    301  call VerifyScreenDump(buf, 'Test_smooth_diff_1', {})
    302 
    303  call StopVimInTerminal(buf)
    304 endfunc
    305 
    306 func Test_smoothscroll_diff_change_line_default()
    307  CheckScreendump
    308  CheckFeature diff
    309 
    310  " Uses the new diffopt default with indent-heuristic and inline:char
    311  let lines =<< trim END
    312    set diffopt=internal,filler,closeoff,indent-heuristic,inline:char,followwrap smoothscroll
    313    call setline(1, repeat(' abc', &columns))
    314    call setline(2, 'bar')
    315    call setline(3, repeat(' abc', &columns))
    316    vnew
    317    call setline(1, repeat(' abc', &columns))
    318    call setline(2, 'foo')
    319    call setline(3, 'bar')
    320    call setline(4, repeat(' abc', &columns))
    321    windo exe "normal! 2gg5\<C-E>"
    322    windo diffthis
    323  END
    324  call writefile(lines, 'XSmoothDiffChangeLine', 'D')
    325  let buf = RunVimInTerminal('-S XSmoothDiffChangeLine', #{rows: 20, columns: 55})
    326 
    327  call VerifyScreenDump(buf, 'Test_smooth_diff_change_line_1', {})
    328  call term_sendkeys(buf, "Abar")
    329  call VerifyScreenDump(buf, 'Test_smooth_diff_change_line_2', {})
    330  call term_sendkeys(buf, "\<Esc>")
    331  call VerifyScreenDump(buf, 'Test_smooth_diff_change_line_3a', {})
    332  call term_sendkeys(buf, "yyp")
    333  call VerifyScreenDump(buf, 'Test_smooth_diff_change_line_4', {})
    334 
    335  call StopVimInTerminal(buf)
    336 endfunc
    337 
    338 func Test_smoothscroll_diff_change_line()
    339  CheckScreendump
    340  CheckFeature diff
    341 
    342  " Uses the old diffopt default
    343  let lines =<< trim END
    344    set diffopt=internal,filler,closeoff,followwrap,inline:simple smoothscroll
    345    call setline(1, repeat(' abc', &columns))
    346    call setline(2, 'bar')
    347    call setline(3, repeat(' abc', &columns))
    348    vnew
    349    call setline(1, repeat(' abc', &columns))
    350    call setline(2, 'foo')
    351    call setline(3, 'bar')
    352    call setline(4, repeat(' abc', &columns))
    353    windo exe "normal! 2gg5\<C-E>"
    354    windo diffthis
    355  END
    356  call writefile(lines, 'XSmoothDiffChangeLine', 'D')
    357  let buf = RunVimInTerminal('-S XSmoothDiffChangeLine', #{rows: 20, columns: 55})
    358 
    359  call VerifyScreenDump(buf, 'Test_smooth_diff_change_line_1', {})
    360  call term_sendkeys(buf, "Abar")
    361  call VerifyScreenDump(buf, 'Test_smooth_diff_change_line_2', {})
    362  call term_sendkeys(buf, "\<Esc>")
    363  call VerifyScreenDump(buf, 'Test_smooth_diff_change_line_3', {})
    364  call term_sendkeys(buf, "yyp")
    365  call VerifyScreenDump(buf, 'Test_smooth_diff_change_line_4', {})
    366 
    367  call StopVimInTerminal(buf)
    368 endfunc
    369 
    370 func Test_smoothscroll_wrap_scrolloff_zero()
    371  CheckScreendump
    372 
    373  let lines =<< trim END
    374      vim9script
    375      setline(1, ['Line' .. (' with some text'->repeat(7))]->repeat(7))
    376      set smoothscroll scrolloff=0
    377      :3
    378  END
    379  call writefile(lines, 'XSmoothWrap', 'D')
    380  let buf = RunVimInTerminal('-S XSmoothWrap', #{rows: 8, cols: 40})
    381 
    382  call VerifyScreenDump(buf, 'Test_smooth_wrap_1', {})
    383 
    384  " moving cursor down - whole bottom line shows
    385  call term_sendkeys(buf, "j")
    386  call VerifyScreenDump(buf, 'Test_smooth_wrap_2', {})
    387 
    388  call term_sendkeys(buf, "\<C-E>j")
    389  call VerifyScreenDump(buf, 'Test_smooth_wrap_3', {})
    390 
    391  call term_sendkeys(buf, "G")
    392  call VerifyScreenDump(buf, 'Test_smooth_wrap_4', {})
    393 
    394  call term_sendkeys(buf, "4\<C-Y>G")
    395  call VerifyScreenDump(buf, 'Test_smooth_wrap_4', {})
    396 
    397  " moving cursor up right after the <<< marker - no need to show whole line
    398  call term_sendkeys(buf, "2gj3l2k")
    399  call VerifyScreenDump(buf, 'Test_smooth_wrap_5', {})
    400 
    401  " moving cursor up where the <<< marker is - whole top line shows
    402  call term_sendkeys(buf, "2j02k")
    403  call VerifyScreenDump(buf, 'Test_smooth_wrap_6', {})
    404 
    405  call StopVimInTerminal(buf)
    406 endfunc
    407 
    408 func Test_smoothscroll_wrap_long_line()
    409  CheckScreendump
    410 
    411  let lines =<< trim END
    412      vim9script
    413      setline(1, ['one', 'two', 'Line' .. (' with lots of text'->repeat(30)) .. ' end', 'four'])
    414      set smoothscroll scrolloff=0
    415      normal 3G10|zt
    416  END
    417  call writefile(lines, 'XSmoothWrap', 'D')
    418  let buf = RunVimInTerminal('-S XSmoothWrap', #{rows: 6, cols: 40})
    419  call VerifyScreenDump(buf, 'Test_smooth_long_1', {})
    420 
    421  " scrolling up, cursor moves screen line down
    422  call term_sendkeys(buf, "\<C-E>")
    423  call VerifyScreenDump(buf, 'Test_smooth_long_2', {})
    424  call term_sendkeys(buf, "5\<C-E>")
    425  call VerifyScreenDump(buf, 'Test_smooth_long_3', {})
    426 
    427  " scrolling down, cursor moves screen line up
    428  call term_sendkeys(buf, "5\<C-Y>")
    429  call VerifyScreenDump(buf, 'Test_smooth_long_4', {})
    430  call term_sendkeys(buf, "\<C-Y>")
    431  call VerifyScreenDump(buf, 'Test_smooth_long_5', {})
    432 
    433  " 'scrolloff' set to 1, scrolling up, cursor moves screen line down
    434  call term_sendkeys(buf, ":set scrolloff=1\<CR>")
    435  call term_sendkeys(buf, "10|\<C-E>")
    436  call VerifyScreenDump(buf, 'Test_smooth_long_6', {})
    437 
    438  " 'scrolloff' set to 1, scrolling down, cursor moves screen line up
    439  call term_sendkeys(buf, "\<C-E>")
    440  call term_sendkeys(buf, "gjgj")
    441  call term_sendkeys(buf, "\<C-Y>")
    442  call VerifyScreenDump(buf, 'Test_smooth_long_7', {})
    443 
    444  " 'scrolloff' set to 2, scrolling up, cursor moves screen line down
    445  call term_sendkeys(buf, ":set scrolloff=2\<CR>")
    446  call term_sendkeys(buf, "10|\<C-E>")
    447  call VerifyScreenDump(buf, 'Test_smooth_long_8', {})
    448 
    449  " 'scrolloff' set to 2, scrolling down, cursor moves screen line up
    450  call term_sendkeys(buf, "\<C-E>")
    451  call term_sendkeys(buf, "gj")
    452  call term_sendkeys(buf, "\<C-Y>")
    453  call VerifyScreenDump(buf, 'Test_smooth_long_9', {})
    454 
    455  " 'scrolloff' set to 0, move cursor down one line.
    456  " Cursor should move properly, and since this is a really long line, it will
    457  " be put on top of the screen.
    458  call term_sendkeys(buf, ":set scrolloff=0\<CR>")
    459  call term_sendkeys(buf, "0j")
    460  call VerifyScreenDump(buf, 'Test_smooth_long_10', {})
    461 
    462  " Test zt/zz/zb that they work properly when a long line is above it
    463  call term_sendkeys(buf, "zt")
    464  call VerifyScreenDump(buf, 'Test_smooth_long_11', {})
    465  call term_sendkeys(buf, "zz")
    466  call VerifyScreenDump(buf, 'Test_smooth_long_12', {})
    467  call term_sendkeys(buf, "zb")
    468  call VerifyScreenDump(buf, 'Test_smooth_long_13', {})
    469 
    470  " Repeat the step and move the cursor down again.
    471  " This time, use a shorter long line that is barely long enough to span more
    472  " than one window. Note that the cursor is at the bottom this time because
    473  " Vim prefers to do so if we are scrolling a few lines only.
    474  call term_sendkeys(buf, ":call setline(1, ['one', 'two', 'Line' .. (' with lots of text'->repeat(10)) .. ' end', 'four'])\<CR>")
    475  " Currently visible lines were replaced, test that the lines and cursor
    476  " are correctly displayed.
    477  call VerifyScreenDump(buf, 'Test_smooth_long_14', {})
    478  call term_sendkeys(buf, "3Gzt")
    479  call term_sendkeys(buf, "j")
    480  call VerifyScreenDump(buf, 'Test_smooth_long_15', {})
    481 
    482  " Repeat the step but this time start it when the line is smooth-scrolled by
    483  " one line. This tests that the offset calculation is still correct and
    484  " still end up scrolling down to the next line with cursor at bottom of
    485  " screen.
    486  call term_sendkeys(buf, "3Gzt")
    487  call term_sendkeys(buf, "\<C-E>j")
    488  call VerifyScreenDump(buf, 'Test_smooth_long_16', {})
    489 
    490  call StopVimInTerminal(buf)
    491 endfunc
    492 
    493 func Test_smoothscroll_one_long_line()
    494  CheckScreendump
    495 
    496  let lines =<< trim END
    497      vim9script
    498      setline(1, 'with lots of text '->repeat(7))
    499      set smoothscroll scrolloff=0
    500  END
    501  call writefile(lines, 'XSmoothOneLong', 'D')
    502  let buf = RunVimInTerminal('-S XSmoothOneLong', #{rows: 6, cols: 40})
    503  call VerifyScreenDump(buf, 'Test_smooth_one_long_1', {})
    504 
    505  call term_sendkeys(buf, "\<C-E>")
    506  call VerifyScreenDump(buf, 'Test_smooth_one_long_2', {})
    507 
    508  call term_sendkeys(buf, "0")
    509  call VerifyScreenDump(buf, 'Test_smooth_one_long_1', {})
    510 
    511  call StopVimInTerminal(buf)
    512 endfunc
    513 
    514 func Test_smoothscroll_long_line_showbreak()
    515  CheckScreendump
    516 
    517  let lines =<< trim END
    518      vim9script
    519      # a line that spans four screen lines
    520      setline(1, 'with lots of text in one line '->repeat(6))
    521      set smoothscroll scrolloff=0 showbreak=+++\ 
    522  END
    523  call writefile(lines, 'XSmoothLongShowbreak', 'D')
    524  let buf = RunVimInTerminal('-S XSmoothLongShowbreak', #{rows: 6, cols: 40})
    525  call VerifyScreenDump(buf, 'Test_smooth_long_showbreak_1', {})
    526 
    527  call term_sendkeys(buf, "\<C-E>")
    528  call VerifyScreenDump(buf, 'Test_smooth_long_showbreak_2', {})
    529 
    530  call term_sendkeys(buf, "0")
    531  call VerifyScreenDump(buf, 'Test_smooth_long_showbreak_1', {})
    532 
    533  call StopVimInTerminal(buf)
    534 endfunc
    535 
    536 " Check that 'smoothscroll' marker is drawn over double-width char correctly.
    537 " Run with multiple encodings.
    538 func Test_smoothscroll_marker_over_double_width()
    539  " Run this in a separate Vim instance to avoid messing up.
    540  let after =<< trim [CODE]
    541    scriptencoding utf-8
    542    call setline(1, 'a'->repeat(&columns) .. '口'->repeat(10))
    543    setlocal smoothscroll
    544    redraw
    545    exe "norm \<C-E>"
    546    redraw
    547    " Check the chars one by one. Don't check the whole line concatenated.
    548    call assert_equal('<', screenstring(1, 1))
    549    call assert_equal('<', screenstring(1, 2))
    550    call assert_equal('<', screenstring(1, 3))
    551    call assert_equal(' ', screenstring(1, 4))
    552    call assert_equal('口', screenstring(1, 5))
    553    call assert_equal('口', screenstring(1, 7))
    554    call assert_equal('口', screenstring(1, 9))
    555    call assert_equal('口', screenstring(1, 11))
    556    call assert_equal('口', screenstring(1, 13))
    557    call assert_equal('口', screenstring(1, 15))
    558    call writefile(v:errors, 'Xresult')
    559    qall!
    560  [CODE]
    561 
    562  let encodings = ['utf-8', 'cp932', 'cp936', 'cp949', 'cp950']
    563  if !has('win32')
    564    let encodings += ['euc-jp']
    565  endif
    566  if has('nvim')
    567    let encodings = ['utf-8']
    568  endif
    569  for enc in encodings
    570    let msg = 'enc=' .. enc
    571    if RunVim([], after, $'--clean --cmd "set encoding={enc}"')
    572      call assert_equal([], readfile('Xresult'), msg)
    573    endif
    574    call delete('Xresult')
    575  endfor
    576 endfunc
    577 
    578 " Same as the test above, but check the text actually shown on screen.
    579 " Only run with UTF-8 encoding.
    580 func Test_smoothscroll_marker_over_double_width_dump()
    581  CheckScreendump
    582 
    583  let lines =<< trim END
    584    call setline(1, 'a'->repeat(&columns) .. '口'->repeat(10))
    585    setlocal smoothscroll
    586  END
    587  call writefile(lines, 'XSmoothMarkerOverDoubleWidth', 'D')
    588  let buf = RunVimInTerminal('-S XSmoothMarkerOverDoubleWidth', #{rows: 6, cols: 40})
    589  call VerifyScreenDump(buf, 'Test_smooth_marker_over_double_width_1', {})
    590 
    591  call term_sendkeys(buf, "\<C-E>")
    592  call VerifyScreenDump(buf, 'Test_smooth_marker_over_double_width_2', {})
    593 
    594  call StopVimInTerminal(buf)
    595 endfunc
    596 
    597 func s:check_col_calc(win_col, win_line, buf_col)
    598  call assert_equal(a:win_col, wincol())
    599  call assert_equal(a:win_line, winline())
    600  call assert_equal(a:buf_col, col('.'))
    601 endfunc
    602 
    603 " Test that if the current cursor is on a smooth scrolled line, we correctly
    604 " reposition it. Also check that we don't miscalculate the values by checking
    605 " the consistency between wincol() and col('.') as they are calculated
    606 " separately in code.
    607 func Test_smoothscroll_cursor_position()
    608  call NewWindow(10, 20)
    609  setl smoothscroll wrap
    610  call setline(1, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
    611 
    612  call s:check_col_calc(1, 1, 1)
    613  exe "normal \<C-E>"
    614 
    615  " Move down another line to avoid blocking the <<< display
    616  call s:check_col_calc(1, 2, 41)
    617  exe "normal \<C-Y>"
    618  call s:check_col_calc(1, 3, 41)
    619 
    620  " Test "g0/g<Home>"
    621  exe "normal gg\<C-E>"
    622  norm $gkg0
    623  call s:check_col_calc(4, 1, 24)
    624 
    625  " Test moving the cursor behind the <<< display with 'virtualedit'
    626  set virtualedit=all
    627  exe "normal \<C-E>gkh"
    628  call s:check_col_calc(3, 2, 23)
    629  set virtualedit&
    630 
    631  normal gg3l
    632  exe "normal \<C-E>"
    633 
    634  " Move down only 1 line when we are out of the range of the <<< display
    635  call s:check_col_calc(4, 1, 24)
    636  exe "normal \<C-Y>"
    637  call s:check_col_calc(4, 2, 24)
    638  normal ggg$
    639  exe "normal \<C-E>"
    640  call s:check_col_calc(20, 1, 40)
    641  exe "normal \<C-Y>"
    642  call s:check_col_calc(20, 2, 40)
    643  normal gg
    644 
    645  " Test number, where we have indented lines
    646  setl number
    647  call s:check_col_calc(5, 1, 1)
    648  exe "normal \<C-E>"
    649 
    650  " Move down only 1 line when the <<< display is on the number column
    651  call s:check_col_calc(5, 1, 17)
    652  exe "normal \<C-Y>"
    653  call s:check_col_calc(5, 2, 17)
    654  normal ggg$
    655  exe "normal \<C-E>"
    656  call s:check_col_calc(20, 1, 32)
    657  exe "normal \<C-Y>"
    658  call s:check_col_calc(20, 2, 32)
    659  normal gg
    660 
    661  setl numberwidth=1
    662 
    663  " Move down another line when numberwidth is too short to cover the whole
    664  " <<< display
    665  call s:check_col_calc(3, 1, 1)
    666  exe "normal \<C-E>"
    667  call s:check_col_calc(3, 2, 37)
    668  exe "normal \<C-Y>"
    669  call s:check_col_calc(3, 3, 37)
    670  normal ggl
    671 
    672  " Only move 1 line down when we are just past the <<< display
    673  call s:check_col_calc(4, 1, 2)
    674  exe "normal \<C-E>"
    675  call s:check_col_calc(4, 1, 20)
    676  exe "normal \<C-Y>"
    677  call s:check_col_calc(4, 2, 20)
    678  normal gg
    679  setl numberwidth&
    680 
    681  " Test number + showbreak, so test that the additional indentation works
    682  setl number showbreak=+++
    683  call s:check_col_calc(5, 1, 1)
    684  exe "normal \<C-E>"
    685  call s:check_col_calc(8, 1, 17)
    686  exe "normal \<C-Y>"
    687  call s:check_col_calc(8, 2, 17)
    688  normal gg
    689 
    690  " Test number + cpo+=n mode, where wrapped lines aren't indented
    691  setl number cpo+=n showbreak=
    692  call s:check_col_calc(5, 1, 1)
    693  exe "normal \<C-E>"
    694  call s:check_col_calc(1, 2, 37)
    695  exe "normal \<C-Y>"
    696  call s:check_col_calc(1, 3, 37)
    697  normal gg
    698 
    699  " Test list + listchars "precedes", where there is always 1 overlap
    700  " regardless of number and cpo-=n.
    701  setl number list listchars=precedes:< cpo-=n
    702  call s:check_col_calc(5, 1, 1)
    703  exe "normal 3|\<C-E>h"
    704  call s:check_col_calc(6, 1, 18)
    705  norm h
    706  call s:check_col_calc(5, 2, 17)
    707  normal gg
    708 
    709  bwipe!
    710 endfunc
    711 
    712 func Test_smoothscroll_cursor_scrolloff()
    713  call NewWindow(10, 20)
    714  setl smoothscroll wrap
    715  setl scrolloff=3
    716 
    717  " 120 chars are 6 screen lines
    718  call setline(1, "abcdefghijklmnopqrstABCDEFGHIJKLMNOPQRSTabcdefghijklmnopqrstABCDEFGHIJKLMNOPQRSTabcdefghijklmnopqrstABCDEFGHIJKLMNOPQRST")
    719  call setline(2, "below")
    720 
    721  call s:check_col_calc(1, 1, 1)
    722 
    723  " CTRL-E shows "<<<DEFG...", cursor move four lines down
    724  exe "normal \<C-E>"
    725  call s:check_col_calc(1, 4, 81)
    726 
    727  " cursor on start of second line, "gk" moves into first line, skipcol doesn't
    728  " change
    729  exe "normal G0gk"
    730  call s:check_col_calc(1, 5, 101)
    731 
    732  " move cursor left one window width worth, scrolls one screen line
    733  exe "normal 20h"
    734  call s:check_col_calc(1, 5, 81)
    735 
    736  " move cursor left one window width worth, scrolls one screen line
    737  exe "normal 20h"
    738  call s:check_col_calc(1, 4, 61)
    739 
    740  " cursor on last line, "gk" should not cause a scroll
    741  set scrolloff=0
    742  normal G0
    743  call s:check_col_calc(1, 7, 1)
    744  normal gk
    745  call s:check_col_calc(1, 6, 101)
    746 
    747  bwipe!
    748 endfunc
    749 
    750 
    751 " Test that mouse picking is still accurate when we have smooth scrolled lines
    752 func Test_smoothscroll_mouse_pos()
    753  CheckNotGui
    754  CheckUnix
    755 
    756  let save_mouse = &mouse
    757  "let save_term = &term
    758  "let save_ttymouse = &ttymouse
    759  set mouse=a "term=xterm ttymouse=xterm2
    760 
    761  call NewWindow(10, 20)
    762  setl smoothscroll wrap
    763  " First line will wrap to 3 physical lines. 2nd/3rd lines are short lines.
    764  call setline(1, ["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", "line 2", "line 3"])
    765 
    766  func s:check_mouse_click(row, col, buf_row, buf_col)
    767    call MouseLeftClick(a:row, a:col)
    768 
    769    call assert_equal(a:col, wincol())
    770    call assert_equal(a:row, winline())
    771    call assert_equal(a:buf_row, line('.'))
    772    call assert_equal(a:buf_col, col('.'))
    773  endfunc
    774 
    775  " Check that clicking without scroll works first.
    776  call s:check_mouse_click(3, 5, 1, 45)
    777  call s:check_mouse_click(4, 1, 2, 1)
    778  call s:check_mouse_click(4, 6, 2, 6)
    779  call s:check_mouse_click(5, 1, 3, 1)
    780  call s:check_mouse_click(5, 6, 3, 6)
    781 
    782  " Smooth scroll, and checks that this didn't mess up mouse clicking
    783  exe "normal \<C-E>"
    784  call s:check_mouse_click(2, 5, 1, 45)
    785  call s:check_mouse_click(3, 1, 2, 1)
    786  call s:check_mouse_click(3, 6, 2, 6)
    787  call s:check_mouse_click(4, 1, 3, 1)
    788  call s:check_mouse_click(4, 6, 3, 6)
    789 
    790  exe "normal \<C-E>"
    791  call s:check_mouse_click(1, 5, 1, 45)
    792  call s:check_mouse_click(2, 1, 2, 1)
    793  call s:check_mouse_click(2, 6, 2, 6)
    794  call s:check_mouse_click(3, 1, 3, 1)
    795  call s:check_mouse_click(3, 6, 3, 6)
    796 
    797  " Make a new first line 11 physical lines tall so it's taller than window
    798  " height, to test overflow calculations with really long lines wrapping.
    799  normal gg
    800  call setline(1, "12345678901234567890"->repeat(11))
    801  exe "normal 6\<C-E>"
    802  call s:check_mouse_click(5, 1, 1, 201)
    803  call s:check_mouse_click(6, 1, 2, 1)
    804  call s:check_mouse_click(7, 1, 3, 1)
    805 
    806  let &mouse = save_mouse
    807  "let &term = save_term
    808  "let &ttymouse = save_ttymouse
    809  bwipe!
    810 endfunc
    811 
    812 " this was dividing by zero
    813 func Test_smoothscroll_zero_width()
    814  CheckScreendump
    815 
    816  let lines =<< trim END
    817      winsize 0 0
    818      vsplit
    819      vsplit
    820      vsplit
    821      vsplit
    822      vsplit
    823      sil norm H
    824      set wrap
    825      set smoothscroll
    826      set number
    827  END
    828  call writefile(lines, 'XSmoothScrollZero', 'D')
    829  let buf = RunVimInTerminal('-u NONE -i NONE -n -m -X -Z -e -s -S XSmoothScrollZero', #{rows: 6, cols: 60, wait_for_ruler: 0})
    830  call VerifyScreenDump(buf, 'Test_smoothscroll_zero_1', {})
    831 
    832  call term_sendkeys(buf, ":sil norm \<C-V>\<C-W>\<C-V>\<C-N>\<CR>")
    833  call VerifyScreenDump(buf, 'Test_smoothscroll_zero_2', {})
    834 
    835  call StopVimInTerminal(buf)
    836 endfunc
    837 
    838 " this was unnecessarily inserting lines
    839 func Test_smoothscroll_ins_lines()
    840  CheckScreendump
    841 
    842  let lines =<< trim END
    843      set wrap
    844      set smoothscroll
    845      set scrolloff=0
    846      set conceallevel=2
    847      call setline(1, [
    848        \'line one' .. 'with lots of text in one line '->repeat(2),
    849        \'line two',
    850        \'line three',
    851        \'line four',
    852        \'line five'
    853      \])
    854  END
    855  call writefile(lines, 'XSmoothScrollInsLines', 'D')
    856  let buf = RunVimInTerminal('-S XSmoothScrollInsLines', #{rows: 6, cols: 40})
    857 
    858  call term_sendkeys(buf, "\<C-E>gjgk")
    859  call VerifyScreenDump(buf, 'Test_smooth_ins_lines', {})
    860 
    861  call StopVimInTerminal(buf)
    862 endfunc
    863 
    864 " this placed the cursor in the command line
    865 func Test_smoothscroll_cursormoved_line()
    866  CheckScreendump
    867 
    868  let lines =<< trim END
    869      set smoothscroll
    870      call setline(1, [
    871        \'',
    872        \'_'->repeat(&lines * &columns),
    873        \(('_')->repeat(&columns - 2) .. 'xxx')->repeat(2)
    874      \])
    875      autocmd CursorMoved * eval [line('w0'), line('w$')]
    876      call search('xxx')
    877  END
    878  call writefile(lines, 'XSmoothCursorMovedLine', 'D')
    879  let buf = RunVimInTerminal('-S XSmoothCursorMovedLine', #{rows: 6})
    880 
    881  call VerifyScreenDump(buf, 'Test_smooth_cursormoved_line', {})
    882 
    883  call StopVimInTerminal(buf)
    884 endfunc
    885 
    886 func Test_smoothscroll_eob()
    887  CheckScreendump
    888 
    889  let lines =<< trim END
    890      set smoothscroll
    891      call setline(1, ['']->repeat(100))
    892      norm G
    893  END
    894  call writefile(lines, 'XSmoothEob', 'D')
    895  let buf = RunVimInTerminal('-S XSmoothEob', #{rows: 10})
    896 
    897  " does not scroll halfway when scrolling to end of buffer
    898  call VerifyScreenDump(buf, 'Test_smooth_eob_1', {})
    899 
    900  " cursor is not placed below window
    901  call term_sendkeys(buf, ":call setline(92, 'a'->repeat(100))\<CR>\<C-L>\<C-B>G")
    902  call VerifyScreenDump(buf, 'Test_smooth_eob_2', {})
    903 
    904  call StopVimInTerminal(buf)
    905 endfunc
    906 
    907 " skipcol should not reset when doing incremental search on the same word
    908 func Test_smoothscroll_incsearch()
    909  CheckScreendump
    910 
    911  let lines =<< trim END
    912      set smoothscroll number scrolloff=0 incsearch
    913      call setline(1, repeat([''], 20))
    914      call setline(11, repeat('a', 100))
    915      call setline(14, 'bbbb')
    916  END
    917  call writefile(lines, 'XSmoothIncsearch', 'D')
    918  let buf = RunVimInTerminal('-S XSmoothIncsearch', #{rows: 8, cols: 40})
    919 
    920  call term_sendkeys(buf, "/b")
    921  call VerifyScreenDump(buf, 'Test_smooth_incsearch_1', {})
    922  call term_sendkeys(buf, "b")
    923  call VerifyScreenDump(buf, 'Test_smooth_incsearch_2', {})
    924  call term_sendkeys(buf, "b")
    925  call VerifyScreenDump(buf, 'Test_smooth_incsearch_3', {})
    926  call term_sendkeys(buf, "b")
    927  call VerifyScreenDump(buf, 'Test_smooth_incsearch_4', {})
    928  call term_sendkeys(buf, "\<CR>")
    929 
    930  call StopVimInTerminal(buf)
    931 endfunc
    932 
    933 " Test scrolling multiple lines and stopping at non-zero skipcol.
    934 func Test_smoothscroll_multi_skipcol()
    935  CheckScreendump
    936 
    937  let lines =<< trim END
    938      setlocal cursorline scrolloff=0 smoothscroll
    939      call setline(1, repeat([''], 8))
    940      call setline(3, repeat('a', 50))
    941      call setline(4, repeat('a', 50))
    942      call setline(7, 'bbb')
    943      call setline(8, 'ccc')
    944      redraw
    945  END
    946  call writefile(lines, 'XSmoothMultiSkipcol', 'D')
    947  let buf = RunVimInTerminal('-S XSmoothMultiSkipcol', #{rows: 10, cols: 40})
    948  call VerifyScreenDump(buf, 'Test_smooth_multi_skipcol_1', {})
    949 
    950  call term_sendkeys(buf, "3\<C-E>")
    951  call VerifyScreenDump(buf, 'Test_smooth_multi_skipcol_2', {})
    952 
    953  call term_sendkeys(buf, "2\<C-E>")
    954  call VerifyScreenDump(buf, 'Test_smooth_multi_skipcol_3', {})
    955 
    956  call StopVimInTerminal(buf)
    957 endfunc
    958 
    959 " this was dividing by zero bug in scroll_cursor_bot
    960 func Test_smoothscroll_zero_width_scroll_cursor_bot_noruler()
    961  CheckScreendump
    962 
    963  let lines =<< trim END
    964      set noruler
    965      silent normal yy
    966      silent normal 19p
    967      set cpoptions+=n
    968      vsplit
    969      vertical resize 0
    970      set foldcolumn=1
    971      set number
    972      set smoothscroll
    973      silent normal 20G
    974  END
    975  call writefile(lines, 'XSmoothScrollZeroBot', 'D')
    976  let buf = RunVimInTerminal('-u NONE -S XSmoothScrollZeroBot', #{rows: 19})
    977  call VerifyScreenDump(buf, 'Test_smoothscroll_zero_bot', {})
    978 
    979  call StopVimInTerminal(buf)
    980 endfunc
    981 
    982 func Test_smoothscroll_zero_width_scroll_cursor_bot_ruler()
    983  CheckScreendump
    984 
    985  let lines =<< trim END
    986      set ruler
    987      silent normal yy
    988      silent normal 19p
    989      set cpoptions+=n
    990      vsplit
    991      vertical resize 0
    992      set foldcolumn=1
    993      set number
    994      set smoothscroll
    995      silent normal 20G
    996  END
    997  call writefile(lines, 'XSmoothScrollZeroBot', 'D')
    998  let buf = RunVimInTerminal('-u NONE -S XSmoothScrollZeroBot', #{rows: 19})
    999  call VerifyScreenDump(buf, 'Test_smoothscroll_zero_bot_ruler', {})
   1000 
   1001  call StopVimInTerminal(buf)
   1002 endfunc
   1003 
   1004 " scroll_cursor_top() should reset skipcol when it changes topline
   1005 func Test_smoothscroll_cursor_top_noruler()
   1006  CheckScreendump
   1007 
   1008  let lines =<< trim END
   1009      set smoothscroll scrolloff=2 noruler
   1010      new | 11resize | wincmd j
   1011      call setline(1, ['line1', 'line2', 'line3'->repeat(20), 'line4'])
   1012      exe "norm G3\<C-E>k"
   1013  END
   1014  call writefile(lines, 'XSmoothScrollCursorTop', 'D')
   1015  let buf = RunVimInTerminal('-u NONE -S XSmoothScrollCursorTop', #{rows: 12, cols: 40})
   1016  call VerifyScreenDump(buf, 'Test_smoothscroll_cursor_top', {})
   1017 
   1018  call StopVimInTerminal(buf)
   1019 endfunc
   1020 
   1021 func Test_smoothscroll_cursor_top_ruler()
   1022  CheckScreendump
   1023 
   1024  let lines =<< trim END
   1025      set smoothscroll scrolloff=2 ruler
   1026      new | 11resize | wincmd j
   1027      call setline(1, ['line1', 'line2', 'line3'->repeat(20), 'line4'])
   1028      exe "norm G3\<C-E>k"
   1029  END
   1030  call writefile(lines, 'XSmoothScrollCursorTop', 'D')
   1031  let buf = RunVimInTerminal('-u NONE -S XSmoothScrollCursorTop', #{rows: 12, cols: 40})
   1032  call VerifyScreenDump(buf, 'Test_smoothscroll_cursor_ru_top', {})
   1033 
   1034  call StopVimInTerminal(buf)
   1035 endfunc
   1036 
   1037 " Division by zero, shouldn't crash
   1038 func Test_smoothscroll_crash()
   1039  CheckScreendump
   1040 
   1041  let lines =<< trim END
   1042      20 new
   1043      vsp
   1044      put =repeat('aaaa', 20)
   1045      set nu fdc=1  smoothscroll cpo+=n
   1046      vert resize 0
   1047      exe "norm! 0\<c-e>"
   1048  END
   1049  call writefile(lines, 'XSmoothScrollCrash', 'D')
   1050  let buf = RunVimInTerminal('-u NONE -S XSmoothScrollCrash', #{rows: 12, cols: 40})
   1051  call term_sendkeys(buf, "2\<C-E>\<C-L>")
   1052 
   1053  call StopVimInTerminal(buf)
   1054 endfunc
   1055 
   1056 func Test_smoothscroll_insert_bottom_noruler()
   1057  CheckScreendump
   1058 
   1059  let lines =<< trim END
   1060    call setline(1, repeat([repeat('A very long line ...', 10)], 5))
   1061    set wrap smoothscroll scrolloff=0 noruler
   1062  END
   1063  call writefile(lines, 'XSmoothScrollInsertBottom', 'D')
   1064  let buf = RunVimInTerminal('-u NONE -S XSmoothScrollInsertBottom', #{rows: 9, cols: 40})
   1065  call term_sendkeys(buf, "Go123456789\<CR>")
   1066  call VerifyScreenDump(buf, 'Test_smoothscroll_insert_bottom', {})
   1067 
   1068  call StopVimInTerminal(buf)
   1069 endfunc
   1070 
   1071 func Test_smoothscroll_insert_bottom_ruler()
   1072  CheckScreendump
   1073 
   1074  let lines =<< trim END
   1075    call setline(1, repeat([repeat('A very long line ...', 10)], 5))
   1076    set wrap smoothscroll scrolloff=0 ruler
   1077  END
   1078  call writefile(lines, 'XSmoothScrollInsertBottom', 'D')
   1079  let buf = RunVimInTerminal('-u NONE -S XSmoothScrollInsertBottom', #{rows: 9, cols: 40})
   1080  call term_sendkeys(buf, "Go123456789\<CR>")
   1081  call VerifyScreenDump(buf, 'Test_smoothscroll_insert_bottom_ruler', {})
   1082 
   1083  call StopVimInTerminal(buf)
   1084 endfunc
   1085 
   1086 func Test_smoothscroll_in_qf_window_noruler()
   1087  CheckFeature quickfix
   1088  CheckScreendump
   1089 
   1090  let lines =<< trim END
   1091    set nocompatible display=lastline noruler
   1092    copen 5
   1093    setlocal number smoothscroll
   1094    let g:l = [{'text': 'foo'}] + repeat([{'text': join(range(30))}], 10)
   1095    call setqflist(g:l, 'r')
   1096    normal! G
   1097    wincmd t
   1098    let g:l1 = [{'text': join(range(1000))}]
   1099  END
   1100  call writefile(lines, 'XSmoothScrollInQfWindow', 'D')
   1101  let buf = RunVimInTerminal('-u NONE -S XSmoothScrollInQfWindow', #{rows: 20, cols: 60})
   1102  call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_1', {})
   1103 
   1104  call term_sendkeys(buf, ":call setqflist([], 'r')\<CR>")
   1105  call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_2', {})
   1106 
   1107  call term_sendkeys(buf, ":call setqflist(g:l, 'r')\<CR>")
   1108  call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_3', {})
   1109 
   1110  call term_sendkeys(buf, ":call setqflist(g:l1, 'r')\<CR>")
   1111  call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_4', {})
   1112 
   1113  call term_sendkeys(buf, "\<C-W>b$\<C-W>t")
   1114  call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_5', {})
   1115 
   1116  call term_sendkeys(buf, ":call setqflist([], 'r')\<CR>")
   1117  call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_2', {})
   1118 
   1119  call term_sendkeys(buf, ":call setqflist(g:l1, 'r')\<CR>")
   1120  call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_4', {})
   1121 
   1122  call term_sendkeys(buf, "\<C-W>b$\<C-W>t")
   1123  call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_5', {})
   1124 
   1125  call term_sendkeys(buf, ":call setqflist(g:l, 'r')\<CR>")
   1126  call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_3', {})
   1127 
   1128  call StopVimInTerminal(buf)
   1129 endfunc
   1130 
   1131 func Test_smoothscroll_in_qf_window_ruler()
   1132  CheckFeature quickfix
   1133  CheckScreendump
   1134 
   1135  let lines =<< trim END
   1136    set nocompatible display=lastline ruler
   1137    copen 5
   1138    setlocal number smoothscroll
   1139    let g:l = [{'text': 'foo'}] + repeat([{'text': join(range(30))}], 10)
   1140    call setqflist(g:l, 'r')
   1141    normal! G
   1142    wincmd t
   1143    let g:l1 = [{'text': join(range(1000))}]
   1144  END
   1145  call writefile(lines, 'XSmoothScrollInQfWindow', 'D')
   1146  let buf = RunVimInTerminal('-u NONE -S XSmoothScrollInQfWindow', #{rows: 20, cols: 60})
   1147  call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_ru_1', {})
   1148 
   1149  call term_sendkeys(buf, ":call setqflist([], 'r')\<CR>")
   1150  call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_ru_2', {})
   1151 
   1152  call term_sendkeys(buf, ":call setqflist(g:l, 'r')\<CR>")
   1153  call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_ru_3', {})
   1154 
   1155  call term_sendkeys(buf, ":call setqflist(g:l1, 'r')\<CR>")
   1156  call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_ru_4', {})
   1157 
   1158  call term_sendkeys(buf, "\<C-W>b$\<C-W>t")
   1159  call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_ru_5', {})
   1160 
   1161  call term_sendkeys(buf, ":call setqflist([], 'r')\<CR>")
   1162  call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_ru_2', {})
   1163 
   1164  call term_sendkeys(buf, ":call setqflist(g:l1, 'r')\<CR>")
   1165  call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_ru_4', {})
   1166 
   1167  call term_sendkeys(buf, "\<C-W>b$\<C-W>t")
   1168  call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_ru_5', {})
   1169 
   1170  call term_sendkeys(buf, ":call setqflist(g:l, 'r')\<CR>")
   1171  call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_ru_3', {})
   1172 
   1173  call StopVimInTerminal(buf)
   1174 endfunc
   1175 
   1176 func Test_smoothscroll_in_zero_width_window()
   1177  set cpo+=n number smoothscroll
   1178  set winwidth=99999 winminwidth=0
   1179 
   1180  vsplit
   1181  call assert_equal(0, winwidth(winnr('#')))
   1182  call win_execute(win_getid(winnr('#')), "norm! \<C-Y>")
   1183 
   1184  only!
   1185  set winwidth& winminwidth&
   1186  set cpo-=n nonumber nosmoothscroll
   1187 endfunc
   1188 
   1189 func Test_smoothscroll_textoff_small_winwidth()
   1190  set smoothscroll number
   1191  call setline(1, 'llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch')
   1192  vsplit
   1193 
   1194  let textoff = getwininfo(win_getid())[0].textoff
   1195  execute 'vertical resize' textoff + 1
   1196  redraw
   1197  call assert_equal(0, winsaveview().skipcol)
   1198  execute "normal! 0\<C-E>"
   1199  redraw
   1200  call assert_equal(1, winsaveview().skipcol)
   1201  execute 'vertical resize' textoff - 1
   1202  " This caused a signed integer overflow.
   1203  redraw
   1204  call assert_equal(1, winsaveview().skipcol)
   1205  execute 'vertical resize' textoff
   1206  " This caused an infinite loop.
   1207  redraw
   1208  call assert_equal(1, winsaveview().skipcol)
   1209 
   1210  %bw!
   1211  set smoothscroll& number&
   1212 endfunc
   1213 
   1214 func Test_smoothscroll_page()
   1215  call NewWindow(10, 40)
   1216  setlocal smoothscroll
   1217  call setline(1, 'abcde '->repeat(150))
   1218 
   1219  exe "norm! \<C-F>"
   1220  call assert_equal(400, winsaveview().skipcol)
   1221  exe "norm! \<C-F>"
   1222  call assert_equal(800, winsaveview().skipcol)
   1223  exe "norm! \<C-F>"
   1224  call assert_equal(880, winsaveview().skipcol)
   1225  exe "norm! \<C-B>"
   1226  call assert_equal(480, winsaveview().skipcol)
   1227  exe "norm! \<C-B>"
   1228  call assert_equal(80, winsaveview().skipcol)
   1229  exe "norm! \<C-B>"
   1230  call assert_equal(0, winsaveview().skipcol)
   1231 
   1232  " Half-page scrolling does not go beyond end of buffer and moves the cursor.
   1233  " Even with 'nostartofline', the correct amount of lines is scrolled.
   1234  setl nostartofline
   1235  exe "norm! 15|\<C-D>"
   1236  call assert_equal(200, winsaveview().skipcol)
   1237  call assert_equal(215, col('.'))
   1238  exe "norm! \<C-D>"
   1239  call assert_equal(400, winsaveview().skipcol)
   1240  call assert_equal(415, col('.'))
   1241  exe "norm! \<C-D>"
   1242  call assert_equal(520, winsaveview().skipcol)
   1243  call assert_equal(615, col('.'))
   1244  exe "norm! \<C-D>"
   1245  call assert_equal(520, winsaveview().skipcol)
   1246  call assert_equal(815, col('.'))
   1247  exe "norm! \<C-D>"
   1248  call assert_equal(520, winsaveview().skipcol)
   1249  call assert_equal(895, col('.'))
   1250  exe "norm! \<C-U>"
   1251  call assert_equal(320, winsaveview().skipcol)
   1252  call assert_equal(695, col('.'))
   1253  exe "norm! \<C-U>"
   1254  call assert_equal(120, winsaveview().skipcol)
   1255  call assert_equal(495, col('.'))
   1256  exe "norm! \<C-U>"
   1257  call assert_equal(0, winsaveview().skipcol)
   1258  call assert_equal(295, col('.'))
   1259  exe "norm! \<C-U>"
   1260  call assert_equal(0, winsaveview().skipcol)
   1261  call assert_equal(95, col('.'))
   1262  exe "norm! \<C-U>"
   1263  call assert_equal(0, winsaveview().skipcol)
   1264  call assert_equal(15, col('.'))
   1265 
   1266  bwipe!
   1267 endfunc
   1268 
   1269 func Test_smoothscroll_next_topline()
   1270  call NewWindow(10, 40)
   1271  setlocal smoothscroll
   1272  call setline(1, ['abcde '->repeat(150)]->repeat(2))
   1273 
   1274  " Scrolling a screenline that causes the cursor to move to the next buffer
   1275  " line should not skip part of that line to bring the cursor into view.
   1276  exe "norm! 22\<C-E>"
   1277  call assert_equal(880, winsaveview().skipcol)
   1278  exe "norm! \<C-E>"
   1279  redraw
   1280  call assert_equal(0, winsaveview().skipcol)
   1281 
   1282  " Also when scrolling back.
   1283  exe "norm! G\<C-Y>"
   1284  redraw
   1285  call assert_equal(880, winsaveview().skipcol)
   1286 
   1287  " Cursor in correct place when not in the first screenline of a buffer line.
   1288  exe "norm! gg4gj20\<C-D>\<C-D>"
   1289  redraw
   1290  call assert_equal(2, line('w0'))
   1291 
   1292  " Cursor does not end up above topline, adjusting topline later.
   1293  setlocal nu cpo+=n
   1294  exe "norm! G$g013\<C-Y>"
   1295  redraw
   1296  call assert_equal(2, line('.'))
   1297  call assert_equal(0, winsaveview().skipcol)
   1298 
   1299  set cpo-=n
   1300  bwipe!
   1301 endfunc
   1302 
   1303 func Test_smoothscroll_long_line_zb()
   1304  call NewWindow(10, 40)
   1305  call setline(1, 'abcde '->repeat(150))
   1306 
   1307  " Also works without 'smoothscroll' when last line of buffer doesn't fit.
   1308  " Used to set topline to buffer line count plus one, causing an empty screen.
   1309  norm zb
   1310  redraw
   1311  call assert_equal(1, winsaveview().topline)
   1312 
   1313  " Moving cursor to bottom works on line that doesn't fit with 'smoothscroll'.
   1314  " Skipcol was adjusted later for cursor being on not visible part of line.
   1315  setlocal smoothscroll
   1316  norm zb
   1317  redraw
   1318  call assert_equal(520, winsaveview().skipcol)
   1319 
   1320  bwipe!
   1321 endfunc
   1322 
   1323 func Test_smooth_long_scrolloff_noruler()
   1324  CheckScreendump
   1325 
   1326  let lines =<< trim END
   1327    set smoothscroll scrolloff=3
   1328    set noruler
   1329    call setline(1, ['one', 'two long '->repeat(100), 'three', 'four', 'five', 'six'])
   1330  END
   1331  call writefile(lines, 'XSmoothLongScrolloff', 'D')
   1332  let buf = RunVimInTerminal('-u NONE -S XSmoothLongScrolloff', #{rows: 8, cols: 40})
   1333  call term_sendkeys(buf, ":norm j721|\<CR>")
   1334  call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_1', {})
   1335 
   1336  call term_sendkeys(buf, "gj")
   1337  call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_2', {})
   1338 
   1339  call term_sendkeys(buf, "gj")
   1340  call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_3', {})
   1341 
   1342  call term_sendkeys(buf, "gj")
   1343  call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_4', {})
   1344 
   1345  call term_sendkeys(buf, "gj")
   1346  call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_5', {})
   1347 
   1348  call term_sendkeys(buf, "gj")
   1349  call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_6', {})
   1350 
   1351  call term_sendkeys(buf, "gk")
   1352  call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_7', {})
   1353 
   1354  call StopVimInTerminal(buf)
   1355 endfunc
   1356 
   1357 func Test_smooth_long_scrolloff_ruler()
   1358  CheckScreendump
   1359 
   1360  let lines =<< trim END
   1361    set smoothscroll scrolloff=3 ruler
   1362    call setline(1, ['one', 'two long '->repeat(100), 'three', 'four', 'five', 'six'])
   1363  END
   1364  call writefile(lines, 'XSmoothLongScrolloff', 'D')
   1365  let buf = RunVimInTerminal('-u NONE -S XSmoothLongScrolloff', #{rows: 8, cols: 40})
   1366  call term_sendkeys(buf, ":norm j721|\<CR>")
   1367  call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_ru_1', {})
   1368 
   1369  call term_sendkeys(buf, "gj")
   1370  call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_ru_2', {})
   1371 
   1372  call term_sendkeys(buf, "gj")
   1373  call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_ru_3', {})
   1374 
   1375  call term_sendkeys(buf, "gj")
   1376  call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_ru_4', {})
   1377 
   1378  call term_sendkeys(buf, "gj")
   1379  call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_ru_5', {})
   1380 
   1381  call term_sendkeys(buf, "gj")
   1382  call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_ru_6', {})
   1383 
   1384  call term_sendkeys(buf, "gk")
   1385  call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_ru_7', {})
   1386 
   1387  call StopVimInTerminal(buf)
   1388 endfunc
   1389 
   1390 func Test_smoothscroll_listchars_eol()
   1391  call NewWindow(10, 40)
   1392  setlocal list listchars=eol:$ scrolloff=0 smoothscroll
   1393  call setline(1, repeat('-', 40))
   1394  call append(1, repeat(['foobar'], 10))
   1395 
   1396  normal! G
   1397  call assert_equal(2, line('w0'))
   1398  call assert_equal(0, winsaveview().skipcol)
   1399 
   1400  exe "normal! \<C-Y>"
   1401  call assert_equal(1, line('w0'))
   1402  call assert_equal(40, winsaveview().skipcol)
   1403 
   1404  exe "normal! \<C-Y>"
   1405  call assert_equal(1, line('w0'))
   1406  call assert_equal(0, winsaveview().skipcol)
   1407 
   1408  exe "normal! \<C-Y>"
   1409  call assert_equal(1, line('w0'))
   1410  call assert_equal(0, winsaveview().skipcol)
   1411 
   1412  exe "normal! \<C-E>"
   1413  call assert_equal(1, line('w0'))
   1414  call assert_equal(40, winsaveview().skipcol)
   1415 
   1416  exe "normal! \<C-E>"
   1417  call assert_equal(2, line('w0'))
   1418  call assert_equal(0, winsaveview().skipcol)
   1419 
   1420  for ve in ['', 'all', 'onemore']
   1421    let &virtualedit = ve
   1422    normal! gg
   1423    call assert_equal(1, line('w0'))
   1424    call assert_equal(0, winsaveview().skipcol)
   1425 
   1426    exe "normal! \<C-E>"
   1427    redraw  " redrawing should not cause another scroll
   1428    call assert_equal(1, line('w0'))
   1429    call assert_equal(40, winsaveview().skipcol)
   1430 
   1431    exe "normal! \<C-E>"
   1432    redraw
   1433    call assert_equal(2, line('w0'))
   1434    call assert_equal(0, winsaveview().skipcol)
   1435 
   1436    if ve != 'all'
   1437      call assert_equal([0, 2, 1, 0], getpos('.'))
   1438    endif
   1439  endfor
   1440 
   1441  set virtualedit&
   1442  bwipe!
   1443 endfunc
   1444 
   1445 " vim: shiftwidth=2 sts=2 expandtab