neovim

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

test_visual.vim (94278B)


      1 " Tests for various Visual modes.
      2 
      3 source shared.vim
      4 source check.vim
      5 source screendump.vim
      6 source vim9.vim
      7 
      8 func Test_block_shift_multibyte()
      9  " Uses double-wide character.
     10  split
     11  call setline(1, ['xヹxxx', 'ヹxxx'])
     12  exe "normal 1G0l\<C-V>jl>"
     13  call assert_equal('x	 ヹxxx', getline(1))
     14  call assert_equal('	ヹxxx', getline(2))
     15  q!
     16 endfunc
     17 
     18 func Test_block_shift_overflow()
     19  " This used to cause a multiplication overflow followed by a crash.
     20  new
     21  normal ii
     22  exe "normal \<C-V>876543210>"
     23  q!
     24 endfunc
     25 
     26 func Test_dotregister_paste()
     27  new
     28  exe "norm! ihello world\<esc>"
     29  norm! 0ve".p
     30  call assert_equal('hello world world', getline(1))
     31  q!
     32 endfunc
     33 
     34 func Test_Visual_ctrl_o()
     35  new
     36  call setline(1, ['one', 'two', 'three'])
     37  call cursor(1,2)
     38  set noshowmode
     39  set tw=0
     40  call feedkeys("\<c-v>jjlIa\<c-\>\<c-o>:set tw=88\<cr>\<esc>", 'tx')
     41  call assert_equal(['oane', 'tawo', 'tahree'], getline(1, 3))
     42  call assert_equal(88, &tw)
     43  set tw&
     44  bw!
     45 endfu
     46 
     47 func Test_Visual_vapo()
     48  new
     49  normal oxx
     50  normal vapo
     51  bwipe!
     52 endfunc
     53 
     54 func Test_Visual_inner_quote()
     55  new
     56  normal oxX
     57  normal vki'
     58  bwipe!
     59 endfunc
     60 
     61 " Test for Visual mode not being reset causing E315 error.
     62 func TriggerTheProblem()
     63  " At this point there is no visual selection because :call reset it.
     64  " Let's restore the selection:
     65  normal gv
     66  '<,'>del _
     67  try
     68      exe "normal \<Esc>"
     69  catch /^Vim\%((\a\+)\)\=:E315/
     70      echom 'Snap! E315 error!'
     71      let g:msg = 'Snap! E315 error!'
     72  endtry
     73 endfunc
     74 
     75 func Test_visual_mode_reset()
     76  enew
     77  let g:msg = "Everything's fine."
     78  enew
     79  setl buftype=nofile
     80  call append(line('$'), 'Delete this line.')
     81 
     82  " NOTE: this has to be done by a call to a function because executing :del
     83  " the ex-way will require the colon operator which resets the visual mode
     84  " thus preventing the problem:
     85  exe "normal! GV:call TriggerTheProblem()\<CR>"
     86  call assert_equal("Everything's fine.", g:msg)
     87 endfunc
     88 
     89 " Test for visual block shift and tab characters.
     90 func Test_block_shift_tab()
     91  new
     92  call append(0, repeat(['one two three'], 5))
     93  call cursor(1,1)
     94  exe "normal i\<C-G>u"
     95  exe "normal fe\<C-V>4jR\<Esc>ugvr1"
     96  call assert_equal('on1 two three', getline(1))
     97  call assert_equal('on1 two three', getline(2))
     98  call assert_equal('on1 two three', getline(5))
     99 
    100  %d _
    101  call append(0, repeat(['abcdefghijklmnopqrstuvwxyz'], 5))
    102  call cursor(1,1)
    103  exe "normal \<C-V>4jI    \<Esc>j<<11|D"
    104  exe "normal j7|a\<Tab>\<Tab>"
    105  exe "normal j7|a\<Tab>\<Tab>   "
    106  exe "normal j7|a\<Tab>       \<Tab>\<Esc>4k13|\<C-V>4j<"
    107  call assert_equal('    abcdefghijklmnopqrstuvwxyz', getline(1))
    108  call assert_equal('abcdefghij', getline(2))
    109  call assert_equal("    abc\<Tab>    defghijklmnopqrstuvwxyz", getline(3))
    110  call assert_equal("    abc\<Tab>    defghijklmnopqrstuvwxyz", getline(4))
    111  call assert_equal("    abc\<Tab>    defghijklmnopqrstuvwxyz", getline(5))
    112 
    113  %s/\s\+//g
    114  call cursor(1,1)
    115  exe "normal \<C-V>4jI    \<Esc>j<<"
    116  exe "normal j7|a\<Tab>\<Tab>"
    117  exe "normal j7|a\<Tab>\<Tab>\<Tab>\<Tab>\<Tab>"
    118  exe "normal j7|a\<Tab>       \<Tab>\<Tab>\<Esc>4k13|\<C-V>4j3<"
    119  call assert_equal('    abcdefghijklmnopqrstuvwxyz', getline(1))
    120  call assert_equal('abcdefghij', getline(2))
    121  call assert_equal("    abc\<Tab>    defghijklmnopqrstuvwxyz", getline(3))
    122  call assert_equal("    abc\<Tab>\<Tab>defghijklmnopqrstuvwxyz", getline(4))
    123  call assert_equal("    abc\<Tab>    defghijklmnopqrstuvwxyz", getline(5))
    124 
    125  " Test for block shift with space characters at the beginning and with
    126  " 'noexpandtab' and 'expandtab'
    127  %d _
    128  call setline(1, ["      1", "      2", "      3"])
    129  setlocal shiftwidth=2 noexpandtab
    130  exe "normal gg\<C-V>3j>"
    131  call assert_equal(["\t1", "\t2", "\t3"], getline(1, '$'))
    132  %d _
    133  call setline(1, ["      1", "      2", "      3"])
    134  setlocal shiftwidth=2 expandtab
    135  exe "normal gg\<C-V>3j>"
    136  call assert_equal(["        1", "        2", "        3"], getline(1, '$'))
    137  setlocal shiftwidth&
    138 
    139  bw!
    140 endfunc
    141 
    142 " Tests Blockwise Visual when there are TABs before the text.
    143 func Test_blockwise_visual()
    144  new
    145  call append(0, ['123456',
    146       \ '234567',
    147       \ '345678',
    148       \ '',
    149       \ 'test text test tex start here',
    150       \ "\t\tsome text",
    151       \ "\t\ttest text",
    152       \ 'test text'])
    153  call cursor(1,1)
    154  exe "normal /start here$\<CR>"
    155  exe 'normal "by$' . "\<C-V>jjlld"
    156  exe "normal /456$\<CR>"
    157  exe "normal \<C-V>jj" . '"bP'
    158  call assert_equal(['123start here56',
    159       \ '234start here67',
    160       \ '345start here78',
    161       \ '',
    162       \ 'test text test tex rt here',
    163       \ "\t\tsomext",
    164       \ "\t\ttesext"], getline(1, 7))
    165 
    166  bw!
    167 endfunc
    168 
    169 " Test swapping corners in blockwise visual mode with o and O
    170 func Test_blockwise_visual_o_O()
    171  new
    172 
    173  exe "norm! 10i.\<Esc>Y4P3lj\<C-V>4l2jr "
    174  exe "norm! gvO\<Esc>ra"
    175  exe "norm! gvO\<Esc>rb"
    176  exe "norm! gvo\<C-c>rc"
    177  exe "norm! gvO\<C-c>rd"
    178  set selection=exclusive
    179  exe "norm! gvOo\<C-c>re"
    180  call assert_equal('...a   be.', getline(4))
    181  exe "norm! gvOO\<C-c>rf"
    182  set selection&
    183 
    184  call assert_equal(['..........',
    185        \            '...c   d..',
    186        \            '...     ..',
    187        \            '...a   bf.',
    188        \            '..........'], getline(1, '$'))
    189 
    190  bw!
    191 endfun
    192 
    193 " Test Virtual replace mode.
    194 func Test_virtual_replace()
    195  if exists('&t_kD')
    196    let save_t_kD = &t_kD
    197  endif
    198  if exists('&t_kb')
    199    let save_t_kb = &t_kb
    200  endif
    201  exe "set t_kD=\<C-V>x7f t_kb=\<C-V>x08"
    202  enew!
    203  exe "normal a\nabcdefghi\njk\tlmn\n    opq	rst\n\<C-D>uvwxyz"
    204  call cursor(1,1)
    205  set ai bs=2
    206  exe "normal gR0\<C-D> 1\nA\nBCDEFGHIJ\n\tKL\nMNO\nPQR"
    207  call assert_equal([' 1',
    208       \ ' A',
    209       \ ' BCDEFGHIJ',
    210       \ ' 	KL',
    211       \ '	MNO',
    212       \ '	PQR',
    213       \ ], getline(1, 6))
    214  normal G
    215  mark a
    216  exe "normal o0\<C-D>\nabcdefghi\njk\tlmn\n    opq\trst\n\<C-D>uvwxyz\n"
    217  exe "normal 'ajgR0\<C-D> 1\nA\nBCDEFGHIJ\n\tKL\nMNO\nPQR" . repeat("\<BS>", 29)
    218  call assert_equal([' 1',
    219       \ 'abcdefghi',
    220       \ 'jk	lmn',
    221       \ '    opq	rst',
    222       \ 'uvwxyz'], getline(7, 11))
    223  normal G
    224  exe "normal iab\tcdefghi\tjkl"
    225  exe "normal 0gRAB......CDEFGHI.J\<Esc>o"
    226  exe "normal iabcdefghijklmnopqrst\<Esc>0gRAB\tIJKLMNO\tQR"
    227  call assert_equal(['AB......CDEFGHI.Jkl',
    228       \ 'AB	IJKLMNO	QRst'], getline(12, 13))
    229 
    230  " Test inserting Tab with 'noexpandtab' and 'softabstop' set to 4
    231  %d
    232  call setline(1, 'aaaaaaaaaaaaa')
    233  set softtabstop=4
    234  exe "normal gggR\<Tab>\<Tab>x"
    235  call assert_equal("\txaaaa", getline(1))
    236  set softtabstop&
    237 
    238  enew!
    239  set noai bs&vim
    240  if exists('save_t_kD')
    241    let &t_kD = save_t_kD
    242  endif
    243  if exists('save_t_kb')
    244    let &t_kb = save_t_kb
    245  endif
    246 endfunc
    247 
    248 " Test Virtual replace mode.
    249 func Test_virtual_replace2()
    250  enew!
    251  set bs=2
    252  exe "normal a\nabcdefghi\njk\tlmn\n    opq	rst\n\<C-D>uvwxyz"
    253  call cursor(1,1)
    254  " Test 1: Test that del deletes the newline
    255  exe "normal gR0\<del> 1\nA\nBCDEFGHIJ\n\tKL\nMNO\nPQR"
    256  call assert_equal(['0 1',
    257       \ 'A',
    258       \ 'BCDEFGHIJ',
    259       \ '	KL',
    260       \ 'MNO',
    261       \ 'PQR',
    262       \ ], getline(1, 6))
    263  " Test 2:
    264  " a newline is not deleted, if no newline has been added in virtual replace mode
    265  %d_
    266  call setline(1, ['abcd', 'efgh', 'ijkl'])
    267  call cursor(2,1)
    268  exe "norm! gR1234\<cr>5\<bs>\<bs>\<bs>"
    269  call assert_equal(['abcd',
    270        \ '123h',
    271        \ 'ijkl'], getline(1, '$'))
    272  " Test 3:
    273  " a newline is deleted, if a newline has been inserted before in virtual replace mode
    274  %d_
    275  call setline(1, ['abcd', 'efgh', 'ijkl'])
    276  call cursor(2,1)
    277  exe "norm! gR1234\<cr>\<cr>56\<bs>\<bs>\<bs>"
    278  call assert_equal(['abcd',
    279        \ '1234',
    280        \ 'ijkl'], getline(1, '$'))
    281  " Test 4:
    282  " delete add a newline, delete it, add it again and check undo
    283  %d_
    284  call setline(1, ['abcd', 'efgh', 'ijkl'])
    285  call cursor(2,1)
    286  " break undo sequence explicitly
    287  let &ul = &ul
    288  exe "norm! gR1234\<cr>\<bs>\<del>56\<cr>"
    289  let &ul = &ul
    290  call assert_equal(['abcd',
    291        \ '123456',
    292        \ ''], getline(1, '$'))
    293  norm! u
    294  call assert_equal(['abcd',
    295        \ 'efgh',
    296        \ 'ijkl'], getline(1, '$'))
    297 
    298  " Test for truncating spaces in a newly added line using 'autoindent' if
    299  " characters are not added to that line.
    300  %d_
    301  call setline(1, ['    app', '    bee', '    cat'])
    302  setlocal autoindent
    303  exe "normal gg$gRt\n\nr"
    304  call assert_equal(['    apt', '', '    rat'], getline(1, '$'))
    305 
    306  " clean up
    307  %d_
    308  set bs&vim
    309 endfunc
    310 
    311 func Test_Visual_word_textobject()
    312  new
    313  call setline(1, ['First sentence. Second sentence.'])
    314 
    315  " When start and end of visual area are identical, 'aw' or 'iw' select
    316  " the whole word.
    317  norm! 1go2fcvawy
    318  call assert_equal('Second ', @")
    319  norm! 1go2fcviwy
    320  call assert_equal('Second', @")
    321 
    322  " When start and end of visual area are not identical, 'aw' or 'iw'
    323  " extend the word in direction of the end of the visual area.
    324  norm! 1go2fcvlawy
    325  call assert_equal('cond ', @")
    326  norm! gv2awy
    327  call assert_equal('cond sentence.', @")
    328 
    329  norm! 1go2fcvliwy
    330  call assert_equal('cond', @")
    331  norm! gv2iwy
    332  call assert_equal('cond sentence', @")
    333 
    334  " Extend visual area in opposite direction.
    335  norm! 1go2fcvhawy
    336  call assert_equal(' Sec', @")
    337  norm! gv2awy
    338  call assert_equal(' sentence. Sec', @")
    339 
    340  norm! 1go2fcvhiwy
    341  call assert_equal('Sec', @")
    342  norm! gv2iwy
    343  call assert_equal('. Sec', @")
    344 
    345  bwipe!
    346 endfunc
    347 
    348 func Test_Visual_sentence_textobject()
    349  new
    350  call setline(1, ['First sentence. Second sentence. Third', 'sentence. Fourth sentence'])
    351 
    352  " When start and end of visual area are identical, 'as' or 'is' select
    353  " the whole sentence.
    354  norm! 1gofdvasy
    355  call assert_equal('Second sentence. ', @")
    356  norm! 1gofdvisy
    357  call assert_equal('Second sentence.', @")
    358 
    359  " When start and end of visual area are not identical, 'as' or 'is'
    360  " extend the sentence in direction of the end of the visual area.
    361  norm! 1gofdvlasy
    362  call assert_equal('d sentence. ', @")
    363  norm! gvasy
    364  call assert_equal("d sentence. Third\nsentence. ", @")
    365 
    366  norm! 1gofdvlisy
    367  call assert_equal('d sentence.', @")
    368  norm! gvisy
    369  call assert_equal('d sentence. ', @")
    370  norm! gvisy
    371  call assert_equal("d sentence. Third\nsentence.", @")
    372 
    373  " Extend visual area in opposite direction.
    374  norm! 1gofdvhasy
    375  call assert_equal(' Second', @")
    376  norm! gvasy
    377  call assert_equal("First sentence. Second", @")
    378 
    379  norm! 1gofdvhisy
    380  call assert_equal('Second', @")
    381  norm! gvisy
    382  call assert_equal(' Second', @")
    383  norm! gvisy
    384  call assert_equal('First sentence. Second', @")
    385 
    386  bwipe!
    387 endfunc
    388 
    389 func Test_Visual_paragraph_textobject()
    390  new
    391  let lines =<< trim [END]
    392    First line.
    393 
    394    Second line.
    395    Third line.
    396    Fourth line.
    397    Fifth line.
    398 
    399    Sixth line.
    400  [END]
    401  call setline(1, lines)
    402 
    403  " When start and end of visual area are identical, 'ap' or 'ip' select
    404  " the whole paragraph.
    405  norm! 4ggvapy
    406  call assert_equal("Second line.\nThird line.\nFourth line.\nFifth line.\n\n", @")
    407  norm! 4ggvipy
    408  call assert_equal("Second line.\nThird line.\nFourth line.\nFifth line.\n", @")
    409 
    410  " When start and end of visual area are not identical, 'ap' or 'ip'
    411  " extend the sentence in direction of the end of the visual area.
    412  " FIXME: actually, it is not sufficient to have different start and
    413  " end of visual selection, the start line and end line have to differ,
    414  " which is not consistent with the documentation.
    415  norm! 4ggVjapy
    416  call assert_equal("Third line.\nFourth line.\nFifth line.\n\n", @")
    417  norm! gvapy
    418  call assert_equal("Third line.\nFourth line.\nFifth line.\n\nSixth line.\n", @")
    419  norm! 4ggVjipy
    420  call assert_equal("Third line.\nFourth line.\nFifth line.\n", @")
    421  norm! gvipy
    422  call assert_equal("Third line.\nFourth line.\nFifth line.\n\n", @")
    423  norm! gvipy
    424  call assert_equal("Third line.\nFourth line.\nFifth line.\n\nSixth line.\n", @")
    425 
    426  " Extend visual area in opposite direction.
    427  norm! 5ggVkapy
    428  call assert_equal("\nSecond line.\nThird line.\nFourth line.\n", @")
    429  norm! gvapy
    430  call assert_equal("First line.\n\nSecond line.\nThird line.\nFourth line.\n", @")
    431  norm! 5ggVkipy
    432  call assert_equal("Second line.\nThird line.\nFourth line.\n", @")
    433  norma gvipy
    434  call assert_equal("\nSecond line.\nThird line.\nFourth line.\n", @")
    435  norm! gvipy
    436  call assert_equal("First line.\n\nSecond line.\nThird line.\nFourth line.\n", @")
    437 
    438  bwipe!
    439 endfunc
    440 
    441 func Test_curswant_not_changed()
    442  new
    443  call setline(1, ['one', 'two'])
    444  au InsertLeave * call getcurpos()
    445  call feedkeys("gg0\<C-V>jI123 \<Esc>j", 'xt')
    446  call assert_equal([0, 2, 1, 0, 1], getcurpos())
    447 
    448  bwipe!
    449  au! InsertLeave
    450 endfunc
    451 
    452 " Tests for "vaBiB", end could be wrong.
    453 func Test_Visual_Block()
    454  new
    455  a
    456 - Bug in "vPPPP" on this text:
    457 {
    458 	cmd;
    459 	{
    460 		cmd;\t/* <-- Start cursor here */
    461 		{
    462 		}
    463 	}
    464 }
    465 .
    466  normal gg
    467  call search('Start cursor here')
    468  normal vaBiBD
    469  call assert_equal(['- Bug in "vPPPP" on this text:',
    470       \ "\t{",
    471       \ "\t}"], getline(1, '$'))
    472 
    473  bw!
    474 endfunc
    475 
    476 " Test for 'p'ut in visual block mode
    477 func Test_visual_block_put()
    478  new
    479  call append(0, ['One', 'Two', 'Three'])
    480  normal gg
    481  yank
    482  call feedkeys("jl\<C-V>ljp", 'xt')
    483  call assert_equal(['One', 'T', 'Tee', 'One', ''], getline(1, '$'))
    484  bw!
    485 endfunc
    486 
    487 func Test_visual_block_put_invalid()
    488  enew!
    489  " behave mswin
    490  set selection=exclusive
    491  norm yy
    492  norm v)Ps/^/	
    493  " this was causing the column to become negative
    494  silent norm ggv)P
    495 
    496  bwipe!
    497  " behave xterm
    498  set selection&
    499 endfunc
    500 
    501 " Visual modes (v V CTRL-V) followed by an operator; count; repeating
    502 func Test_visual_mode_op()
    503  new
    504  call append(0, '')
    505 
    506  call setline(1, 'apple banana cherry')
    507  call cursor(1, 1)
    508  normal lvld.l3vd.
    509  call assert_equal('a y', getline(1))
    510 
    511  call setline(1, ['line 1 line 1', 'line 2 line 2', 'line 3 line 3',
    512        \ 'line 4 line 4', 'line 5 line 5', 'line 6 line 6'])
    513  call cursor(1, 1)
    514  exe "normal Vcnewline\<Esc>j.j2Vd."
    515  call assert_equal(['newline', 'newline'], getline(1, '$'))
    516 
    517  call deletebufline('', 1, '$')
    518  call setline(1, ['xxxxxxxxxxxxx', 'xxxxxxxxxxxxx', 'xxxxxxxxxxxxx',
    519        \ 'xxxxxxxxxxxxx'])
    520  exe "normal \<C-V>jlc  \<Esc>l.l2\<C-V>c----\<Esc>l."
    521  call assert_equal(['    --------x',
    522        \ '    --------x',
    523        \ 'xxxx--------x',
    524        \ 'xxxx--------x'], getline(1, '$'))
    525 
    526  bwipe!
    527 endfunc
    528 
    529 " Visual mode maps (movement and text object)
    530 " Visual mode maps; count; repeating
    531 "   - Simple
    532 "   - With an Ex command (custom text object)
    533 func Test_visual_mode_maps()
    534  new
    535  call append(0, '')
    536 
    537  func SelectInCaps()
    538    let [line1, col1] = searchpos('\u', 'bcnW')
    539    let [line2, col2] = searchpos('.\u', 'nW')
    540    call setpos("'<", [0, line1, col1, 0])
    541    call setpos("'>", [0, line2, col2, 0])
    542    normal! gv
    543  endfunction
    544 
    545  vnoremap W /\u/s-1<CR>
    546  vnoremap iW :<C-U>call SelectInCaps()<CR>
    547 
    548  call setline(1, 'KiwiRaspberryDateWatermelonPeach')
    549  call cursor(1, 1)
    550  exe "normal vWcNo\<Esc>l.fD2vd."
    551  call assert_equal('NoNoberryach', getline(1))
    552 
    553  call setline(1, 'JambuRambutanBananaTangerineMango')
    554  call cursor(1, 1)
    555  exe "normal llviWc-\<Esc>l.l2vdl."
    556  call assert_equal('--ago', getline(1))
    557 
    558  vunmap W
    559  vunmap iW
    560  bwipe!
    561  delfunc SelectInCaps
    562 endfunc
    563 
    564 " Operator-pending mode maps (movement and text object)
    565 "   - Simple
    566 "   - With Ex command moving the cursor
    567 "   - With Ex command and Visual selection (custom text object)
    568 func Test_visual_oper_pending_mode_maps()
    569  new
    570  call append(0, '')
    571 
    572  func MoveToCap()
    573    call search('\u', 'W')
    574  endfunction
    575 
    576  func SelectInCaps()
    577    let [line1, col1] = searchpos('\u', 'bcnW')
    578    let [line2, col2] = searchpos('.\u', 'nW')
    579    call setpos("'<", [0, line1, col1, 0])
    580    call setpos("'>", [0, line2, col2, 0])
    581    normal! gv
    582  endfunction
    583 
    584  onoremap W /\u/<CR>
    585  onoremap <Leader>W :<C-U>call MoveToCap()<CR>
    586  onoremap iW :<C-U>call SelectInCaps()<CR>
    587 
    588  call setline(1, 'PineappleQuinceLoganberryOrangeGrapefruitKiwiZ')
    589  call cursor(1, 1)
    590  exe "normal cW-\<Esc>l.l2.l."
    591  call assert_equal('----Z', getline(1))
    592 
    593  call setline(1, 'JuniperDurianZ')
    594  call cursor(1, 1)
    595  exe "normal g?\WfD."
    596  call assert_equal('WhavcreQhevnaZ', getline(1))
    597 
    598  call setline(1, 'LemonNectarineZ')
    599  call cursor(1, 1)
    600  exe "normal yiWPlciWNew\<Esc>fr."
    601  call assert_equal('LemonNewNewZ', getline(1))
    602 
    603  ounmap W
    604  ounmap <Leader>W
    605  ounmap iW
    606  bwipe!
    607  delfunc MoveToCap
    608  delfunc SelectInCaps
    609 endfunc
    610 
    611 " Patch 7.3.879: Properly abort Operator-pending mode for "dv:<Esc>" etc.
    612 func Test_op_pend_mode_abort()
    613  new
    614  call append(0, '')
    615 
    616  call setline(1, ['zzzz', 'zzzz'])
    617  call cursor(1, 1)
    618 
    619  exe "normal dV:\<CR>dv:\<CR>"
    620  call assert_equal(['zzz'], getline(1, 2))
    621  set nomodifiable
    622  call assert_fails('exe "normal d:\<CR>"', 'E21:')
    623  set modifiable
    624  call feedkeys("dv:\<Esc>dV:\<Esc>", 'xt')
    625  call assert_equal(['zzz'], getline(1, 2))
    626  set nomodifiable
    627  let v:errmsg = ''
    628  call feedkeys("d:\<Esc>", 'xt')
    629  call assert_true(v:errmsg !~# '^E21:')
    630  set modifiable
    631 
    632  bwipe!
    633 endfunc
    634 
    635 func Test_characterwise_visual_mode()
    636  new
    637 
    638  " characterwise visual mode: replace last line
    639  $put ='a'
    640  let @" = 'x'
    641  normal v$p
    642  call assert_equal('x', getline('$'))
    643 
    644  " characterwise visual mode: delete middle line
    645  call deletebufline('', 1, '$')
    646  call append('$', ['a', 'b', 'c'])
    647  normal G
    648  normal kkv$d
    649  call assert_equal(['', 'b', 'c'], getline(1, '$'))
    650 
    651  " characterwise visual mode: delete middle two lines
    652  call deletebufline('', 1, '$')
    653  call append('$', ['a', 'b', 'c'])
    654  normal Gkkvj$d
    655  call assert_equal(['', 'c'], getline(1, '$'))
    656 
    657  " characterwise visual mode: delete last line
    658  call deletebufline('', 1, '$')
    659  call append('$', ['a', 'b', 'c'])
    660  normal Gv$d
    661  call assert_equal(['', 'a', 'b', ''], getline(1, '$'))
    662 
    663  " characterwise visual mode: delete last two lines
    664  call deletebufline('', 1, '$')
    665  call append('$', ['a', 'b', 'c'])
    666  normal Gkvj$d
    667  call assert_equal(['', 'a', ''], getline(1, '$'))
    668 
    669  " characterwise visual mode: use a count with the visual mode from the last
    670  " line in the buffer
    671  %d _
    672  call setline(1, ['one', 'two', 'three', 'four'])
    673  norm! vj$y
    674  norm! G1vy
    675  call assert_equal('four', @")
    676 
    677  " characterwise visual mode: replace a single character line and the eol
    678  %d _
    679  call setline(1, "a")
    680  normal v$rx
    681  call assert_equal(['x'], getline(1, '$'))
    682 
    683  " replace a character with composing characters
    684  call setline(1, "xã̳x")
    685  normal gg0lvrb
    686  call assert_equal("xbx", getline(1))
    687 
    688  bwipe!
    689 endfunc
    690 
    691 func Test_visual_mode_put()
    692  new
    693 
    694  " v_p: replace last character with line register at middle line
    695  call append('$', ['aaa', 'bbb', 'ccc'])
    696  normal G
    697  -2yank
    698  normal k$vp
    699  call assert_equal(['', 'aaa', 'bb', 'aaa', '', 'ccc'], getline(1, '$'))
    700 
    701  " v_p: replace last character with line register at middle line selecting
    702  " newline
    703  call deletebufline('', 1, '$')
    704  call append('$', ['aaa', 'bbb', 'ccc'])
    705  normal G
    706  -2yank
    707  normal k$v$p
    708  call assert_equal(['', 'aaa', 'bb', 'aaa', 'ccc'], getline(1, '$'))
    709 
    710  " v_p: replace last character with line register at last line
    711  call deletebufline('', 1, '$')
    712  call append('$', ['aaa', 'bbb', 'ccc'])
    713  normal G
    714  -2yank
    715  normal $vp
    716  call assert_equal(['', 'aaa', 'bbb', 'cc', 'aaa', ''], getline(1, '$'))
    717 
    718  " v_p: replace last character with line register at last line selecting
    719  " newline
    720  call deletebufline('', 1, '$')
    721  call append('$', ['aaa', 'bbb', 'ccc'])
    722  normal G
    723  -2yank
    724  normal $v$p
    725  call assert_equal(['', 'aaa', 'bbb', 'cc', 'aaa', ''], getline(1, '$'))
    726 
    727  bwipe!
    728 endfunc
    729 
    730 func Test_gv_with_exclusive_selection()
    731  new
    732 
    733  " gv with exclusive selection after an operation
    734  call append('$', ['zzz ', 'äà '])
    735  set selection=exclusive
    736  normal Gkv3lyjv3lpgvcxxx
    737  call assert_equal(['', 'zzz ', 'xxx '], getline(1, '$'))
    738 
    739  " gv with exclusive selection without an operation
    740  call deletebufline('', 1, '$')
    741  call append('$', 'zzz ')
    742  set selection=exclusive
    743  exe "normal G0v3l\<Esc>gvcxxx"
    744  call assert_equal(['', 'xxx '], getline(1, '$'))
    745 
    746  set selection&vim
    747  bwipe!
    748 endfunc
    749 
    750 " Tests for the visual block mode commands
    751 func Test_visual_block_mode()
    752  new
    753  call append(0, '')
    754  call setline(1, repeat(['abcdefghijklm'], 5))
    755  call cursor(1, 1)
    756 
    757  " Test shift-right of a block
    758  exe "normal jllll\<C-V>jj>wll\<C-V>jlll>"
    759  " Test shift-left of a block
    760  exe "normal G$hhhh\<C-V>kk<"
    761  " Test block-insert
    762  exe "normal Gkl\<C-V>kkkIxyz"
    763  " Test block-replace
    764  exe "normal Gllll\<C-V>kkklllrq"
    765  " Test block-change
    766  exe "normal G$khhh\<C-V>hhkkcmno"
    767  call assert_equal(['axyzbcdefghijklm',
    768        \ 'axyzqqqq   mno	      ghijklm',
    769        \ 'axyzqqqqef mno        ghijklm',
    770        \ 'axyzqqqqefgmnoklm',
    771        \ 'abcdqqqqijklm'], getline(1, 5))
    772 
    773  " Test 'C' to change till the end of the line
    774  call cursor(3, 4)
    775  exe "normal! \<C-V>j3lCooo"
    776  call assert_equal(['axyooo', 'axyooo'], getline(3, 4))
    777 
    778  " Test 'D' to delete till the end of the line
    779  call cursor(3, 3)
    780  exe "normal! \<C-V>j2lD"
    781  call assert_equal(['ax', 'ax'], getline(3, 4))
    782 
    783  " Test block insert with a short line that ends before the block
    784  %d _
    785  call setline(1, ["  one", "a", "  two"])
    786  exe "normal gg\<C-V>2jIx"
    787  call assert_equal(["  xone", "a", "  xtwo"], getline(1, '$'))
    788 
    789  " Test block append at EOL with '$' and without '$'
    790  %d _
    791  call setline(1, ["one", "a", "two"])
    792  exe "normal gg$\<C-V>2jAx"
    793  call assert_equal(["onex", "ax", "twox"], getline(1, '$'))
    794  %d _
    795  call setline(1, ["one", "a", "two"])
    796  exe "normal gg3l\<C-V>2jAx"
    797  call assert_equal(["onex", "a  x", "twox"], getline(1, '$'))
    798 
    799  " Test block replace with an empty line in the middle and use $ to jump to
    800  " the end of the line.
    801  %d _
    802  call setline(1, ['one', '', 'two'])
    803  exe "normal gg$\<C-V>2jrx"
    804  call assert_equal(["onx", "", "twx"], getline(1, '$'))
    805 
    806  " Test block replace with an empty line in the middle and move cursor to the
    807  " end of the line
    808  %d _
    809  call setline(1, ['one', '', 'two'])
    810  exe "normal gg2l\<C-V>2jrx"
    811  call assert_equal(["onx", "", "twx"], getline(1, '$'))
    812 
    813  " Replace odd number of characters with a multibyte character
    814  %d _
    815  call setline(1, ['abcd', 'efgh'])
    816  exe "normal ggl\<C-V>2ljr\u1100"
    817  call assert_equal(["a\u1100 ", "e\u1100 "], getline(1, '$'))
    818 
    819  " During visual block append, if the cursor moved outside of the selected
    820  " range, then the edit should not be applied to the block.
    821  %d _
    822  call setline(1, ['aaa', 'bbb', 'ccc'])
    823  exe "normal 2G\<C-V>jAx\<Up>"
    824  call assert_equal(['aaa', 'bxbb', 'ccc'], getline(1, '$'))
    825 
    826  " During visual block append, if the cursor is moved before the start of the
    827  " block, then the new text should be appended there.
    828  %d _
    829  call setline(1, ['aaa', 'bbb', 'ccc'])
    830  exe "normal $\<C-V>2jA\<Left>x"
    831  call assert_equal(['aaxa', 'bbxb', 'ccxc'], getline(1, '$'))
    832  " Repeat the previous test but use 'l' to move the cursor instead of '$'
    833  call setline(1, ['aaa', 'bbb', 'ccc'])
    834  exe "normal! gg2l\<C-V>2jA\<Left>x"
    835  call assert_equal(['aaxa', 'bbxb', 'ccxc'], getline(1, '$'))
    836 
    837  " Change a characterwise motion to a blockwise motion using CTRL-V
    838  %d _
    839  call setline(1, ['123', '456', '789'])
    840  exe "normal ld\<C-V>j"
    841  call assert_equal(['13', '46', '789'], getline(1, '$'))
    842 
    843  " Test from ':help v_b_I_example'
    844  %d _
    845  setlocal tabstop=8 shiftwidth=4
    846  let lines =<< trim END
    847    abcdefghijklmnopqrstuvwxyz
    848    abc		defghijklmnopqrstuvwxyz
    849    abcdef  ghi		jklmnopqrstuvwxyz
    850    abcdefghijklmnopqrstuvwxyz
    851  END
    852  call setline(1, lines)
    853  exe "normal ggfo\<C-V>3jISTRING"
    854  let expected =<< trim END
    855    abcdefghijklmnSTRINGopqrstuvwxyz
    856    abc	      STRING  defghijklmnopqrstuvwxyz
    857    abcdef  ghi   STRING  	jklmnopqrstuvwxyz
    858    abcdefghijklmnSTRINGopqrstuvwxyz
    859  END
    860  call assert_equal(expected, getline(1, '$'))
    861 
    862  " Test from ':help v_b_A_example'
    863  %d _
    864  let lines =<< trim END
    865    abcdefghijklmnopqrstuvwxyz
    866    abc		defghijklmnopqrstuvwxyz
    867    abcdef  ghi		jklmnopqrstuvwxyz
    868    abcdefghijklmnopqrstuvwxyz
    869  END
    870  call setline(1, lines)
    871  exe "normal ggfo\<C-V>3j$ASTRING"
    872  let expected =<< trim END
    873    abcdefghijklmnopqrstuvwxyzSTRING
    874    abc		defghijklmnopqrstuvwxyzSTRING
    875    abcdef  ghi		jklmnopqrstuvwxyzSTRING
    876    abcdefghijklmnopqrstuvwxyzSTRING
    877  END
    878  call assert_equal(expected, getline(1, '$'))
    879 
    880  " Test from ':help v_b_<_example'
    881  %d _
    882  let lines =<< trim END
    883    abcdefghijklmnopqrstuvwxyz
    884    abc		defghijklmnopqrstuvwxyz
    885    abcdef  ghi		jklmnopqrstuvwxyz
    886    abcdefghijklmnopqrstuvwxyz
    887  END
    888  call setline(1, lines)
    889  exe "normal ggfo\<C-V>3j3l<.."
    890  let expected =<< trim END
    891    abcdefghijklmnopqrstuvwxyz
    892    abc	      defghijklmnopqrstuvwxyz
    893    abcdef  ghi   jklmnopqrstuvwxyz
    894    abcdefghijklmnopqrstuvwxyz
    895  END
    896  call assert_equal(expected, getline(1, '$'))
    897 
    898  " Test from ':help v_b_>_example'
    899  %d _
    900  let lines =<< trim END
    901    abcdefghijklmnopqrstuvwxyz
    902    abc		defghijklmnopqrstuvwxyz
    903    abcdef  ghi		jklmnopqrstuvwxyz
    904    abcdefghijklmnopqrstuvwxyz
    905  END
    906  call setline(1, lines)
    907  exe "normal ggfo\<C-V>3j>.."
    908  let expected =<< trim END
    909    abcdefghijklmn		  opqrstuvwxyz
    910    abc			    defghijklmnopqrstuvwxyz
    911    abcdef  ghi			    jklmnopqrstuvwxyz
    912    abcdefghijklmn		  opqrstuvwxyz
    913  END
    914  call assert_equal(expected, getline(1, '$'))
    915 
    916  " Test from ':help v_b_r_example'
    917  %d _
    918  let lines =<< trim END
    919    abcdefghijklmnopqrstuvwxyz
    920    abc		defghijklmnopqrstuvwxyz
    921    abcdef  ghi		jklmnopqrstuvwxyz
    922    abcdefghijklmnopqrstuvwxyz
    923  END
    924  call setline(1, lines)
    925  exe "normal ggfo\<C-V>5l3jrX"
    926  let expected =<< trim END
    927    abcdefghijklmnXXXXXXuvwxyz
    928    abc	      XXXXXXhijklmnopqrstuvwxyz
    929    abcdef  ghi   XXXXXX    jklmnopqrstuvwxyz
    930    abcdefghijklmnXXXXXXuvwxyz
    931  END
    932  call assert_equal(expected, getline(1, '$'))
    933 
    934  bwipe!
    935  set tabstop& shiftwidth&
    936 endfunc
    937 
    938 func Test_visual_force_motion_feedkeys()
    939    onoremap <expr> i- execute('let g:mode = mode(1)')->slice(0, 0)
    940    call feedkeys('dvi-', 'x')
    941    call assert_equal('nov', g:mode)
    942    call feedkeys('di-', 'x')
    943    call assert_equal('no', g:mode)
    944    ounmap i-
    945 endfunc
    946 
    947 " Test block-insert using cursor keys for movement
    948 func Test_visual_block_insert_cursor_keys()
    949  new
    950  call append(0, ['aaaaaa', 'bbbbbb', 'cccccc', 'dddddd'])
    951  call cursor(1, 1)
    952 
    953  exe "norm! l\<C-V>jjjlllI\<Right>\<Right>  \<Esc>"
    954  call assert_equal(['aaa  aaa', 'bbb  bbb', 'ccc  ccc', 'ddd  ddd'],
    955        \ getline(1, 4))
    956 
    957  call deletebufline('', 1, '$')
    958  call setline(1, ['xaaa', 'bbbb', 'cccc', 'dddd'])
    959  call cursor(1, 1)
    960  exe "norm! \<C-V>jjjI<>\<Left>p\<Esc>"
    961  call assert_equal(['<p>xaaa', '<p>bbbb', '<p>cccc', '<p>dddd'],
    962        \ getline(1, 4))
    963  bwipe!
    964 endfunc
    965 
    966 func Test_visual_block_create()
    967  new
    968  call append(0, '')
    969  " Test for Visual block was created with the last <C-v>$
    970  call setline(1, ['A23', '4567'])
    971  call cursor(1, 1)
    972  exe "norm! l\<C-V>j$Aab\<Esc>"
    973  call assert_equal(['A23ab', '4567ab'], getline(1, 2))
    974 
    975  " Test for Visual block was created with the middle <C-v>$ (1)
    976  call deletebufline('', 1, '$')
    977  call setline(1, ['B23', '4567'])
    978  call cursor(1, 1)
    979  exe "norm! l\<C-V>j$hAab\<Esc>"
    980  call assert_equal(['B23 ab', '4567ab'], getline(1, 2))
    981 
    982  " Test for Visual block was created with the middle <C-v>$ (2)
    983  call deletebufline('', 1, '$')
    984  call setline(1, ['C23', '4567'])
    985  call cursor(1, 1)
    986  exe "norm! l\<C-V>j$hhAab\<Esc>"
    987  call assert_equal(['C23ab', '456ab7'], getline(1, 2))
    988  bwipe!
    989 endfunc
    990 
    991 " Test for Visual block insert when virtualedit=all
    992 func Test_virtualedit_visual_block()
    993  set ve=all
    994  new
    995  call append(0, ["\t\tline1", "\t\tline2", "\t\tline3"])
    996  call cursor(1, 1)
    997  exe "norm! 07l\<C-V>jjIx\<Esc>"
    998  call assert_equal(["       x \tline1",
    999        \ "       x \tline2",
   1000        \ "       x \tline3"], getline(1, 3))
   1001 
   1002  " Test for Visual block append when virtualedit=all
   1003  exe "norm! 012l\<C-v>jjAx\<Esc>"
   1004  call assert_equal(['       x     x   line1',
   1005        \ '       x     x   line2',
   1006        \ '       x     x   line3'], getline(1, 3))
   1007  set ve=
   1008  bwipe!
   1009 endfunc
   1010 
   1011 " Test for changing case
   1012 func Test_visual_change_case()
   1013  new
   1014  " gUe must uppercase a whole word, also when ß changes to ẞ
   1015  exe "normal Gothe youtußeuu end\<Esc>Ypk0wgUe\r"
   1016  " gUfx must uppercase until x, inclusive.
   1017  exe "normal O- youßtußexu -\<Esc>0fogUfx\r"
   1018  " VU must uppercase a whole line
   1019  exe "normal YpkVU\r"
   1020  " same, when it's the last line in the buffer
   1021  exe "normal YPGi111\<Esc>VUddP\r"
   1022  " Uppercase two lines
   1023  exe "normal Oblah di\rdoh dut\<Esc>VkUj\r"
   1024  " Uppercase part of two lines
   1025  exe "normal ddppi333\<Esc>k0i222\<Esc>fyllvjfuUk"
   1026  call assert_equal(['the YOUTUẞEUU end', '- yOUẞTUẞEXu -',
   1027        \ 'THE YOUTUẞEUU END', '111THE YOUTUẞEUU END', 'BLAH DI', 'DOH DUT',
   1028        \ '222the yoUTUẞEUU END', '333THE YOUTUßeuu end'], getline(2, '$'))
   1029  bwipe!
   1030 endfunc
   1031 
   1032 " Test for Visual replace using Enter or NL
   1033 func Test_visual_replace_crnl()
   1034  new
   1035  exe "normal G3o123456789\e2k05l\<C-V>2jr\r"
   1036  exe "normal G3o98765\e2k02l\<C-V>2jr\<C-V>\r\n"
   1037  exe "normal G3o123456789\e2k05l\<C-V>2jr\n"
   1038  exe "normal G3o98765\e2k02l\<C-V>2jr\<C-V>\n"
   1039  call assert_equal(['12345', '789', '12345', '789', '12345', '789', "98\r65",
   1040        \ "98\r65", "98\r65", '12345', '789', '12345', '789', '12345', '789',
   1041        \ "98\n65", "98\n65", "98\n65"], getline(2, '$'))
   1042  bwipe!
   1043 endfunc
   1044 
   1045 func Test_ve_block_curpos()
   1046  new
   1047  " Test cursor position. When ve=block and Visual block mode and $gj
   1048  call append(0, ['12345', '789'])
   1049  call cursor(1, 3)
   1050  set virtualedit=block
   1051  exe "norm! \<C-V>$gj\<Esc>"
   1052  call assert_equal([0, 2, 4, 0], getpos("'>"))
   1053  set virtualedit=
   1054  bwipe!
   1055 endfunc
   1056 
   1057 " Test for block_insert when replacing spaces in front of the a with tabs
   1058 func Test_block_insert_replace_tabs()
   1059  new
   1060  set ts=8 sts=4 sw=4
   1061  call append(0, ["#define BO_ALL\t    0x0001",
   1062        \ "#define BO_BS\t    0x0002",
   1063        \ "#define BO_CRSR\t    0x0004"])
   1064  call cursor(1, 1)
   1065  exe "norm! f0\<C-V>2jI\<tab>\<esc>"
   1066  call assert_equal([
   1067        \ "#define BO_ALL\t\t0x0001",
   1068        \ "#define BO_BS\t    \t0x0002",
   1069        \ "#define BO_CRSR\t    \t0x0004", ''], getline(1, '$'))
   1070  set ts& sts& sw&
   1071  bwipe!
   1072 endfunc
   1073 
   1074 " Test for * register in :
   1075 func Test_star_register()
   1076  call assert_fails('*bfirst', 'E16:')
   1077  new
   1078  call setline(1, ['foo', 'bar', 'baz', 'qux'])
   1079  exe "normal jVj\<ESC>"
   1080  *yank r
   1081  call assert_equal("bar\nbaz\n", @r)
   1082 
   1083  delmarks < >
   1084  call assert_fails('*yank', 'E20:')
   1085  bw!
   1086 endfunc
   1087 
   1088 " Test for changing text in visual mode with 'exclusive' selection
   1089 func Test_exclusive_selection()
   1090  new
   1091  call setline(1, ['one', 'two'])
   1092  set selection=exclusive
   1093  call feedkeys("vwcabc", 'xt')
   1094  call assert_equal('abctwo', getline(1))
   1095  call setline(1, ["\tone"])
   1096  set virtualedit=all
   1097  call feedkeys('0v2lcl', 'xt')
   1098  call assert_equal('l      one', getline(1))
   1099  set virtualedit&
   1100  set selection&
   1101  bw!
   1102 endfunc
   1103 
   1104 " Test for inclusive motion in visual mode with 'exclusive' selection
   1105 func Test_inclusive_motion_selection_exclusive()
   1106  func s:compare_exclu_inclu(line, keys, expected_exclu)
   1107    let msg = "data: '" . a:line . "' operation: '" . a:keys . "'"
   1108    call setline(1, a:line)
   1109    set selection=exclusive
   1110    call feedkeys(a:keys, 'xt')
   1111    call assert_equal(a:expected_exclu, getpos('.'), msg)
   1112    let pos_ex = col('.')
   1113    set selection=inclusive
   1114    call feedkeys(a:keys, 'xt')
   1115    let pos_in = col('.')
   1116    call assert_equal(1, pos_ex - pos_in, msg)
   1117  endfunc
   1118 
   1119  new
   1120  " Test 'e' motion
   1121  set selection=exclusive
   1122  call setline(1, 'eins zwei drei')
   1123  norm! ggvey
   1124  call assert_equal('eins', @")
   1125  call setline(1, 'abc(abc)abc')
   1126  norm! ggveeed
   1127  call assert_equal(')abc', getline(1))
   1128  call setline(1, 'abc(abc)abc')
   1129  norm! gg3lvey
   1130  call assert_equal('(abc', @")
   1131  call s:compare_exclu_inclu('abc(abc)abc', 'ggveee', [0, 1, 8, 0])
   1132  " Test 'f' motion
   1133  call s:compare_exclu_inclu('geschwindigkeit', 'ggvfefe', [0, 1, 14, 0])
   1134  call s:compare_exclu_inclu('loooooooooooong', 'ggv2fo2fo2fo', [0, 1, 8, 0])
   1135  " Test 't' motion
   1136  call s:compare_exclu_inclu('geschwindigkeit', 'ggv2te', [0, 1, 13, 0])
   1137  call s:compare_exclu_inclu('loooooooooooong', 'gglv2to2to2to', [0, 1, 6, 0])
   1138  " Test ';' motion
   1139  call s:compare_exclu_inclu('geschwindigkeit', 'ggvfi;;', [0, 1, 15, 0])
   1140  call s:compare_exclu_inclu('geschwindigkeit', 'ggvti;;', [0, 1, 14, 0])
   1141  call s:compare_exclu_inclu('loooooooooooong', 'ggv2fo;;', [0, 1, 6, 0])
   1142  call s:compare_exclu_inclu('loooooooooooong', 'ggvl2to;;', [0, 1, 6, 0])
   1143  " Clean up
   1144  set selection&
   1145  bw!
   1146 endfunc
   1147 
   1148 " Test for starting linewise visual with a count.
   1149 " This test needs to be run without any previous visual mode. Otherwise the
   1150 " count will use the count from the previous visual mode.
   1151 func Test_linewise_visual_with_count()
   1152  let after =<< trim [CODE]
   1153    call setline(1, ['one', 'two', 'three', 'four'])
   1154    norm! 3Vy
   1155    call assert_equal("one\ntwo\nthree\n", @")
   1156    call writefile(v:errors, 'Xtestout')
   1157    qall!
   1158  [CODE]
   1159  if RunVim([], after, '')
   1160    call assert_equal([], readfile('Xtestout'))
   1161    call delete('Xtestout')
   1162  endif
   1163 endfunc
   1164 
   1165 " Test for starting characterwise visual with a count.
   1166 " This test needs to be run without any previous visual mode. Otherwise the
   1167 " count will use the count from the previous visual mode.
   1168 func Test_characterwise_visual_with_count()
   1169  let after =<< trim [CODE]
   1170    call setline(1, ['one two', 'three'])
   1171    norm! l5vy
   1172    call assert_equal("ne tw", @")
   1173    call writefile(v:errors, 'Xtestout')
   1174    qall!
   1175  [CODE]
   1176  if RunVim([], after, '')
   1177    call assert_equal([], readfile('Xtestout'))
   1178    call delete('Xtestout')
   1179  endif
   1180 endfunc
   1181 
   1182 " Test for visually selecting an inner block (iB)
   1183 func Test_visual_inner_block()
   1184  new
   1185  call setline(1, ['one', '{', 'two', '{', 'three', '}', 'four', '}', 'five'])
   1186  call cursor(5, 1)
   1187  " visually select all the lines in the block and then execute iB
   1188  call feedkeys("ViB\<C-C>", 'xt')
   1189  call assert_equal([0, 5, 1, 0], getpos("'<"))
   1190  call assert_equal([0, 5, 6, 0], getpos("'>"))
   1191  " visually select two inner blocks
   1192  call feedkeys("ViBiB\<C-C>", 'xt')
   1193  call assert_equal([0, 3, 1, 0], getpos("'<"))
   1194  call assert_equal([0, 7, 5, 0], getpos("'>"))
   1195  " try to select non-existing inner block
   1196  call cursor(5, 1)
   1197  call assert_beeps('normal ViBiBiB')
   1198  " try to select an unclosed inner block
   1199  8,9d
   1200  call cursor(5, 1)
   1201  call assert_beeps('normal ViBiB')
   1202  bw!
   1203 endfunc
   1204 
   1205 func Test_visual_put_in_block()
   1206  new
   1207  call setline(1, ['xxxx', 'y∞yy', 'zzzz'])
   1208  normal 1G2yl
   1209  exe "normal 1G2l\<C-V>jjlp"
   1210  call assert_equal(['xxxx', 'y∞xx', 'zzxx'], getline(1, 3))
   1211  bwipe!
   1212 endfunc
   1213 
   1214 func Test_visual_put_in_block_using_zp()
   1215  new
   1216  " paste using zP
   1217  call setline(1, ['/path;text', '/path;text', '/path;text', '',
   1218    \ '/subdir',
   1219    \ '/longsubdir',
   1220    \ '/longlongsubdir'])
   1221  exe "normal! 5G\<c-v>2j$y"
   1222  norm! 1Gf;zP
   1223  call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
   1224  %d
   1225  " paste using zP
   1226  call setline(1, ['/path;text', '/path;text', '/path;text', '',
   1227    \ '/subdir',
   1228    \ '/longsubdir',
   1229    \ '/longlongsubdir'])
   1230  exe "normal! 5G\<c-v>2j$y"
   1231  norm! 1Gf;hzp
   1232  call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
   1233  bwipe!
   1234 endfunc
   1235 
   1236 func Test_visual_put_in_block_using_zy_and_zp()
   1237  new
   1238 
   1239  " Test 1) Paste using zp - after the cursor without trailing spaces
   1240  call setline(1, ['/path;text', '/path;text', '/path;text', '',
   1241    \ 'texttext  /subdir           columntext',
   1242 	\ 'texttext  /longsubdir       columntext',
   1243    \ 'texttext  /longlongsubdir   columntext'])
   1244  exe "normal! 5G0f/\<c-v>2jezy"
   1245  norm! 1G0f;hzp
   1246  call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
   1247 
   1248  " Test 2) Paste using zP - in front of the cursor without trailing spaces
   1249  %d
   1250  call setline(1, ['/path;text', '/path;text', '/path;text', '',
   1251    \ 'texttext  /subdir           columntext',
   1252 	\ 'texttext  /longsubdir       columntext',
   1253    \ 'texttext  /longlongsubdir   columntext'])
   1254  exe "normal! 5G0f/\<c-v>2jezy"
   1255  norm! 1G0f;zP
   1256  call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
   1257 
   1258  " Test 3) Paste using p - with trailing spaces
   1259  %d
   1260  call setline(1, ['/path;text', '/path;text', '/path;text', '',
   1261    \ 'texttext  /subdir           columntext',
   1262 	\ 'texttext  /longsubdir       columntext',
   1263    \ 'texttext  /longlongsubdir   columntext'])
   1264  exe "normal! 5G0f/\<c-v>2jezy"
   1265  norm! 1G0f;hp
   1266  call assert_equal(['/path/subdir        ;text', '/path/longsubdir    ;text', '/path/longlongsubdir;text'], getline(1, 3))
   1267 
   1268  " Test 4) Paste using P - with trailing spaces
   1269  %d
   1270  call setline(1, ['/path;text', '/path;text', '/path;text', '',
   1271    \ 'texttext  /subdir           columntext',
   1272 	\ 'texttext  /longsubdir       columntext',
   1273    \ 'texttext  /longlongsubdir   columntext'])
   1274  exe "normal! 5G0f/\<c-v>2jezy"
   1275  norm! 1G0f;P
   1276  call assert_equal(['/path/subdir        ;text', '/path/longsubdir    ;text', '/path/longlongsubdir;text'], getline(1, 3))
   1277 
   1278  " Test 5) Yank with spaces inside the block
   1279  %d
   1280  call setline(1, ['/path;text', '/path;text', '/path;text', '',
   1281    \ 'texttext  /sub    dir/           columntext',
   1282    \ 'texttext  /lon    gsubdir/       columntext',
   1283    \ 'texttext  /lon    glongsubdir/   columntext'])
   1284  exe "normal! 5G0f/\<c-v>2jf/zy"
   1285  norm! 1G0f;zP
   1286  call assert_equal(['/path/sub    dir/;text', '/path/lon    gsubdir/;text', '/path/lon    glongsubdir/;text'], getline(1, 3))
   1287  bwipe!
   1288 endfunc
   1289 
   1290 func Test_visual_put_blockedit_zy_and_zp()
   1291  new
   1292 
   1293  call setline(1, ['aa', 'bbbbb', 'ccc', '', 'XX', 'GGHHJ', 'RTZU'])
   1294  exe "normal! gg0\<c-v>2j$zy"
   1295  norm! 5gg0zP
   1296  call assert_equal(['aa', 'bbbbb', 'ccc', '', 'aaXX', 'bbbbbGGHHJ', 'cccRTZU'], getline(1, 7))
   1297  "
   1298  " now with blockmode editing
   1299  sil %d
   1300  :set ve=block
   1301  call setline(1, ['aa', 'bbbbb', 'ccc', '', 'XX', 'GGHHJ', 'RTZU'])
   1302  exe "normal! gg0\<c-v>2j$zy"
   1303  norm! 5gg0zP
   1304  call assert_equal(['aa', 'bbbbb', 'ccc', '', 'aaXX', 'bbbbbGGHHJ', 'cccRTZU'], getline(1, 7))
   1305  set ve&vim
   1306  bw!
   1307 endfunc
   1308 
   1309 func Test_visual_block_yank_zy()
   1310  new
   1311  " this was reading before the start of the line
   1312  exe "norm o\<C-T>\<Esc>\<C-V>zy"
   1313  bwipe!
   1314 endfunc
   1315 
   1316 func Test_visual_block_with_virtualedit()
   1317  CheckScreendump
   1318 
   1319  let lines =<< trim END
   1320    call setline(1, ['aaaaaa', 'bbbb', 'cc'])
   1321    set virtualedit=block
   1322    normal G
   1323  END
   1324  call writefile(lines, 'XTest_block')
   1325 
   1326  let buf = RunVimInTerminal('-S XTest_block', {'rows': 8, 'cols': 50})
   1327  call term_sendkeys(buf, "\<C-V>gg$")
   1328  call VerifyScreenDump(buf, 'Test_visual_block_with_virtualedit', {})
   1329 
   1330  call term_sendkeys(buf, "\<Esc>gg\<C-V>G$")
   1331  call VerifyScreenDump(buf, 'Test_visual_block_with_virtualedit2', {})
   1332 
   1333  " clean up
   1334  call term_sendkeys(buf, "\<Esc>")
   1335  call StopVimInTerminal(buf)
   1336  call delete('XTest_block')
   1337 endfunc
   1338 
   1339 func Test_visual_block_ctrl_w_f()
   1340  " Empty block selected in new buffer should not result in an error.
   1341  au! BufNew foo sil norm f
   1342  edit foo
   1343 
   1344  au! BufNew
   1345 endfunc
   1346 
   1347 func Test_visual_block_append_invalid_char()
   1348  " this was going over the end of the line
   1349  set isprint=@,161-255
   1350  new
   1351  call setline(1, ['	   let xxx', 'xxxxxˆ', 'xxxxxxxxxxx'])
   1352  exe "normal 0\<C-V>jjA-\<Esc>"
   1353  call assert_equal(['	-   let xxx', 'xxxxx   -ˆ', 'xxxxxxxx-xxx'], getline(1, 3))
   1354  bwipe!
   1355  set isprint&
   1356 endfunc
   1357 
   1358 func Test_visual_block_with_substitute()
   1359  " this was reading beyond the end of the line
   1360  new
   1361  norm a0)
   1362  sil! norm  O
   1363  s/)
   1364  sil! norm 
   1365  bwipe!
   1366 endfunc
   1367 
   1368 func Test_visual_reselect_with_count()
   1369  enew
   1370  call setline(1, ['aaaaaa', '✗ bbbb', '✗ bbbb'])
   1371  exe "normal! 2Gw\<C-V>jed"
   1372  exe "normal! gg0lP"
   1373  call assert_equal(['abbbbaaaaa', '✗bbbb ', '✗ '], getline(1, '$'))
   1374 
   1375  exe "normal! 1vr."
   1376  call assert_equal(['a....aaaaa', '✗.... ', '✗ '], getline(1, '$'))
   1377 
   1378  bwipe!
   1379 
   1380  " this was causing an illegal memory access
   1381  let lines =<< trim END
   1382 
   1383 
   1384 
   1385      :
   1386      r<sfile>
   1387      exe "%norm e3\<c-v>kr\t"
   1388      :
   1389 
   1390      :
   1391  END
   1392  call writefile(lines, 'XvisualReselect')
   1393  source XvisualReselect
   1394 
   1395  bwipe!
   1396  call delete('XvisualReselect')
   1397 endfunc
   1398 
   1399 func Test_visual_reselect_exclusive()
   1400  new
   1401  call setline(1, ['abcde', 'abcde'])
   1402  set selection=exclusive
   1403  normal 1G0viwd
   1404  normal 2G01vd
   1405  call assert_equal(['', ''], getline(1, 2))
   1406 
   1407  set selection&
   1408  bwipe!
   1409 endfunc
   1410 
   1411 func Test_visual_block_insert_round_off()
   1412  new
   1413  " The number of characters are tuned to fill a 4096 byte allocated block,
   1414  " so that valgrind reports going over the end.
   1415  call setline(1, ['xxxxx', repeat('0', 1350), "\t", repeat('x', 60)])
   1416  exe "normal gg0\<C-V>GI" .. repeat('0', 1320) .. "\<Esc>"
   1417  bwipe!
   1418 endfunc
   1419 
   1420 " this was causing an ml_get error
   1421 func Test_visual_exchange_windows()
   1422  enew!
   1423  new
   1424  call setline(1, ['foo', 'bar'])
   1425  exe "normal G\<C-V>gg\<C-W>\<C-X>OO\<Esc>"
   1426  bwipe!
   1427  bwipe!
   1428 endfunc
   1429 
   1430 " this was leaving the end of the Visual area beyond the end of a line
   1431 func Test_visual_ex_copy_line()
   1432  new
   1433  call setline(1, ["aaa", "bbbbbbbbbxbb"])
   1434  /x
   1435  exe "normal ggvjfxO"
   1436  t0
   1437  normal gNU
   1438  bwipe!
   1439 endfunc
   1440 
   1441 " This was leaving the end of the Visual area beyond the end of a line.
   1442 " Set 'undolevels' to start a new undo block.
   1443 func Test_visual_undo_deletes_last_line()
   1444  new
   1445  call setline(1, ["aaa", "ccc", "dyd"])
   1446  set undolevels=100
   1447  exe "normal obbbbbbbbbxbb\<Esc>"
   1448  set undolevels=100
   1449  /y
   1450  exe "normal ggvjfxO"
   1451  undo
   1452  normal gNU
   1453 
   1454  bwipe!
   1455 endfunc
   1456 
   1457 func Test_visual_paste()
   1458  new
   1459 
   1460  " v_p overwrites unnamed register.
   1461  call setline(1, ['xxxx'])
   1462  call setreg('"', 'foo')
   1463  call setreg('-', 'bar')
   1464  normal gg0vp
   1465  call assert_equal('x', @")
   1466  call assert_equal('x', @-)
   1467  call assert_equal('fooxxx', getline(1))
   1468  normal $vp
   1469  call assert_equal('x', @")
   1470  call assert_equal('x', @-)
   1471  call assert_equal('fooxxx', getline(1))
   1472  " Test with a different register as unnamed register.
   1473  call setline(2, ['baz'])
   1474  normal 2gg0"rD
   1475  call assert_equal('baz', @")
   1476  normal gg0vp
   1477  call assert_equal('f', @")
   1478  call assert_equal('f', @-)
   1479  call assert_equal('bazooxxx', getline(1))
   1480  normal $vp
   1481  call assert_equal('x', @")
   1482  call assert_equal('x', @-)
   1483  call assert_equal('bazooxxf', getline(1))
   1484 
   1485  bwipe!
   1486 endfunc
   1487 
   1488 func Test_visual_paste_clipboard()
   1489  CheckFeature clipboard_working
   1490 
   1491  if has('gui')
   1492    " auto select feature breaks tests
   1493    set guioptions-=a
   1494  endif
   1495 
   1496  " v_P does not overwrite unnamed register.
   1497  call setline(1, ['xxxx'])
   1498  call setreg('"', 'foo')
   1499  call setreg('-', 'bar')
   1500  normal gg0vP
   1501  call assert_equal('foo', @")
   1502  call assert_equal('bar', @-)
   1503  call assert_equal('fooxxx', getline(1))
   1504  normal $vP
   1505  call assert_equal('foo', @")
   1506  call assert_equal('bar', @-)
   1507  call assert_equal('fooxxfoo', getline(1))
   1508  " Test with a different register as unnamed register.
   1509  call setline(2, ['baz'])
   1510  normal 2gg0"rD
   1511  call assert_equal('baz', @")
   1512  normal gg0vP
   1513  call assert_equal('baz', @")
   1514  call assert_equal('bar', @-)
   1515  call assert_equal('bazooxxfoo', getline(1))
   1516  normal $vP
   1517  call assert_equal('baz', @")
   1518  call assert_equal('bar', @-)
   1519  call assert_equal('bazooxxfobaz', getline(1))
   1520 
   1521  " Test for unnamed clipboard
   1522  set clipboard=unnamed
   1523  call setline(1, ['xxxx'])
   1524  call setreg('"', 'foo')
   1525  call setreg('-', 'bar')
   1526  call setreg('*', 'baz')
   1527  normal gg0vP
   1528  call assert_equal('foo', @")
   1529  call assert_equal('bar', @-)
   1530  call assert_equal('baz', @*)
   1531  call assert_equal('bazxxx', getline(1))
   1532 
   1533  " Test for unnamedplus clipboard
   1534  if has('unnamedplus')
   1535    set clipboard=unnamedplus
   1536    call setline(1, ['xxxx'])
   1537    call setreg('"', 'foo')
   1538    call setreg('-', 'bar')
   1539    call setreg('+', 'baz')
   1540    normal gg0vP
   1541    call assert_equal('foo', @")
   1542    call assert_equal('bar', @-)
   1543    call assert_equal('baz', @+)
   1544    call assert_equal('bazxxx', getline(1))
   1545  endif
   1546 
   1547  set clipboard&
   1548  if has('gui')
   1549    set guioptions&
   1550  endif
   1551  bwipe!
   1552 endfunc
   1553 
   1554 func Test_visual_area_adjusted_when_hiding()
   1555  " The Visual area ended after the end of the line after :hide
   1556  call setline(1, 'xxx')
   1557  vsplit Xfile
   1558  call setline(1, 'xxxxxxxx')
   1559  norm! $o
   1560  hid
   1561  norm! zW
   1562  bwipe!
   1563  bwipe!
   1564 endfunc
   1565 
   1566 func Test_switch_buffer_ends_visual_mode()
   1567  enew
   1568  call setline(1, 'foo')
   1569  set hidden
   1570  set virtualedit=all
   1571  let buf1 = bufnr()
   1572  enew
   1573  let buf2 = bufnr()
   1574  call setline(1, ['', '', '', ''])
   1575  call cursor(4, 5)
   1576  call feedkeys("\<C-V>3k4h", 'xt')
   1577  exe 'buffer' buf1
   1578  call assert_equal('n', mode())
   1579 
   1580  set nohidden
   1581  set virtualedit=
   1582  bwipe!
   1583  exe 'bwipe!' buf2
   1584 endfunc
   1585 
   1586 " Check fix for the heap-based buffer overflow bug found in the function
   1587 " utfc_ptr2len and reported at
   1588 " https://huntr.dev/bounties/ae933869-a1ec-402a-bbea-d51764c6618e
   1589 func Test_heap_buffer_overflow()
   1590  enew
   1591  set updatecount=0
   1592 
   1593  norm R0
   1594  split other
   1595  norm R000
   1596  exe "norm \<C-V>l"
   1597  ball
   1598  call assert_equal(getpos("."), getpos("v"))
   1599  call assert_equal('n', mode())
   1600  norm zW
   1601 
   1602  %bwipe!
   1603  set updatecount&
   1604 endfunc
   1605 
   1606 " Test Visual highlight with cursor at end of screen line and 'showbreak'
   1607 func Test_visual_hl_with_showbreak()
   1608  CheckScreendump
   1609 
   1610  let lines =<< trim END
   1611    setlocal showbreak=+
   1612    call setline(1, repeat('a', &columns + 10))
   1613    normal g$v4lo
   1614  END
   1615  call writefile(lines, 'XTest_visual_sbr', 'D')
   1616 
   1617  let buf = RunVimInTerminal('-S XTest_visual_sbr', {'rows': 6, 'cols': 50})
   1618  call VerifyScreenDump(buf, 'Test_visual_hl_with_showbreak', {})
   1619 
   1620  " clean up
   1621  call term_sendkeys(buf, "\<Esc>")
   1622  call StopVimInTerminal(buf)
   1623 endfunc
   1624 
   1625 func Test_Visual_r_CTRL_C()
   1626  new
   1627  " visual r_cmd
   1628  call setline(1, ['   '])
   1629  call feedkeys("\<c-v>$r\<c-c>", 'tx')
   1630  call assert_equal([''], getline(1, 1))
   1631 
   1632  " visual gr_cmd
   1633  call setline(1, ['   '])
   1634  call feedkeys("\<c-v>$gr\<c-c>", 'tx')
   1635  call assert_equal([''], getline(1, 1))
   1636  bw!
   1637 endfunc
   1638 
   1639 func Test_visual_drag_out_of_window()
   1640  rightbelow vnew
   1641  call setline(1, '123456789')
   1642  set mouse=a
   1643  func ClickExpr(off)
   1644    call Ntest_setmouse(1, getwininfo(win_getid())[0].wincol + a:off)
   1645    return "\<LeftMouse>"
   1646  endfunc
   1647  func DragExpr(off)
   1648    call Ntest_setmouse(1, getwininfo(win_getid())[0].wincol + a:off)
   1649    return "\<LeftDrag>"
   1650  endfunc
   1651 
   1652  nnoremap <expr> <F2> ClickExpr(5)
   1653  nnoremap <expr> <F3> DragExpr(-1)
   1654  redraw
   1655  call feedkeys("\<F2>\<F3>\<LeftRelease>", 'tx')
   1656  call assert_equal([1, 6], [col('.'), col('v')])
   1657  call feedkeys("\<Esc>", 'tx')
   1658 
   1659  nnoremap <expr> <F2> ClickExpr(6)
   1660  nnoremap <expr> <F3> DragExpr(-2)
   1661  redraw
   1662  call feedkeys("\<F2>\<F3>\<LeftRelease>", 'tx')
   1663  call assert_equal([1, 7], [col('.'), col('v')])
   1664  call feedkeys("\<Esc>", 'tx')
   1665 
   1666  nunmap <F2>
   1667  nunmap <F3>
   1668  delfunc ClickExpr
   1669  delfunc DragExpr
   1670  set mouse&
   1671  bwipe!
   1672 endfunc
   1673 
   1674 func Test_visual_substitute_visual()
   1675  new
   1676  call setline(1, ['one', 'two', 'three'])
   1677  call feedkeys("Gk\<C-V>j$:s/\\%V\\_.*\\%V/foobar\<CR>", 'tx')
   1678  call assert_equal(['one', 'foobar'], getline(1, '$'))
   1679  bwipe!
   1680 endfunc
   1681 
   1682 func Test_virtualedit_exclusive_selection()
   1683  new
   1684  set virtualedit=all selection=exclusive
   1685 
   1686  call setline(1, "a\tb")
   1687  normal! 0v8ly
   1688  call assert_equal("a\t", getreg('"'))
   1689  normal! 0v6ly
   1690  call assert_equal('a     ', getreg('"'))
   1691  normal! 06lv2ly
   1692  call assert_equal('  ', getreg('"'))
   1693 
   1694  set virtualedit& selection&
   1695  bwipe!
   1696 endfunc
   1697 
   1698 func Test_visual_getregion()
   1699  let lines =<< trim END
   1700    new
   1701 
   1702    call setline(1, ['one', 'two', 'three'])
   1703 
   1704    #" Visual mode
   1705    call cursor(1, 1)
   1706    call feedkeys("\<ESC>vjl", 'tx')
   1707 
   1708    call assert_equal(['one', 'tw'],
   1709          \ 'v'->getpos()->getregion(getpos('.')))
   1710    call assert_equal([
   1711          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
   1712          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 0]]
   1713          \ ],
   1714          \ 'v'->getpos()->getregionpos(getpos('.')))
   1715 
   1716    call assert_equal(['one', 'tw'],
   1717          \ '.'->getpos()->getregion(getpos('v')))
   1718    call assert_equal([
   1719          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
   1720          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 0]]
   1721          \ ],
   1722          \ '.'->getpos()->getregionpos(getpos('v')))
   1723 
   1724    call assert_equal(['o'],
   1725          \ 'v'->getpos()->getregion(getpos('v')))
   1726    call assert_equal([
   1727          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 1, 0]],
   1728          \ ],
   1729          \ 'v'->getpos()->getregionpos(getpos('v')))
   1730 
   1731    call assert_equal(['w'],
   1732          \ '.'->getpos()->getregion(getpos('.'), {'type': 'v' }))
   1733    call assert_equal([
   1734          \   [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 0]],
   1735          \ ],
   1736          \ '.'->getpos()->getregionpos(getpos('.'), {'type': 'v' }))
   1737 
   1738    call assert_equal(['one', 'two'],
   1739          \ getpos('.')->getregion(getpos('v'), {'type': 'V' }))
   1740    call assert_equal([
   1741          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
   1742          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
   1743          \ ],
   1744          \ getpos('.')->getregionpos(getpos('v'), {'type': 'V' }))
   1745 
   1746    call assert_equal(['on', 'tw'],
   1747          \ getpos('.')->getregion(getpos('v'), {'type': "\<C-v>" }))
   1748    call assert_equal([
   1749          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 0]],
   1750          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 0]],
   1751          \ ],
   1752          \ getpos('.')->getregionpos(getpos('v'), {'type': "\<C-v>" }))
   1753 
   1754    #" Line visual mode
   1755    call cursor(1, 1)
   1756    call feedkeys("\<ESC>Vl", 'tx')
   1757    call assert_equal(['one'],
   1758          \ getregion(getpos('v'), getpos('.'), {'type': 'V' }))
   1759    call assert_equal(['one'],
   1760          \ getregion(getpos('.'), getpos('v'), {'type': 'V' }))
   1761    call assert_equal(['one'],
   1762          \ getregion(getpos('v'), getpos('v'), {'type': 'V' }))
   1763    call assert_equal(['one'],
   1764          \ getregion(getpos('.'), getpos('.'), {'type': 'V' }))
   1765    call assert_equal(['on'],
   1766          \ getpos('.')->getregion(getpos('v'), {'type': 'v' }))
   1767    call assert_equal(['on'],
   1768          \ getpos('.')->getregion(getpos('v'), {'type': "\<C-v>" }))
   1769 
   1770    #" Block visual mode
   1771    call cursor(1, 1)
   1772    call feedkeys("\<ESC>\<C-v>ll", 'tx')
   1773    call assert_equal(['one'],
   1774          \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   1775    call assert_equal(['one'],
   1776          \ getregion(getpos('.'), getpos('v'), {'type': "\<C-v>" }))
   1777    call assert_equal(['o'],
   1778          \ getregion(getpos('v'), getpos('v'), {'type': "\<C-v>" }))
   1779    call assert_equal(['e'],
   1780          \ getregion(getpos('.'), getpos('.'), {'type': "\<C-v>" }))
   1781    call assert_equal(['one'],
   1782          \ '.'->getpos()->getregion(getpos('v'), {'type': 'V' }))
   1783    call assert_equal(['one'],
   1784          \ '.'->getpos()->getregion(getpos('v'), {'type': 'v' }))
   1785 
   1786    #" Using Marks
   1787    call setpos("'a", [0, 2, 3, 0])
   1788    call cursor(1, 1)
   1789    call assert_equal(['one', 'two'],
   1790          \ "'a"->getpos()->getregion(getpos('.'), {'type': 'v' }))
   1791    call assert_equal(['one', 'two'],
   1792          \ "."->getpos()->getregion(getpos("'a"), {'type': 'v' }))
   1793    call assert_equal(['one', 'two'],
   1794          \ "."->getpos()->getregion(getpos("'a"), {'type': 'V' }))
   1795    call assert_equal(['two'],
   1796          \ "'a"->getpos()->getregion(getpos("'a"), {'type': 'V' }))
   1797    call assert_equal(['one', 'two'],
   1798          \ "."->getpos()->getregion(getpos("'a"), {'type': "\<c-v>" }))
   1799    call feedkeys("\<ESC>jVj\<ESC>", 'tx')
   1800    call assert_equal(['two', 'three'], getregion(getpos("'<"), getpos("'>")))
   1801    call assert_equal(['two', 'three'], getregion(getpos("'>"), getpos("'<")))
   1802 
   1803    #" Using List
   1804    call cursor(1, 1)
   1805    call assert_equal(['one', 'two'],
   1806          \ [0, 2, 3, 0]->getregion(getpos('.'), {'type': 'v' }))
   1807    call assert_equal(['one', 'two'],
   1808          \ '.'->getpos()->getregion([0, 2, 3, 0], {'type': 'v' }))
   1809    call assert_equal(['one', 'two'],
   1810          \ '.'->getpos()->getregion([0, 2, 3, 0], {'type': 'V' }))
   1811    call assert_equal(['two'],
   1812          \ [0, 2, 3, 0]->getregion([0, 2, 3, 0], {'type': 'V' }))
   1813    call assert_equal(['one', 'two'],
   1814          \ '.'->getpos()->getregion([0, 2, 3, 0], {'type': "\<c-v>" }))
   1815 
   1816    #" Multiline with line visual mode
   1817    call cursor(1, 1)
   1818    call feedkeys("\<ESC>Vjj", 'tx')
   1819    call assert_equal(['one', 'two', 'three'],
   1820          \ getregion(getpos('v'), getpos('.'), {'type': 'V' }))
   1821    call assert_equal([
   1822          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
   1823          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
   1824          \   [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
   1825          \ ],
   1826          \ getregionpos(getpos('v'), getpos('.'), {'type': 'V' }))
   1827    call assert_equal([
   1828          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
   1829          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
   1830          \   [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 0]],
   1831          \ ],
   1832          \ getregionpos(getpos('v'), getpos('.'),
   1833          \              {'type': 'V', 'eol': v:true }))
   1834 
   1835    #" Multiline with block visual mode
   1836    call cursor(1, 1)
   1837    call feedkeys("\<ESC>\<C-v>jj", 'tx')
   1838    call assert_equal(['o', 't', 't'],
   1839          \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   1840    call assert_equal([
   1841          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 1, 0]],
   1842          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 1, 0]],
   1843          \   [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 1, 0]],
   1844          \ ],
   1845          \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   1846 
   1847    call cursor(1, 1)
   1848    call feedkeys("\<ESC>\<C-v>jj$", 'tx')
   1849    call assert_equal(['one', 'two', 'three'],
   1850          \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   1851    call assert_equal([
   1852          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
   1853          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
   1854          \   [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
   1855          \ ],
   1856          \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   1857    call assert_equal([
   1858          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
   1859          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
   1860          \   [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
   1861          \ ],
   1862          \ getregionpos(getpos('v'), getpos('.'),
   1863          \              {'type': "\<C-v>", 'eol': v:true }))
   1864 
   1865    #" 'virtualedit'
   1866    set virtualedit=all
   1867 
   1868    call cursor(1, 1)
   1869    call feedkeys("\<ESC>\<C-v>10ljj$", 'tx')
   1870    call assert_equal(['one   ', 'two   ', 'three '],
   1871          \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   1872    call assert_equal([
   1873          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
   1874          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
   1875          \   [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
   1876          \ ],
   1877          \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   1878    call assert_equal([
   1879          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 3]],
   1880          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 3]],
   1881          \   [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 1]],
   1882          \ ],
   1883          \ getregionpos(getpos('v'), getpos('.'),
   1884          \              {'type': "\<C-v>", 'eol': v:true }))
   1885 
   1886    call cursor(3, 5)
   1887    call feedkeys("\<ESC>\<C-v>hkk", 'tx')
   1888    call assert_equal(['  ', '  ', 'ee'],
   1889          \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   1890    call assert_equal([
   1891          \   [[bufnr('%'), 1, 0, 0], [bufnr('%'), 1, 0, 0]],
   1892          \   [[bufnr('%'), 2, 0, 0], [bufnr('%'), 2, 0, 0]],
   1893          \   [[bufnr('%'), 3, 4, 0], [bufnr('%'), 3, 5, 0]],
   1894          \ ],
   1895          \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   1896    call assert_equal([
   1897          \   [[bufnr('%'), 1, 4, 0], [bufnr('%'), 1, 4, 2]],
   1898          \   [[bufnr('%'), 2, 4, 0], [bufnr('%'), 2, 4, 2]],
   1899          \   [[bufnr('%'), 3, 4, 0], [bufnr('%'), 3, 5, 0]],
   1900          \ ],
   1901          \ getregionpos(getpos('v'), getpos('.'),
   1902          \              {'type': "\<C-v>", 'eol': v:true }))
   1903 
   1904    call cursor(3, 5)
   1905    call feedkeys("\<ESC>\<C-v>kk", 'tx')
   1906    call assert_equal([' ', ' ', 'e'],
   1907          \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   1908    call assert_equal([
   1909          \   [[bufnr('%'), 1, 0, 0], [bufnr('%'), 1, 0, 0]],
   1910          \   [[bufnr('%'), 2, 0, 0], [bufnr('%'), 2, 0, 0]],
   1911          \   [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
   1912          \ ],
   1913          \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   1914    call assert_equal([
   1915          \   [[bufnr('%'), 1, 4, 1], [bufnr('%'), 1, 4, 2]],
   1916          \   [[bufnr('%'), 2, 4, 1], [bufnr('%'), 2, 4, 2]],
   1917          \   [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
   1918          \ ],
   1919          \ getregionpos(getpos('v'), getpos('.'),
   1920          \              {'type': "\<C-v>", 'eol': v:true }))
   1921 
   1922    call cursor(1, 3)
   1923    call feedkeys("\<ESC>vjj4l", 'tx')
   1924    call assert_equal(['e', 'two', 'three  '],
   1925          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   1926    call assert_equal([
   1927          \   [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 3, 0]],
   1928          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
   1929          \   [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
   1930          \ ],
   1931          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   1932    call assert_equal([
   1933          \   [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 4, 0]],
   1934          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
   1935          \   [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 2]],
   1936          \ ],
   1937          \ getregionpos(getpos('v'), getpos('.'),
   1938          \              {'type': 'v', 'eol': v:true }))
   1939 
   1940    call cursor(1, 3)
   1941    call feedkeys("\<ESC>lvjj3l", 'tx')
   1942    call assert_equal(['', 'two', 'three  '],
   1943          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   1944    call assert_equal([
   1945          \   [[bufnr('%'), 1, 0, 0], [bufnr('%'), 1, 0, 0]],
   1946          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
   1947          \   [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
   1948          \ ],
   1949          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   1950    call assert_equal([
   1951          \   [[bufnr('%'), 1, 4, 0], [bufnr('%'), 1, 4, 0]],
   1952          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
   1953          \   [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 2]],
   1954          \ ],
   1955          \ getregionpos(getpos('v'), getpos('.'),
   1956          \              {'type': 'v', 'eol': v:true }))
   1957 
   1958    call cursor(3, 5)
   1959    call feedkeys("\<ESC>v3l", 'tx')
   1960    call assert_equal(['e   '],
   1961          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   1962    call assert_equal([
   1963          \   [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
   1964          \ ],
   1965          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   1966    call assert_equal([
   1967          \   [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 6, 3]],
   1968          \ ],
   1969          \ getregionpos(getpos('v'), getpos('.'),
   1970          \              {'type': 'v', 'eol': v:true }))
   1971 
   1972    call cursor(3, 5)
   1973    call feedkeys("\<ESC>lv3l", 'tx')
   1974    call assert_equal(['    '],
   1975          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   1976    call assert_equal([
   1977          \   [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
   1978          \ ],
   1979          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   1980    call assert_equal([
   1981          \   [[bufnr('%'), 3, 6, 0], [bufnr('%'), 3, 6, 4]],
   1982          \ ],
   1983          \ getregionpos(getpos('v'), getpos('.'),
   1984          \              {'type': 'v', 'eol': v:true }))
   1985 
   1986    call cursor(3, 5)
   1987    call feedkeys("\<ESC>3lv3l", 'tx')
   1988    call assert_equal(['    '],
   1989          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   1990    call assert_equal([
   1991          \   [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
   1992          \ ],
   1993          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   1994    call assert_equal([
   1995          \   [[bufnr('%'), 3, 6, 2], [bufnr('%'), 3, 6, 6]],
   1996          \ ],
   1997          \ getregionpos(getpos('v'), getpos('.'),
   1998          \              {'type': 'v', 'eol': v:true }))
   1999 
   2000    set virtualedit&
   2001 
   2002    #" using wrong types for positions
   2003    call cursor(1, 1)
   2004    call feedkeys("\<ESC>vjj$", 'tx')
   2005    call assert_fails("call getregion(1, 2)", 'E1211:')
   2006    call assert_fails("call getregion(getpos('.'), {})", 'E1211:')
   2007    call assert_fails(':echo "."->getpos()->getregion("$", [])', 'E1211:')
   2008    call assert_fails("call getregionpos(1, 2)", 'E1211:')
   2009    call assert_fails("call getregionpos(getpos('.'), {})", 'E1211:')
   2010    call assert_fails(':echo "."->getpos()->getregionpos("$", [])', 'E1211:')
   2011 
   2012    #" using invalid value for "type"
   2013    call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': '' })", 'E475:')
   2014    call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': '' })", 'E475:')
   2015    call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': 'v0' })", 'E475:')
   2016    call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': 'v0' })", 'E475:')
   2017    call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': 'V0' })", 'E475:')
   2018    call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': 'V0' })", 'E475:')
   2019    call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': '\<C-v>0' })", 'E475:')
   2020    call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': '\<C-v>0' })", 'E475:')
   2021    call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': '\<C-v>1:' })", 'E475:')
   2022    call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': '\<C-v>1:' })", 'E475:')
   2023 
   2024    #" using a mark from another buffer to current buffer
   2025    new
   2026    LET g:buf = bufnr()
   2027    call setline(1, range(10))
   2028    normal! GmA
   2029    wincmd p
   2030    call assert_equal([g:buf, 10, 1, 0], getpos("'A"))
   2031    call assert_equal([], getregion(getpos('.'), getpos("'A"), {'type': 'v' }))
   2032    call assert_equal([], getregion(getpos("'A"), getpos('.'), {'type': 'v' }))
   2033    call assert_equal([], getregionpos(getpos('.'), getpos("'A"), {'type': 'v' }))
   2034    call assert_equal([], getregionpos(getpos("'A"), getpos('.'), {'type': 'v' }))
   2035 
   2036    #" using two marks from another buffer
   2037    wincmd p
   2038    normal! GmB
   2039    wincmd p
   2040    call assert_equal([g:buf, 10, 1, 0], getpos("'B"))
   2041    call assert_equal(['9'],
   2042          \ getregion(getpos("'B"), getpos("'A"), {'type': 'v' }))
   2043    call assert_equal([
   2044          \   [[g:buf, 10, 1, 0], [g:buf, 10, 1, 0]],
   2045          \ ],
   2046          \ getregionpos(getpos("'B"), getpos("'A"), {'type': 'v' }))
   2047 
   2048    #" using two positions from another buffer
   2049    for type in ['v', 'V', "\<C-V>"]
   2050      for exclusive in [v:false, v:true]
   2051        call assert_equal(range(10)->mapnew('string(v:val)'),
   2052              \ getregion([g:buf, 1, 1, 0], [g:buf, 10, 2, 0],
   2053              \ {'type': type, 'exclusive': exclusive }))
   2054        call assert_equal(range(10)->mapnew('string(v:val)'),
   2055              \ getregion([g:buf, 10, 2, 0], [g:buf, 1, 1, 0],
   2056              \ {'type': type, 'exclusive': exclusive }))
   2057        call assert_equal(range(1, 10)->mapnew('repeat([[g:buf, v:val, 1, 0]], 2)'),
   2058              \ getregionpos([g:buf, 1, 1, 0], [g:buf, 10, 2, 0],
   2059              \ {'type': type, 'exclusive': exclusive }))
   2060        call assert_equal(range(1, 10)->mapnew('repeat([[g:buf, v:val, 1, 0]], 2)'),
   2061              \ getregionpos([g:buf, 10, 2, 0], [g:buf, 1, 1, 0],
   2062              \ {'type': type, 'exclusive': exclusive }))
   2063      endfor
   2064    endfor
   2065 
   2066    #" using invalid positions in buffer
   2067    call assert_fails('call getregion([g:buf, 0, 1, 0], [g:buf, 10, 2, 0])', 'E966:')
   2068    call assert_fails('call getregion([g:buf, 10, 2, 0], [g:buf, 0, 1, 0])', 'E966:')
   2069    call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 11, 2, 0])', 'E966:')
   2070    call assert_fails('call getregion([g:buf, 11, 2, 0], [g:buf, 1, 1, 0])', 'E966:')
   2071    call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 10, 0, 0])', 'E964:')
   2072    call assert_fails('call getregion([g:buf, 10, 0, 0], [g:buf, 1, 1, 0])', 'E964:')
   2073    call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 10, 3, 0])', 'E964:')
   2074    call assert_fails('call getregion([g:buf, 10, 3, 0], [g:buf, 1, 1, 0])', 'E964:')
   2075    call assert_fails('call getregion([g:buf, 1, 0, 0], [g:buf, 1, 1, 0])', 'E964:')
   2076    call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 1, 0, 0])', 'E964:')
   2077 
   2078    #" using invalid buffer
   2079    call assert_fails('call getregion([10000, 10, 1, 0], [10000, 10, 1, 0])', 'E681:')
   2080 
   2081    exe $':{g:buf}bwipe!'
   2082    unlet g:buf
   2083    bwipe!
   2084  END
   2085  call CheckLegacyAndVim9Success(lines)
   2086 
   2087  let lines =<< trim END
   2088    #" Selection in starts or ends in the middle of a multibyte character
   2089    new
   2090    call setline(1, [
   2091          \   "abcdefghijk\u00ab",
   2092          \   "\U0001f1e6\u00ab\U0001f1e7\u00ab\U0001f1e8\u00ab\U0001f1e9",
   2093          \   "1234567890"
   2094          \ ])
   2095 
   2096    call cursor(1, 3)
   2097    call feedkeys("\<Esc>\<C-v>ljj", 'xt')
   2098    call assert_equal(['cd', "\u00ab ", '34'],
   2099          \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2100    call assert_equal([
   2101          \   [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 4, 0]],
   2102          \   [[bufnr('%'), 2, 5, 0], [bufnr('%'), 2, 7, 1]],
   2103          \   [[bufnr('%'), 3, 3, 0], [bufnr('%'), 3, 4, 0]],
   2104          \ ],
   2105          \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2106 
   2107    call cursor(1, 4)
   2108    call feedkeys("\<Esc>\<C-v>ljj", 'xt')
   2109    call assert_equal(['de', "\U0001f1e7", '45'],
   2110          \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2111    call assert_equal([
   2112          \   [[bufnr('%'), 1, 4, 0], [bufnr('%'), 1, 5, 0]],
   2113          \   [[bufnr('%'), 2, 7, 0], [bufnr('%'), 2, 10, 0]],
   2114          \   [[bufnr('%'), 3, 4, 0], [bufnr('%'), 3, 5, 0]],
   2115          \ ],
   2116          \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2117 
   2118    call cursor(1, 5)
   2119    call feedkeys("\<Esc>\<C-v>jj", 'xt')
   2120    call assert_equal(['e', ' ', '5'],
   2121          \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2122    call assert_equal([
   2123          \   [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 5, 0]],
   2124          \   [[bufnr('%'), 2, 7, 1], [bufnr('%'), 2, 7, 2]],
   2125          \   [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
   2126          \ ],
   2127          \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2128    call assert_equal(['efghijk«', '🇦«🇧«🇨«🇩', '12345'],
   2129          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   2130    call assert_equal([
   2131          \   [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 13, 0]],
   2132          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 22, 0]],
   2133          \   [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
   2134          \ ],
   2135          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   2136 
   2137    call cursor(1, 5)
   2138    call feedkeys("\<Esc>\<C-v>5l2j", 'xt')
   2139    call assert_equal(['efghij', ' «🇨« ', '567890'],
   2140          \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2141    call assert_equal([
   2142          \   [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 10, 0]],
   2143          \   [[bufnr('%'), 2, 7, 1], [bufnr('%'), 2, 19, 1]],
   2144          \   [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 10, 0]],
   2145          \ ],
   2146          \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2147 
   2148    call cursor(1, 4)
   2149    call feedkeys("\<Esc>\<C-v>02j", 'xt')
   2150    call assert_equal(['abcd', '🇦« ', '1234'],
   2151          \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2152    call assert_equal([
   2153          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
   2154          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 7, 1]],
   2155          \   [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 4, 0]],
   2156          \ ],
   2157          \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2158 
   2159    #" characterwise selection with multibyte chars
   2160    call cursor(1, 1)
   2161    call feedkeys("\<Esc>vj", 'xt')
   2162    call assert_equal(['abcdefghijk«', "\U0001f1e6"],
   2163          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   2164    call assert_equal([
   2165          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 13, 0]],
   2166          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
   2167          \ ],
   2168          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   2169 
   2170    set selection=exclusive
   2171    call feedkeys('l', 'xt')
   2172    call assert_equal(['abcdefghijk«', "\U0001f1e6"],
   2173          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   2174    call assert_equal([
   2175          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 13, 0]],
   2176          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
   2177          \ ],
   2178          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   2179 
   2180    #" marks on multibyte chars
   2181    call setpos("'a", [0, 1, 11, 0])
   2182    call setpos("'b", [0, 2, 16, 0])
   2183    call setpos("'c", [0, 2, 0, 0])
   2184    call cursor(1, 1)
   2185 
   2186    call assert_equal(['ghijk', '🇨«🇩'],
   2187          \ getregion(getpos("'a"), getpos("'b"), {'type': "\<C-v>" }))
   2188    call assert_equal([
   2189          \   [[bufnr('%'), 1, 7, 0], [bufnr('%'), 1, 11, 0]],
   2190          \   [[bufnr('%'), 2, 13, 0], [bufnr('%'), 2, 22, 0]],
   2191          \ ],
   2192          \ getregionpos(getpos("'a"), getpos("'b"), {'type': "\<C-v>" }))
   2193 
   2194    call assert_equal(['k«', '🇦«🇧«🇨'],
   2195          \ getregion(getpos("'a"), getpos("'b"), {'type': 'v' }))
   2196    call assert_equal([
   2197          \   [[bufnr('%'), 1, 11, 0], [bufnr('%'), 1, 13, 0]],
   2198          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 16, 0]],
   2199          \ ],
   2200          \ getregionpos(getpos("'a"), getpos("'b"), {'type': 'v' }))
   2201 
   2202    call assert_equal(['k«'],
   2203          \ getregion(getpos("'a"), getpos("'c"), {'type': 'v' }))
   2204    call assert_equal([
   2205          \   [[bufnr('%'), 1, 11, 0], [bufnr('%'), 1, 13, 0]],
   2206          \ ],
   2207          \ getregionpos(getpos("'a"), getpos("'c"), {'type': 'v' }))
   2208 
   2209    #" use inclusive selection, although 'selection' is exclusive
   2210    call setpos("'a", [0, 1, 11, 0])
   2211    call setpos("'b", [0, 1, 1, 0])
   2212    call assert_equal(['abcdefghijk'],
   2213          \ getregion(getpos("'a"), getpos("'b"),
   2214          \ {'type': "\<c-v>", 'exclusive': v:false }))
   2215    call assert_equal(['abcdefghij'],
   2216          \ getregion(getpos("'a"), getpos("'b"),
   2217          \ {'type': "\<c-v>", 'exclusive': v:true }))
   2218    call assert_equal(['abcdefghijk'],
   2219          \ getregion(getpos("'a"), getpos("'b"),
   2220          \ {'type': 'v', 'exclusive': 0 }))
   2221    call assert_equal(['abcdefghij'],
   2222          \ getregion(getpos("'a"), getpos("'b"),
   2223          \ {'type': 'v', 'exclusive': 1 }))
   2224    call assert_equal(['abcdefghijk«'],
   2225          \ getregion(getpos("'a"), getpos("'b"),
   2226          \ {'type': 'V', 'exclusive': 0 }))
   2227    call assert_equal(['abcdefghijk«'],
   2228          \ getregion(getpos("'a"), getpos("'b"),
   2229          \ {'type': 'V', 'exclusive': 1 }))
   2230 
   2231    set selection&
   2232    bwipe!
   2233  END
   2234  call CheckLegacyAndVim9Success(lines)
   2235 
   2236  let lines =<< trim END
   2237    #" Exclusive selection
   2238    new
   2239    set selection=exclusive
   2240    call setline(1, ["a\tc", "x\tz", '', ''])
   2241    call cursor(1, 1)
   2242    call feedkeys("\<Esc>v2l", 'xt')
   2243    call assert_equal(["a\t"],
   2244          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   2245    call cursor(1, 1)
   2246    call feedkeys("\<Esc>v$G", 'xt')
   2247    call assert_equal(["a\tc", "x\tz", ''],
   2248          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   2249    call cursor(1, 1)
   2250    call feedkeys("\<Esc>v$j", 'xt')
   2251    call assert_equal(["a\tc", "x\tz"],
   2252          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   2253    call cursor(1, 1)
   2254    call feedkeys("\<Esc>\<C-v>$j", 'xt')
   2255    call assert_equal(["a\tc", "x\tz"],
   2256          \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2257    call cursor(1, 1)
   2258    call feedkeys("\<Esc>\<C-v>$G", 'xt')
   2259    call assert_equal(["a", "x", '', ''],
   2260          \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2261    call cursor(1, 1)
   2262    call feedkeys("\<Esc>wv2j", 'xt')
   2263    call assert_equal(["c", "x\tz"],
   2264          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   2265    set selection&
   2266    bwipe!
   2267 
   2268    #" Exclusive selection 2
   2269    new
   2270    call setline(1, ["a\tc", "x\tz", '', ''])
   2271 
   2272    call cursor(1, 1)
   2273    call feedkeys("\<Esc>v2l", 'xt')
   2274    call assert_equal(["a\t"],
   2275          \ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
   2276    call assert_equal([
   2277          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 0]],
   2278          \ ],
   2279          \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
   2280 
   2281    call cursor(1, 1)
   2282    call feedkeys("\<Esc>v$G", 'xt')
   2283    call assert_equal(["a\tc", "x\tz", ''],
   2284          \ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
   2285    call assert_equal([
   2286          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
   2287          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
   2288          \   [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
   2289          \ ],
   2290          \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
   2291 
   2292    call cursor(1, 1)
   2293    call feedkeys("\<Esc>v$j", 'xt')
   2294    call assert_equal(["a\tc", "x\tz"],
   2295          \ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
   2296    call assert_equal([
   2297          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
   2298          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
   2299          \ ],
   2300          \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
   2301 
   2302    call cursor(1, 1)
   2303    call feedkeys("\<Esc>\<C-v>$j", 'xt')
   2304    call assert_equal(["a\tc", "x\tz"],
   2305          \ getregion(getpos('v'), getpos('.'),
   2306          \           {'exclusive': v:true, 'type': "\<C-v>" }))
   2307    call assert_equal([
   2308          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
   2309          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
   2310          \ ],
   2311          \ getregionpos(getpos('v'), getpos('.'),
   2312          \              {'exclusive': v:true, 'type': "\<C-v>" }))
   2313 
   2314    call cursor(1, 1)
   2315    call feedkeys("\<Esc>\<C-v>$G", 'xt')
   2316    call assert_equal(["a", "x", '', ''],
   2317          \ getregion(getpos('v'), getpos('.'),
   2318          \           {'exclusive': v:true, 'type': "\<C-v>" }))
   2319    call assert_equal([
   2320          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 1, 0]],
   2321          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 1, 0]],
   2322          \   [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
   2323          \   [[bufnr('%'), 4, 0, 0], [bufnr('%'), 4, 0, 0]],
   2324          \ ],
   2325          \ getregionpos(getpos('v'), getpos('.'),
   2326          \              {'exclusive': v:true, 'type': "\<C-v>" }))
   2327 
   2328    call cursor(1, 1)
   2329    call feedkeys("\<Esc>wv2j", 'xt')
   2330    call assert_equal(["c", "x\tz"],
   2331          \ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
   2332    call assert_equal([
   2333          \   [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 3, 0]],
   2334          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
   2335          \ ],
   2336          \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
   2337 
   2338    #" 'virtualedit' with exclusive selection
   2339    set selection=exclusive
   2340    set virtualedit=all
   2341 
   2342    call cursor(1, 1)
   2343    call feedkeys("\<Esc>vj", 'xt')
   2344    call assert_equal(["a\tc"],
   2345          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   2346    call assert_equal([
   2347          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
   2348          \ ],
   2349          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   2350 
   2351    call cursor(1, 1)
   2352    call feedkeys("\<Esc>v8l", 'xt')
   2353    call assert_equal(["a\t"],
   2354          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   2355    call assert_equal([
   2356          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 0]],
   2357          \ ],
   2358          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   2359 
   2360    call cursor(1, 1)
   2361    call feedkeys("\<Esc>v6l", 'xt')
   2362    call assert_equal(['a     '],
   2363          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   2364    call assert_equal([
   2365          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 5]],
   2366          \ ],
   2367          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   2368 
   2369    call cursor(1, 1)
   2370    call feedkeys("\<Esc>6lv2l", 'xt')
   2371    call assert_equal(['  '],
   2372          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   2373    call assert_equal([
   2374          \   [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 2, 0]],
   2375          \ ],
   2376          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   2377 
   2378    call cursor(1, 1)
   2379    call feedkeys("\<Esc>lv2l", 'xt')
   2380    call assert_equal(['  '],
   2381          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   2382    call assert_equal([
   2383          \   [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 2]],
   2384          \ ],
   2385          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   2386 
   2387    call cursor(1, 1)
   2388    call feedkeys("\<Esc>2lv2l", 'xt')
   2389    call assert_equal(['  '],
   2390          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   2391    call assert_equal([
   2392          \   [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 3]],
   2393          \ ],
   2394          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   2395 
   2396    call feedkeys('j', 'xt')
   2397    call assert_equal(['      c', 'x   '],
   2398          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   2399    call assert_equal([
   2400          \   [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 3, 0]],
   2401          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 3]],
   2402          \ ],
   2403          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   2404 
   2405    call cursor(1, 1)
   2406    call feedkeys("\<Esc>6l\<C-v>2lj", 'xt')
   2407    call assert_equal(['  ', '  '],
   2408          \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2409    call assert_equal([
   2410          \   [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 2, 7]],
   2411          \   [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 2, 7]],
   2412          \ ],
   2413          \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2414 
   2415    call cursor(1, 1)
   2416    call feedkeys("\<Esc>l\<C-v>2l2j", 'xt')
   2417    call assert_equal(['  ', '  ', '  '],
   2418          \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2419    call assert_equal([
   2420          \   [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 2]],
   2421          \   [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 2]],
   2422          \   [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
   2423          \ ],
   2424          \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2425    call assert_equal([
   2426          \   [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 2]],
   2427          \   [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 2]],
   2428          \   [[bufnr('%'), 3, 1, 1], [bufnr('%'), 3, 1, 3]],
   2429          \ ],
   2430          \ getregionpos(getpos('v'), getpos('.'),
   2431          \              {'type': "\<C-v>", "eol": v:true }))
   2432 
   2433    call cursor(1, 1)
   2434    call feedkeys("\<Esc>2l\<C-v>2l2j", 'xt')
   2435    call assert_equal(['  ', '  ', '  '],
   2436          \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2437    call assert_equal([
   2438          \   [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 3]],
   2439          \   [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 3]],
   2440          \   [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
   2441          \ ],
   2442          \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2443    call assert_equal([
   2444          \   [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 3]],
   2445          \   [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 3]],
   2446          \   [[bufnr('%'), 3, 1, 2], [bufnr('%'), 3, 1, 4]],
   2447          \ ],
   2448          \ getregionpos(getpos('v'), getpos('.'),
   2449          \              {'type': "\<C-v>", "eol": v:true }))
   2450 
   2451    #" 'virtualedit' with inclusive selection
   2452    set selection&
   2453 
   2454    call cursor(1, 1)
   2455    call feedkeys("\<Esc>vj", 'xt')
   2456    call assert_equal(["a\tc", 'x'],
   2457          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   2458    call assert_equal([
   2459          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
   2460          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 1, 0]],
   2461          \ ],
   2462          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   2463 
   2464    call cursor(1, 1)
   2465    call feedkeys("\<Esc>v8l", 'xt')
   2466    call assert_equal(["a\tc"],
   2467          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   2468    call assert_equal([
   2469          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
   2470          \ ],
   2471          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   2472 
   2473    call cursor(1, 1)
   2474    call feedkeys("\<Esc>v6l", 'xt')
   2475    call assert_equal(['a      '],
   2476          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   2477    call assert_equal([
   2478          \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 6]],
   2479          \ ],
   2480          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   2481 
   2482    call cursor(1, 1)
   2483    call feedkeys("\<Esc>6lv2l", 'xt')
   2484    call assert_equal(['  c'],
   2485          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   2486    call assert_equal([
   2487          \   [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 3, 0]],
   2488          \ ],
   2489          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   2490 
   2491    call cursor(1, 1)
   2492    call feedkeys("\<Esc>lv2l", 'xt')
   2493    call assert_equal(['   '],
   2494          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   2495    call assert_equal([
   2496          \   [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 3]],
   2497          \ ],
   2498          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   2499 
   2500    call cursor(1, 1)
   2501    call feedkeys("\<Esc>2lv2l", 'xt')
   2502    call assert_equal(['   '],
   2503          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   2504    call assert_equal([
   2505          \   [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 4]],
   2506          \ ],
   2507          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   2508 
   2509    call feedkeys('j', 'xt')
   2510    call assert_equal(['      c', 'x    '],
   2511          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   2512    call assert_equal([
   2513          \   [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 3, 0]],
   2514          \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 4]],
   2515          \ ],
   2516          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   2517 
   2518    call cursor(1, 1)
   2519    call feedkeys("\<Esc>6l\<C-v>2lj", 'xt')
   2520    call assert_equal(['  c', '  z'],
   2521          \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2522    call assert_equal([
   2523          \   [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 3, 0]],
   2524          \   [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 3, 0]],
   2525          \ ],
   2526          \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2527 
   2528    call cursor(1, 1)
   2529    call feedkeys("\<Esc>l\<C-v>2l2j", 'xt')
   2530    call assert_equal(['   ', '   ', '   '],
   2531          \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2532    call assert_equal([
   2533          \   [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 3]],
   2534          \   [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 3]],
   2535          \   [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
   2536          \ ],
   2537          \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2538    call assert_equal([
   2539          \   [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 3]],
   2540          \   [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 3]],
   2541          \   [[bufnr('%'), 3, 1, 1], [bufnr('%'), 3, 1, 4]],
   2542          \ ],
   2543          \ getregionpos(getpos('v'), getpos('.'),
   2544          \              {'type': "\<C-v>", "eol": v:true }))
   2545 
   2546    call cursor(1, 1)
   2547    call feedkeys("\<Esc>2l\<C-v>2l2j", 'xt')
   2548    call assert_equal(['   ', '   ', '   '],
   2549          \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2550    call assert_equal([
   2551          \   [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 4]],
   2552          \   [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 4]],
   2553          \   [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
   2554          \ ],
   2555          \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2556    call assert_equal([
   2557          \   [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 4]],
   2558          \   [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 4]],
   2559          \   [[bufnr('%'), 3, 1, 2], [bufnr('%'), 3, 1, 5]],
   2560          \ ],
   2561          \ getregionpos(getpos('v'), getpos('.'),
   2562          \              {'type': "\<C-v>", "eol": v:true }))
   2563 
   2564    set virtualedit&
   2565    bwipe!
   2566  END
   2567  call CheckLegacyAndVim9Success(lines)
   2568 
   2569  let lines =<< trim END
   2570    #" 'virtualedit' with TABs at end of line
   2571    new
   2572    set virtualedit=all
   2573    call setline(1, ["\t", "a\t", "aa\t"])
   2574 
   2575    call feedkeys("gg06l\<C-v>3l2j", 'xt')
   2576    call assert_equal(['    ', '    ', '    '],
   2577          \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2578    call assert_equal([
   2579          \   [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 1, 0]],
   2580          \   [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 2, 0]],
   2581          \   [[bufnr('%'), 3, 3, 4], [bufnr('%'), 3, 3, 0]],
   2582          \ ],
   2583          \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
   2584    call assert_equal([
   2585          \   [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 2, 2]],
   2586          \   [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 3, 2]],
   2587          \   [[bufnr('%'), 3, 3, 4], [bufnr('%'), 3, 4, 2]],
   2588          \ ],
   2589          \ getregionpos(getpos('v'), getpos('.'),
   2590          \              {'type': "\<C-v>", "eol": v:true }))
   2591 
   2592    call feedkeys("gg06lv3l", 'xt')
   2593    call assert_equal(['    '],
   2594          \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
   2595    call assert_equal([
   2596          \   [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 1, 0]],
   2597          \ ],
   2598          \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
   2599    call assert_equal([
   2600          \   [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 2, 2]],
   2601          \ ],
   2602          \ getregionpos(getpos('v'), getpos('.'),
   2603          \              {'type': 'v', "eol": v:true }))
   2604 
   2605    set virtualedit&
   2606    bwipe!
   2607  END
   2608  call CheckLegacyAndVim9Success(lines)
   2609 endfunc
   2610 
   2611 func Test_getregion_invalid_buf()
   2612  new
   2613  help index
   2614  call cursor(7, 6)
   2615  norm! mA
   2616  call cursor(7, 18)
   2617  norm! mB
   2618  call assert_equal(['file contains'], getregion(getpos("'A"), getpos("'B")))
   2619  " close the help window
   2620  q
   2621  call assert_fails("call getregion(getpos(\"'A\"), getpos(\"'B\"))", 'E681:')
   2622  bwipe!
   2623 endfunc
   2624 
   2625 func Test_getregion_after_yank()
   2626  func! Check_Results(type)
   2627    call assert_equal(g:expected_region,
   2628          \ getregion(getpos("'["), getpos("']"), #{ type: a:type }))
   2629    call assert_equal(g:expected_regionpos,
   2630          \ getregionpos(getpos("'["), getpos("']"), #{ type: a:type }))
   2631    call assert_equal(g:expected_region,
   2632          \ getregion(getpos("']"), getpos("'["), #{ type: a:type }))
   2633    call assert_equal(g:expected_regionpos,
   2634          \ getregionpos(getpos("']"), getpos("'["), #{ type: a:type }))
   2635    let g:checked = 1
   2636  endfunc
   2637 
   2638  autocmd TextYankPost *
   2639        \ : if v:event.operator ==? 'y'
   2640        \ | call Check_Results(v:event.regtype)
   2641        \ | endif
   2642 
   2643  new
   2644  call setline(1, ['abcd', 'efghijk', 'lmn'])
   2645 
   2646  let g:expected_region = ['abcd']
   2647  let g:expected_regionpos = [
   2648        \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
   2649        \ ]
   2650  let g:checked = 0
   2651  normal yy
   2652  call assert_equal(1, g:checked)
   2653  call Check_Results(getregtype('"'))
   2654 
   2655  let g:expected_region = ['cd', 'ghijk', 'n']
   2656  let g:expected_regionpos = [
   2657        \   [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 4, 0]],
   2658        \   [[bufnr('%'), 2, 3, 0], [bufnr('%'), 2, 7, 0]],
   2659        \   [[bufnr('%'), 3, 3, 0], [bufnr('%'), 3, 3, 0]],
   2660        \ ]
   2661  let g:checked = 0
   2662  call feedkeys("gg0ll\<C-V>jj$y", 'tx')
   2663  call assert_equal(1, g:checked)
   2664  call Check_Results(getregtype('"'))
   2665  call assert_equal(g:expected_region, getreg('"', v:true, v:true))
   2666 
   2667  let g:expected_region = ['bc', 'fg', 'mn']
   2668  let g:expected_regionpos = [
   2669        \   [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 3, 0]],
   2670        \   [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 3, 0]],
   2671        \   [[bufnr('%'), 3, 2, 0], [bufnr('%'), 3, 3, 0]],
   2672        \ ]
   2673  let g:checked = 0
   2674  call feedkeys("gg0l\<C-V>jjly", 'tx')
   2675  call assert_equal(1, g:checked)
   2676  call Check_Results(getregtype('"'))
   2677  call assert_equal(g:expected_region, getreg('"', v:true, v:true))
   2678 
   2679  bwipe!
   2680 
   2681  new
   2682  let lines = ['asdfghjkl', '«口=口»', 'qwertyuiop', '口口=口口', 'zxcvbnm']
   2683  call setline(1, lines)
   2684 
   2685  let g:expected_region = lines
   2686  let g:expected_regionpos = [
   2687        \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 9, 0]],
   2688        \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 11, 0]],
   2689        \   [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 10, 0]],
   2690        \   [[bufnr('%'), 4, 1, 0], [bufnr('%'), 4, 13, 0]],
   2691        \   [[bufnr('%'), 5, 1, 0], [bufnr('%'), 5, 7, 0]],
   2692        \ ]
   2693  let g:checked = 0
   2694  call feedkeys('ggyG', 'tx')
   2695  call assert_equal(1, g:checked)
   2696  call Check_Results(getregtype('"'))
   2697  call assert_equal(g:expected_region, getreg('"', v:true, v:true))
   2698 
   2699  let g:expected_region = ['=口»', 'qwertyuiop', '口口=口']
   2700  let g:expected_regionpos = [
   2701        \   [[bufnr('%'), 2, 6, 0], [bufnr('%'), 2, 11, 0]],
   2702        \   [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 10, 0]],
   2703        \   [[bufnr('%'), 4, 1, 0], [bufnr('%'), 4, 10, 0]],
   2704        \ ]
   2705  let g:checked = 0
   2706  call feedkeys('2gg02lv2j2ly', 'tx')
   2707  call assert_equal(1, g:checked)
   2708  call Check_Results(getregtype('"'))
   2709  call assert_equal(g:expected_region, getreg('"', v:true, v:true))
   2710 
   2711  let g:expected_region = ['asdf', '«口=', 'qwer', '口口', 'zxcv']
   2712  let g:expected_regionpos = [
   2713        \   [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
   2714        \   [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 6, 0]],
   2715        \   [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 4, 0]],
   2716        \   [[bufnr('%'), 4, 1, 0], [bufnr('%'), 4, 6, 0]],
   2717        \   [[bufnr('%'), 5, 1, 0], [bufnr('%'), 5, 4, 0]],
   2718        \ ]
   2719  let g:checked = 0
   2720  call feedkeys("G0\<C-V>3l4ky", 'tx')
   2721  call assert_equal(1, g:checked)
   2722  call Check_Results(getregtype('"'))
   2723  call assert_equal(g:expected_region, getreg('"', v:true, v:true))
   2724 
   2725  let g:expected_region = ['ghjkl', '口»', 'tyuiop', '=口口', 'bnm']
   2726  let g:expected_regionpos = [
   2727        \   [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 9, 0]],
   2728        \   [[bufnr('%'), 2, 7, 0], [bufnr('%'), 2, 11, 0]],
   2729        \   [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 10, 0]],
   2730        \   [[bufnr('%'), 4, 7, 0], [bufnr('%'), 4, 13, 0]],
   2731        \   [[bufnr('%'), 5, 5, 0], [bufnr('%'), 5, 7, 0]],
   2732        \ ]
   2733  let g:checked = 0
   2734  call feedkeys("G04l\<C-V>$4ky", 'tx')
   2735  call assert_equal(1, g:checked)
   2736  call Check_Results(getregtype('"'))
   2737  call assert_equal(g:expected_region, getreg('"', v:true, v:true))
   2738 
   2739  bwipe!
   2740 
   2741  unlet g:expected_region
   2742  unlet g:expected_regionpos
   2743  unlet g:checked
   2744  autocmd! TextYankPost
   2745  delfunc Check_Results
   2746 endfunc
   2747 
   2748 func Test_visual_block_cursor_delete()
   2749  new
   2750  call setline(1, 'ab')
   2751  exe ":norm! $\<c-v>hI\<Del>\<ESC>"
   2752  call assert_equal(['b'], getline(1, 1))
   2753  bwipe!
   2754 endfunc
   2755 
   2756 func Test_visual_block_cursor_insert_enter()
   2757  new
   2758  call setline(1, ['asdf asdf', 'asdf asdf', 'asdf asdf', 'asdf asdf'])
   2759  call cursor(1, 5)
   2760  exe ":norm! \<c-v>3jcw\<cr>"
   2761  call assert_equal(['asdfw', 'asdf', 'asdfasdf', 'asdfasdf', 'asdfasdf'], getline(1, '$'))
   2762  bwipe!
   2763 endfunc
   2764 
   2765 func Test_visual_block_exclusive_selection()
   2766  new
   2767  set selection=exclusive
   2768  call setline(1, ['asöd asdf', 'asdf asdf', 'as€d asdf', 'asdf asdf'])
   2769  call cursor(1, 1)
   2770  exe ":norm! \<c-v>eh3j~"
   2771  call assert_equal(['ASÖd asdf', 'ASDf asdf', 'AS€d asdf', 'ASDf asdf'], getline(1, '$'))
   2772  exe ":norm! 1v~"
   2773  call assert_equal(['asöd asdf', 'asdf asdf', 'as€d asdf', 'asdf asdf'], getline(1, '$'))
   2774  bwipe!
   2775  set selection&vim
   2776 endfunc
   2777 
   2778 func Test_visual_block_exclusive_selection_adjusted()
   2779  new
   2780  " Test that the end-position of the visual selection is adjusted for exclusive selection
   2781  set selection=exclusive
   2782  call setline(1, ['asöd asdf  ', 'asdf asdf  ', 'as€d asdf  ', 'asdf asdf  '])
   2783  call cursor(1, 1)
   2784  " inclusive motion
   2785  exe ":norm! \<c-v>e3jy"
   2786  call assert_equal([0, 4, 5, 0], getpos("'>"))
   2787  " exclusive motion
   2788  exe ":norm! \<c-v>ta3jy"
   2789  call assert_equal([0, 4, 6, 0], getpos("'>"))
   2790  " another inclusive motion
   2791  exe ":norm! \<c-v>g_3jy"
   2792  call assert_equal([0, 4, 10, 0], getpos("'>"))
   2793 
   2794  " Reset selection option to Vim default
   2795  set selection&vim
   2796  call cursor(1, 1)
   2797 
   2798  " inclusive motion
   2799  exe ":norm! \<c-v>e3jy"
   2800  call assert_equal([0, 4, 4, 0], getpos("'>"))
   2801  " exclusive motion
   2802  exe ":norm! \<c-v>ta3jy"
   2803  call assert_equal([0, 4, 5, 0], getpos("'>"))
   2804  " another inclusive motion
   2805  exe ":norm! \<c-v>g_3jy"
   2806  call assert_equal([0, 4, 9, 0], getpos("'>"))
   2807  bwipe!
   2808  set selection&vim
   2809 endfunc
   2810 
   2811 " the following caused a Heap-Overflow, because Vim was accessing outside of a
   2812 " line end
   2813 func Test_visual_pos_buffer_heap_overflow()
   2814  set virtualedit=all
   2815  args Xa Xb
   2816  all
   2817  call setline(1, ['', '', ''])
   2818  call cursor(3, 1)
   2819  wincmd w
   2820  call setline(1, 'foobar')
   2821  normal! $lv0
   2822  all
   2823  call setreg('"', 'baz')
   2824  normal! [P
   2825  set virtualedit=
   2826  bw! Xa Xb
   2827 endfunc
   2828 
   2829 " Test visual block pos update after block insert and gv
   2830 func Test_visual_block_pos_update()
   2831  new
   2832  set virtualedit=block
   2833  call setline(1, ['aacccc', 'bb'])
   2834  exe "norm! e\<C-v>jAa\<Esc>gv"
   2835  call assert_equal([[0, 1, 6, 0], [0 , 2, 6, 0]], [getpos("v"), getpos(".")])
   2836  normal! kj
   2837  call assert_equal([[0, 1, 6, 0], [0 , 2, 6, 0]], [getpos("v"), getpos(".")])
   2838  set virtualedit=
   2839  bw!
   2840 endfunc
   2841 
   2842 " Test that blockwise end position matches getpos('.')
   2843 " when 'wrap' and 'linebreak' are set
   2844 func Test_getregionpos_block_linebreak_matches_getpos()
   2845  CheckFeature linebreak
   2846 
   2847  new
   2848  setlocal buftype=
   2849  setlocal bufhidden=wipe
   2850  setlocal noswapfile
   2851 
   2852  setlocal wrap
   2853  setlocal linebreak
   2854  setlocal breakat=\ \t
   2855  setlocal nonumber norelativenumber
   2856  setlocal signcolumn=no
   2857  setlocal foldcolumn=0
   2858 
   2859  call setline(1, '1111111111 2222222222 3333333333 4444444444 5555555555 6666666666 7777777777 8888888888')
   2860 
   2861  " Force wrapping deterministically by shrinking the screen width.
   2862  let save_columns = &columns
   2863  let moved = 0
   2864  for c in [30, 20, 15, 10]
   2865    execute 'set columns=' .. c
   2866    redraw!
   2867    normal! gg0
   2868    let row0 = winline()
   2869    normal! gj
   2870    let row1 = winline()
   2871    if row1 > row0
   2872      let moved = 1
   2873      break
   2874    endif
   2875  endfor
   2876  call assert_true(moved)
   2877 
   2878  " Move a bit right so we are not at column 1, then go back up one screen line.
   2879  normal! 5l
   2880  normal! gk
   2881  let row2 = winline()
   2882  call assert_equal(row0, row2)
   2883 
   2884  " Start Visual block and move down one screen line to the previous position.
   2885  execute "normal! \<C-V>"
   2886  normal! gj
   2887  let row3 = winline()
   2888  call assert_equal(row1, row3)
   2889 
   2890  let p1 = getpos('v')
   2891  let p2 = getpos('.')
   2892 
   2893  " Sanity: block selection is within the same wrapped buffer line.
   2894  call assert_equal(1, p1[1])
   2895  call assert_equal(1, p2[1])
   2896 
   2897  " For blockwise region, getregionpos() should not report an end position
   2898  " different from the {pos2} we passed in.
   2899  let segs = getregionpos(p1, p2, #{ type: "\<C-V>", exclusive: v:false })
   2900 
   2901  call assert_equal(1, len(segs))
   2902  let endp = segs[0][1]
   2903 
   2904  call assert_equal(p2[1], endp[1])  " lnum
   2905  call assert_equal(p2[2], endp[2])  " col
   2906  call assert_equal(p2[3], endp[3])  " off
   2907 
   2908  let &columns = save_columns
   2909  bw!
   2910 endfunc
   2911 " vim: shiftwidth=2 sts=2 expandtab