neovim

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

test_registers.vim (31154B)


      1 " Tests for register operations
      2 
      3 source check.vim
      4 source view_util.vim
      5 
      6 " This test must be executed first to check for empty and unset registers.
      7 func Test_aaa_empty_reg_test()
      8  call assert_fails('normal @@', 'E748:')
      9  call assert_fails('normal @%', 'E354:')
     10  call assert_fails('normal @#', 'E354:')
     11  call assert_fails('normal @!', 'E354:')
     12  call assert_fails('normal @:', 'E30:')
     13  call assert_fails('normal @.', 'E29:')
     14  call assert_fails('put /', 'E35:')
     15  call assert_fails('put .', 'E29:')
     16 endfunc
     17 
     18 func Test_yank_shows_register()
     19    enew
     20    set report=0
     21    call setline(1, ['foo', 'bar'])
     22    " Line-wise
     23    exe 'norm! yy'
     24    call assert_equal('1 line yanked', v:statusmsg)
     25    exe 'norm! "zyy'
     26    call assert_equal('1 line yanked into "z', v:statusmsg)
     27    exe 'norm! yj'
     28    call assert_equal('2 lines yanked', v:statusmsg)
     29    exe 'norm! "zyj'
     30    call assert_equal('2 lines yanked into "z', v:statusmsg)
     31 
     32    " Block-wise
     33    exe "norm! \<C-V>y"
     34    call assert_equal('block of 1 line yanked', v:statusmsg)
     35    exe "norm! \<C-V>\"zy"
     36    call assert_equal('block of 1 line yanked into "z', v:statusmsg)
     37    exe "norm! \<C-V>jy"
     38    call assert_equal('block of 2 lines yanked', v:statusmsg)
     39    exe "norm! \<C-V>j\"zy"
     40    call assert_equal('block of 2 lines yanked into "z', v:statusmsg)
     41 
     42    bwipe!
     43 endfunc
     44 
     45 func Test_display_registers()
     46    " Disable clipboard
     47    let save_clipboard = get(g:, 'clipboard', {})
     48    let g:clipboard = {}
     49 
     50    e file1
     51    e file2
     52    call setline(1, ['foo', 'bar'])
     53    /bar
     54    exe 'norm! y2l"axx'
     55    call feedkeys("i\<C-R>=2*4\n\<esc>")
     56    call feedkeys(":ls\n", 'xt')
     57 
     58    " these commands work in the sandbox
     59    let a = execute('sandbox display')
     60    let b = execute('sandbox registers')
     61 
     62    call assert_equal(a, b)
     63    call assert_match('^\nType Name Content\n'
     64          \ .         '  c  ""   a\n'
     65          \ .         '  c  "0   ba\n'
     66          \ .         '  c  "a   b\n'
     67          \ .         '.*'
     68          \ .         '  c  "-   a\n'
     69          \ .         '.*'
     70          \ .         '  c  ":   ls\n'
     71          \ .         '  c  "%   file2\n'
     72          \ .         '  c  "#   file1\n'
     73          \ .         '  c  "/   bar\n'
     74          \ .         '  c  "=   2\*4', a)
     75 
     76    let a = execute('registers a')
     77    call assert_match('^\nType Name Content\n'
     78          \ .         '  c  "a   b', a)
     79 
     80    let a = execute('registers :')
     81    call assert_match('^\nType Name Content\n'
     82          \ .         '  c  ":   ls', a)
     83 
     84    bwipe!
     85    let g:clipboard = save_clipboard
     86 endfunc
     87 
     88 func Test_register_one()
     89  " delete a line goes into register one
     90  new
     91  call setline(1, "one")
     92  normal dd
     93  call assert_equal("one\n", @1)
     94 
     95  " delete a word does not change register one, does change "-
     96  call setline(1, "two")
     97  normal de
     98  call assert_equal("one\n", @1)
     99  call assert_equal("two", @-)
    100 
    101  " delete a word with a register does not change register one
    102  call setline(1, "three")
    103  normal "ade
    104  call assert_equal("three", @a)
    105  call assert_equal("one\n", @1)
    106 
    107  " delete a word with register DOES change register one with one of a list of
    108  " operators
    109  " %
    110  call setline(1, ["(12)3"])
    111  normal "ad%
    112  call assert_equal("(12)", @a)
    113  call assert_equal("(12)", @1)
    114 
    115  " (
    116  call setline(1, ["first second"])
    117  normal $"ad(
    118  call assert_equal("first secon", @a)
    119  call assert_equal("first secon", @1)
    120 
    121  " )
    122  call setline(1, ["First Second."])
    123  normal gg0"ad)
    124  call assert_equal("First Second.", @a)
    125  call assert_equal("First Second.", @1)
    126 
    127  " `
    128  call setline(1, ["start here."])
    129  normal gg0fhmx0"ad`x
    130  call assert_equal("start ", @a)
    131  call assert_equal("start ", @1)
    132 
    133  " /
    134  call setline(1, ["searchX"])
    135  exe "normal gg0\"ad/X\<CR>"
    136  call assert_equal("search", @a)
    137  call assert_equal("search", @1)
    138 
    139  " ?
    140  call setline(1, ["Ysearch"])
    141  exe "normal gg$\"ad?Y\<CR>"
    142  call assert_equal("Ysearc", @a)
    143  call assert_equal("Ysearc", @1)
    144 
    145  " n
    146  call setline(1, ["Ynext"])
    147  normal gg$"adn
    148  call assert_equal("Ynex", @a)
    149  call assert_equal("Ynex", @1)
    150 
    151  " N
    152  call setline(1, ["prevY"])
    153  normal gg0"adN
    154  call assert_equal("prev", @a)
    155  call assert_equal("prev", @1)
    156 
    157  " }
    158  call setline(1, ["one", ""])
    159  normal gg0"ad}
    160  call assert_equal("one\n", @a)
    161  call assert_equal("one\n", @1)
    162 
    163  " {
    164  call setline(1, ["", "two"])
    165  normal 2G$"ad{
    166  call assert_equal("\ntw", @a)
    167  call assert_equal("\ntw", @1)
    168 
    169  bwipe!
    170 endfunc
    171 
    172 func Test_recording_status_in_ex_line()
    173  set noruler
    174  norm qx
    175  redraw!
    176  call assert_equal('recording @x', Screenline(&lines))
    177  set shortmess=q
    178  redraw!
    179  call assert_equal('', Screenline(&lines)) " Nvim: shm+=q fully hides message
    180  set shortmess&
    181  norm q
    182  redraw!
    183  call assert_equal('', Screenline(&lines))
    184  set ruler
    185  norm qx
    186  redraw!
    187  call assert_match('recording @x\s*0,0-1\s*All', Screenline(&lines))
    188  set shortmess=q
    189  redraw!
    190  call assert_match('\s*0,0-1\s*All', Screenline(&lines)) " Nvim: shm+=q fully hides
    191  set shortmess&
    192  norm q
    193  redraw!
    194  call assert_match('\s*0,0-1\s*All', Screenline(&lines))
    195 endfunc
    196 
    197 " Check that replaying a typed sequence does not use an Esc and following
    198 " characters as an escape sequence.
    199 func Test_recording_esc_sequence()
    200  new
    201  try
    202    let save_F2 = &t_F2
    203  catch
    204  endtry
    205  let t_F2 = "\<Esc>OQ"
    206  call feedkeys("qqiTest\<Esc>", "xt")
    207  call feedkeys("OQuirk\<Esc>q", "xt")
    208  call feedkeys("Go\<Esc>@q", "xt")
    209  call assert_equal(['Quirk', 'Test', 'Quirk', 'Test'], getline(1, 4))
    210  bwipe!
    211  if exists('save_F2')
    212    let &t_F2 = save_F2
    213  else
    214    set t_F2=
    215  endif
    216 endfunc
    217 
    218 func Test_recording_with_select_mode()
    219  new
    220  call feedkeys("qacc12345\<Esc>gH98765\<Esc>q", "tx")
    221  call assert_equal("98765", getline(1))
    222  call assert_equal("cc12345\<Esc>gH98765\<Esc>", @a)
    223  call setline(1, 'asdf')
    224  normal! @a
    225  call assert_equal("98765", getline(1))
    226  bwipe!
    227 endfunc
    228 
    229 func Run_test_recording_with_select_mode_utf8()
    230  new
    231 
    232  " Test with different text lengths: 5, 7, 9, 11, 13, 15, to check that
    233  " a character isn't split between two buffer blocks.
    234  for s in ['12345', '口=口', '口口口', '口=口=口', '口口=口口', '口口口口口']
    235    " 0x80 is K_SPECIAL
    236    " 0x9B is CSI
    237    " 哦: 0xE5 0x93 0xA6
    238    " 洛: 0xE6 0xB4 0x9B
    239    " 固: 0xE5 0x9B 0xBA
    240    " 四: 0xE5 0x9B 0x9B
    241    " 最: 0xE6 0x9C 0x80
    242    " 倒: 0xE5 0x80 0x92
    243    " 倀: 0xE5 0x80 0x80
    244    for c in ['哦', '洛', '固', '四', '最', '倒', '倀']
    245      call setline(1, 'asdf')
    246      call feedkeys($"qacc{s}\<Esc>gH{c}\<Esc>q", "tx")
    247      call assert_equal(c, getline(1))
    248      call assert_equal($"cc{s}\<Esc>gH{c}\<Esc>", @a)
    249      call setline(1, 'asdf')
    250      normal! @a
    251      call assert_equal(c, getline(1))
    252 
    253      " Test with Shift modifier.
    254      let shift_c = eval($'"\<S-{c}>"')
    255      call setline(1, 'asdf')
    256      call feedkeys($"qacc{s}\<Esc>gH{shift_c}\<Esc>q", "tx")
    257      call assert_equal(c, getline(1))
    258      call assert_equal($"cc{s}\<Esc>gH{shift_c}\<Esc>", @a)
    259      call setline(1, 'asdf')
    260      normal! @a
    261      call assert_equal(c, getline(1))
    262    endfor
    263  endfor
    264 
    265  bwipe!
    266 endfunc
    267 
    268 func Test_recording_with_select_mode_utf8()
    269  call Run_test_recording_with_select_mode_utf8()
    270 endfunc
    271 
    272 " This must be done as one of the last tests, because it starts the GUI, which
    273 " cannot be undone.
    274 func Test_zz_recording_with_select_mode_utf8_gui()
    275  CheckCanRunGui
    276 
    277  gui -f
    278  call Run_test_recording_with_select_mode_utf8()
    279 endfunc
    280 
    281 func Test_recording_append_utf8()
    282  new
    283 
    284  let keys = "cc哦洛固四最倒倀\<Esc>0"
    285  call feedkeys($'qr{keys}q', 'xt')
    286  call assert_equal(keys, @r)
    287 
    288  let morekeys = "A…foobar\<Esc>0"
    289  call feedkeys($'qR{morekeys}q', 'xt')
    290  call assert_equal(keys .. morekeys, @r)
    291 
    292  bwipe!
    293 endfunc
    294 
    295 func Test_recording_with_super_mod()
    296  if "\<D-j>"[-1:] == '>'
    297    throw 'Skipped: <D- modifier not supported'
    298  endif
    299 
    300  nnoremap <D-j> <Ignore>
    301  let s = repeat("\<D-j>", 1000)
    302  " This used to crash Vim
    303  call feedkeys($'qr{s}q', 'tx')
    304  call assert_equal(s, @r)
    305  nunmap <D-j>
    306 endfunc
    307 
    308 " Test for executing the last used register (@)
    309 func Test_last_used_exec_reg()
    310  " Test for the @: command
    311  let a = ''
    312  call feedkeys(":let a ..= 'Vim'\<CR>", 'xt')
    313  normal @:
    314  call assert_equal('VimVim', a)
    315 
    316  " Test for the @= command
    317  let x = ''
    318  let a = ":let x ..= 'Vim'\<CR>"
    319  exe "normal @=a\<CR>"
    320  normal @@
    321  call assert_equal('VimVim', x)
    322 
    323  " Test for the @. command
    324  let a = ''
    325  call feedkeys("i:let a ..= 'Edit'\<CR>", 'xt')
    326  normal @.
    327  normal @@
    328  call assert_equal('EditEdit', a)
    329 
    330  " Test for repeating the last command-line in visual mode
    331  call append(0, 'register')
    332  normal gg
    333  let @r = ''
    334  call feedkeys("v:yank R\<CR>", 'xt')
    335  call feedkeys("v@:", 'xt')
    336  call assert_equal("\nregister\nregister\n", @r)
    337 
    338  enew!
    339 endfunc
    340 
    341 func Test_get_register()
    342  enew
    343  edit Xfile1
    344  edit Xfile2
    345  call assert_equal('Xfile2', getreg('%'))
    346  call assert_equal('Xfile1', getreg('#'))
    347 
    348  call feedkeys("iTwo\<Esc>", 'xt')
    349  call assert_equal('Two', getreg('.'))
    350  call assert_equal('', getreg('_'))
    351  call assert_beeps('normal ":yy')
    352  call assert_beeps('normal "%yy')
    353  call assert_beeps('normal ".yy')
    354 
    355  call assert_equal('', getreg("\<C-F>"))
    356  call assert_equal('', getreg("\<C-W>"))
    357  call assert_equal('', getreg("\<C-L>"))
    358  " Change the last used register to '"' for the next test
    359  normal! ""yy
    360  let @" = 'happy'
    361  call assert_equal('happy', getreg())
    362  call assert_equal('happy', getreg(''))
    363 
    364  call assert_equal('', getregtype('!'))
    365  call assert_fails('echo getregtype([])', 'E730:')
    366  call assert_equal('v', getregtype())
    367  call assert_equal('v', getregtype(''))
    368 
    369  " Test for inserting an invalid register content
    370  call assert_beeps('exe "normal i\<C-R>!"')
    371 
    372  " Test for inserting a register with multiple lines
    373  call deletebufline('', 1, '$')
    374  call setreg('r', ['a', 'b'])
    375  exe "normal i\<C-R>r"
    376  call assert_equal(['a', 'b', ''], getline(1, '$'))
    377 
    378  " Test for inserting a multi-line register in the command line
    379  call feedkeys(":\<C-R>r\<Esc>", 'xt')
    380  " Nvim: no trailing CR because of #6137
    381  " call assert_equal("a\rb\r", histget(':', -1))
    382  call assert_equal("a\rb", histget(':', -1))
    383 
    384  call assert_fails('let r = getreg("=", [])', 'E745:')
    385  call assert_fails('let r = getreg("=", 1, [])', 'E745:')
    386  enew!
    387 
    388  " Using a register in operator-pending mode should fail
    389  call assert_beeps('norm! c"')
    390 endfunc
    391 
    392 func Test_set_register()
    393  call assert_fails("call setreg('#', 200)", 'E86:')
    394  " call assert_fails("call setreg('a', test_unknown())", 'E908:')
    395 
    396  edit Xfile_alt_1
    397  let b1 = bufnr('')
    398  edit Xfile_alt_2
    399  let b2 = bufnr('')
    400  edit Xfile_alt_3
    401  let b3 = bufnr('')
    402  call setreg('#', 'alt_1')
    403  call assert_equal('Xfile_alt_1', getreg('#'))
    404  call setreg('#', b2)
    405  call assert_equal('Xfile_alt_2', getreg('#'))
    406 
    407  let ab = 'regwrite'
    408  call setreg('=', '')
    409  call setreg('=', 'a', 'a')
    410  call setreg('=', 'b', 'a')
    411  call assert_equal('regwrite', getreg('='))
    412 
    413  " Test for setting a list of lines to special registers
    414  call setreg('/', [])
    415  call assert_equal('', @/)
    416  call setreg('=', [])
    417  call assert_equal('', @=)
    418  call assert_fails("call setreg('/', ['a', 'b'])", 'E883:')
    419  call assert_fails("call setreg('=', ['a', 'b'])", 'E883:')
    420  call assert_equal(0, setreg('_', ['a', 'b']))
    421 
    422  " Test for recording to a invalid register
    423  call assert_beeps('normal q$')
    424 
    425  " Appending to a register when recording
    426  call append(0, "text for clipboard test")
    427  normal gg
    428  call feedkeys('qrllq', 'xt')
    429  call feedkeys('qRhhq', 'xt')
    430  call assert_equal('llhh', getreg('r'))
    431 
    432  " Appending a list of characters to a register from different lines
    433  let @r = ''
    434  call append(0, ['abcdef', '123456'])
    435  normal gg"ry3l
    436  call cursor(2, 4)
    437  normal "Ry3l
    438  call assert_equal('abc456', @r)
    439 
    440  " Test for gP with multiple lines selected using characterwise motion
    441  %delete
    442  call append(0, ['vim editor', 'vim editor'])
    443  let @r = ''
    444  exe "normal ggwy/vim /e\<CR>gP"
    445  call assert_equal(['vim editor', 'vim editor', 'vim editor'], getline(1, 3))
    446 
    447  " Test for gP with . register
    448  %delete
    449  normal iabc
    450  normal ".gp
    451  call assert_equal('abcabc', getline(1))
    452  normal 0".gP
    453  call assert_equal('abcabcabc', getline(1))
    454 
    455  let @"=''
    456  call setreg('', '1')
    457  call assert_equal('1', @")
    458  call setreg('@', '2')
    459  call assert_equal('2', @")
    460 
    461  enew!
    462 endfunc
    463 
    464 " Test for blockwise register width calculations
    465 func Test_set_register_blockwise_width()
    466  " Test for regular calculations and overriding the width
    467  call setreg('a', "12\n1234\n123", 'b')
    468  call assert_equal("\<c-v>4", getreginfo('a').regtype)
    469  call setreg('a', "12\n1234\n123", 'b1')
    470  call assert_equal("\<c-v>1", getreginfo('a').regtype)
    471  call setreg('a', "12\n1234\n123", 'b6')
    472  call assert_equal("\<c-v>6", getreginfo('a').regtype)
    473 
    474  " Test for Unicode parsing
    475  call setreg('a', "z😅😅z\n12345", 'b')
    476  call assert_equal("\<c-v>6", getreginfo('a').regtype)
    477  call setreg('a', ["z😅😅z", "12345"], 'b')
    478  call assert_equal("\<c-v>6", getreginfo('a').regtype)
    479 endfunc
    480 
    481 " Test for clipboard registers (* and +)
    482 func Test_clipboard_regs()
    483  throw 'skipped: needs clipboard=autoselect,autoselectplus'
    484 
    485  CheckNotGui
    486  CheckFeature clipboard_working
    487 
    488  new
    489  call append(0, "text for clipboard test")
    490  normal gg"*yiw
    491  call assert_equal('text', getreg('*'))
    492  normal gg2w"+yiw
    493  call assert_equal('clipboard', getreg('+'))
    494 
    495  " Test for replacing the clipboard register contents
    496  set clipboard=unnamed
    497  let @* = 'food'
    498  normal ggviw"*p
    499  call assert_equal('text', getreg('*'))
    500  call assert_equal('food for clipboard test', getline(1))
    501  normal ggviw"*p
    502  call assert_equal('food', getreg('*'))
    503  call assert_equal('text for clipboard test', getline(1))
    504 
    505  " Test for replacing the selection register contents
    506  set clipboard=unnamedplus
    507  let @+ = 'food'
    508  normal ggviw"+p
    509  call assert_equal('text', getreg('+'))
    510  call assert_equal('food for clipboard test', getline(1))
    511  normal ggviw"+p
    512  call assert_equal('food', getreg('+'))
    513  call assert_equal('text for clipboard test', getline(1))
    514 
    515  " Test for auto copying visually selected text to clipboard register
    516  call setline(1, "text for clipboard test")
    517  let @* = ''
    518  set clipboard=autoselect
    519  normal ggwwviwy
    520  call assert_equal('clipboard', @*)
    521 
    522  " Test for auto copying visually selected text to selection register
    523  let @+ = ''
    524  set clipboard=autoselectplus
    525  normal ggwviwy
    526  call assert_equal('for', @+)
    527 
    528  set clipboard&vim
    529  bwipe!
    530 endfunc
    531 
    532 " Test for restarting the current mode (insert or virtual replace) after
    533 " executing the contents of a register
    534 func Test_put_reg_restart_mode()
    535  new
    536  call append(0, 'editor')
    537  normal gg
    538  let @r = "ivim \<Esc>"
    539  call feedkeys("i\<C-O>@r\<C-R>=mode()\<CR>", 'xt')
    540  call assert_equal('vimi editor', getline(1))
    541 
    542  call setline(1, 'editor')
    543  normal gg
    544  call feedkeys("gR\<C-O>@r\<C-R>=mode()\<CR>", 'xt')
    545  call assert_equal('vimReditor', getline(1))
    546 
    547  bwipe!
    548 endfunc
    549 
    550 " Test for executing a register using :@ command
    551 func Test_execute_register()
    552  call setreg('r', [])
    553  call assert_beeps('@r')
    554  let i = 1
    555  let @q = 'let i+= 1'
    556  @q
    557  @
    558  call assert_equal(3, i)
    559 
    560  " try to execute expression register and use a backspace to cancel it
    561  new
    562  call feedkeys("@=\<BS>ax\<CR>y", 'xt')
    563  call assert_equal(['x', 'y'], getline(1, '$'))
    564  bw!
    565 
    566  " cannot execute a register in operator pending mode
    567  call assert_beeps('normal! c@r')
    568 endfunc
    569 
    570 " Test for getting register info
    571 func Test_get_reginfo()
    572  enew
    573  call setline(1, ['foo', 'bar'])
    574 
    575  exe 'norm! "zyy'
    576  let info = getreginfo('"')
    577  call assert_equal('z', info.points_to)
    578  call setreg('y', 'baz')
    579  call assert_equal('z', getreginfo('').points_to)
    580  call setreg('y', { 'isunnamed': v:true })
    581  call assert_equal('y', getreginfo('"').points_to)
    582 
    583  exe '$put'
    584  call assert_equal(getreg('y'), getline(3))
    585  call setreg('', 'qux')
    586  call assert_equal('0', getreginfo('').points_to)
    587  call setreg('x', 'quux')
    588  call assert_equal('0', getreginfo('').points_to)
    589 
    590  let info = getreginfo('')
    591  call assert_equal(getreg('', 1, 1), info.regcontents)
    592  call assert_equal(getregtype(''), info.regtype)
    593 
    594  exe "norm! 0\<c-v>e" .. '"zy'
    595  let info = getreginfo('z')
    596  call assert_equal(getreg('z', 1, 1), info.regcontents)
    597  call assert_equal(getregtype('z'), info.regtype)
    598  call assert_equal(1, +info.isunnamed)
    599 
    600  let info = getreginfo('"')
    601  call assert_equal('z', info.points_to)
    602 
    603  let @a="a1b2"
    604  nnoremap <F2> <Cmd>let g:RegInfo = getreginfo()<CR>
    605  exe "normal \"a\<F2>"
    606  call assert_equal({'regcontents': ['a1b2'], 'isunnamed': v:false,
    607        \ 'regtype': 'v'}, g:RegInfo)
    608  nunmap <F2>
    609  unlet g:RegInfo
    610 
    611  " The type of "isunnamed" was VAR_SPECIAL but should be VAR_BOOL.  Can only
    612  " be noticed when using json_encod().
    613  call setreg('a', 'foo')
    614  let reginfo = getreginfo('a')
    615  let expected = #{regcontents: ['foo'], isunnamed: v:false, regtype: 'v'}
    616  call assert_equal(json_encode(expected), json_encode(reginfo))
    617 
    618  bwipe!
    619 endfunc
    620 
    621 " Test for restoring register with dict from getreginfo
    622 func Test_set_register_dict()
    623  enew!
    624 
    625  call setreg('"', #{ regcontents: ['one', 'two'],
    626        \ regtype: 'V', points_to: 'z' })
    627  call assert_equal(['one', 'two'], getreg('"', 1, 1))
    628  let info = getreginfo('"')
    629  call assert_equal('z', info.points_to)
    630  call assert_equal('V', info.regtype)
    631  call assert_equal(1, +getreginfo('z').isunnamed)
    632 
    633  call setreg('x', #{ regcontents: ['three', 'four'],
    634        \ regtype: 'v', isunnamed: v:true })
    635  call assert_equal(['three', 'four'], getreg('"', 1, 1))
    636  let info = getreginfo('"')
    637  call assert_equal('x', info.points_to)
    638  call assert_equal('v', info.regtype)
    639  call assert_equal(1, +getreginfo('x').isunnamed)
    640 
    641  call setreg('y', #{ regcontents: 'five',
    642        \ regtype: "\<c-v>", isunnamed: v:false })
    643  call assert_equal("\<c-v>4", getreginfo('y').regtype)
    644  call assert_equal(0, +getreginfo('y').isunnamed)
    645  call assert_equal(['three', 'four'], getreg('"', 1, 1))
    646  call assert_equal('x', getreginfo('"').points_to)
    647 
    648  call setreg('"', #{ regcontents: 'six' })
    649  call assert_equal('0', getreginfo('"').points_to)
    650  call assert_equal(1, +getreginfo('0').isunnamed)
    651  call assert_equal(['six'], getreginfo('0').regcontents)
    652  call assert_equal(['six'], getreginfo('"').regcontents)
    653 
    654  let @x = 'one'
    655  call setreg('x', {})
    656  call assert_equal(1, len(split(execute('reg x'), '\n')))
    657 
    658  call assert_fails("call setreg('0', #{regtype: 'V'}, 'v')", 'E118:')
    659  call assert_fails("call setreg('0', #{regtype: 'X'})", 'E475:')
    660  call assert_fails("call setreg('0', #{regtype: 'vy'})", 'E475:')
    661 
    662  bwipe!
    663 endfunc
    664 
    665 func Test_v_register()
    666  enew
    667  call setline(1, 'nothing')
    668 
    669  func s:Put()
    670    let s:register = v:register
    671    exec 'normal! "' .. v:register .. 'P'
    672  endfunc
    673  nnoremap <buffer> <plug>(test) :<c-u>call s:Put()<cr>
    674  xnoremap <buffer> <plug>(test) :<c-u>call s:Put()<cr>
    675  nmap <buffer> S <plug>(test)
    676  xmap <buffer> S <plug>(test)
    677 
    678  let @z = "testz\n"
    679  let @" = "test@\n"
    680 
    681  let s:register = ''
    682  call feedkeys('"_ddS', 'mx')
    683  call assert_equal('"', s:register)        " fails before 8.2.0929
    684  call assert_equal('test@', getline('.'))  " fails before 8.2.0929
    685 
    686  let s:register = ''
    687  call feedkeys('V"_dS', 'mx')
    688  call assert_equal('"', s:register)
    689  call assert_equal('test@', getline('.'))
    690 
    691  let s:register = ''
    692  call feedkeys('"zS', 'mx')
    693  call assert_equal('z', s:register)
    694  call assert_equal('testz', getline('.'))
    695 
    696  let s:register = ''
    697  call feedkeys('"zSS', 'mx')
    698  call assert_equal('"', s:register)
    699  call assert_equal('test@', getline('.'))
    700 
    701  let s:register = ''
    702  call feedkeys("\"z\<Ignore>S", 'mx')
    703  call assert_equal('z', s:register)
    704  call assert_equal('testz', getline('.'))
    705 
    706  let s:register = ''
    707  call feedkeys('"_S', 'mx')
    708  call assert_equal('_', s:register)
    709 
    710  let s:register = ''
    711  call feedkeys('V"zS', 'mx')
    712  call assert_equal('z', s:register)
    713  call assert_equal('testz', getline('.'))
    714 
    715  let s:register = ''
    716  call feedkeys('V"zSS', 'mx')
    717  call assert_equal('"', s:register)
    718  call assert_equal('test@', getline('.'))
    719 
    720  let s:register = ''
    721  call feedkeys("V\"z\<Ignore>S", 'mx')
    722  call assert_equal('z', s:register)
    723  call assert_equal('testz', getline('.'))
    724 
    725  let s:register = ''
    726  call feedkeys('V"_S', 'mx')
    727  call assert_equal('_', s:register)
    728 
    729  let s:register = ''
    730  normal "_ddS
    731  call assert_equal('"', s:register)        " fails before 8.2.0929
    732  call assert_equal('test@', getline('.'))  " fails before 8.2.0929
    733 
    734  let s:register = ''
    735  normal V"_dS
    736  call assert_equal('"', s:register)
    737  call assert_equal('test@', getline('.'))
    738 
    739  let s:register = ''
    740  execute 'normal "z:call' "s:Put()\n"
    741  call assert_equal('z', s:register)
    742  call assert_equal('testz', getline('.'))
    743 
    744  " Test operator and omap
    745  let @b = 'testb'
    746  func s:OpFunc(...)
    747    let s:register2 = v:register
    748  endfunc
    749  set opfunc=s:OpFunc
    750 
    751  normal "bg@l
    752  normal S
    753  call assert_equal('"', s:register)        " fails before 8.2.0929
    754  call assert_equal('b', s:register2)
    755 
    756  func s:Motion()
    757    let s:register1 = v:register
    758    normal! l
    759  endfunc
    760  onoremap <buffer> Q :<c-u>call s:Motion()<cr>
    761 
    762  normal "bg@Q
    763  normal S
    764  call assert_equal('"', s:register)
    765  call assert_equal('b', s:register1)
    766  call assert_equal('"', s:register2)
    767 
    768  set opfunc&
    769  bwipe!
    770 endfunc
    771 
    772 " Test for executing the contents of a register as an Ex command with line
    773 " continuation.
    774 func Test_execute_reg_as_ex_cmd()
    775  " Line continuation with just two lines
    776  let code =<< trim END
    777    let l = [
    778      \ 1]
    779  END
    780  let @r = code->join("\n")
    781  let l = []
    782  @r
    783  call assert_equal([1], l)
    784 
    785  " Line continuation with more than two lines
    786  let code =<< trim END
    787    let l = [
    788      \ 1,
    789      \ 2,
    790      \ 3]
    791  END
    792  let @r = code->join("\n")
    793  let l = []
    794  @r
    795  call assert_equal([1, 2, 3], l)
    796 
    797  " use comments interspersed with code
    798  let code =<< trim END
    799    let l = [
    800      "\ one
    801      \ 1,
    802      "\ two
    803      \ 2,
    804      "\ three
    805      \ 3]
    806  END
    807  let @r = code->join("\n")
    808  let l = []
    809  @r
    810  call assert_equal([1, 2, 3], l)
    811 
    812  " use line continuation in the middle
    813  let code =<< trim END
    814    let a = "one"
    815    let l = [
    816      \ 1,
    817      \ 2]
    818    let b = "two"
    819  END
    820  let @r = code->join("\n")
    821  let l = []
    822  @r
    823  call assert_equal([1, 2], l)
    824  call assert_equal("one", a)
    825  call assert_equal("two", b)
    826 
    827  " only one line with a \
    828  let @r = "\\let l = 1"
    829  call assert_fails('@r', 'E10:')
    830 
    831  " only one line with a "\
    832  let @r = '   "\ let i = 1'
    833  @r
    834  call assert_false(exists('i'))
    835 
    836  " first line also begins with a \
    837  let @r = "\\let l = [\n\\ 1]"
    838  call assert_fails('@r', 'E10:')
    839 
    840  " Test with a large number of lines
    841  let @r = "let str = \n"
    842  let @r ..= repeat("  \\ 'abcdefghijklmnopqrstuvwxyz' ..\n", 312)
    843  let @r ..= '  \ ""'
    844  @r
    845  call assert_equal(repeat('abcdefghijklmnopqrstuvwxyz', 312), str)
    846 endfunc
    847 
    848 func Test_ve_blockpaste()
    849  new
    850  set ve=all
    851  0put =['QWERTZ','ASDFGH']
    852  call cursor(1,1)
    853  exe ":norm! \<C-V>3ljdP"
    854  call assert_equal(1, col('.'))
    855  call assert_equal(['QWERTZ', 'ASDFGH'], getline(1, 2))
    856  call cursor(1,1)
    857  exe ":norm! \<C-V>3ljd"
    858  call cursor(1,1)
    859  norm! $3lP
    860  call assert_equal(5, col('.'))
    861  call assert_equal(['TZ  QWER', 'GH  ASDF'], getline(1, 2))
    862  set ve&vim
    863  bwipe!
    864 endfunc
    865 
    866 func Test_insert_small_delete()
    867  new
    868  call setline(1, ['foo foobar bar'])
    869  call cursor(1,1)
    870  exe ":norm! ciw'\<C-R>-'"
    871  call assert_equal("'foo' foobar bar", getline(1))
    872  exe ":norm! w.w."
    873  call assert_equal("'foo' 'foobar' 'bar'", getline(1))
    874  bwipe!
    875 endfunc
    876 
    877 " Record in insert mode using CTRL-O
    878 func Test_record_in_insert_mode()
    879  new
    880  let @r = ''
    881  call setline(1, ['foo'])
    882  call feedkeys("i\<C-O>qrbaz\<C-O>q", 'xt')
    883  call assert_equal('baz', @r)
    884  bwipe!
    885 endfunc
    886 
    887 func Test_record_in_select_mode()
    888  new
    889  call setline(1, 'text')
    890  sil norm q00
    891  sil norm q
    892  call assert_equal('0ext', getline(1))
    893 
    894  %delete
    895  let @r = ''
    896  call setline(1, ['abc', 'abc', 'abc'])
    897  smap <F2> <Right><Right>,
    898  call feedkeys("qrgh\<F2>Dk\<Esc>q", 'xt')
    899  call assert_equal("gh\<F2>Dk\<Esc>", @r)
    900  norm j0@rj0@@
    901  call assert_equal([',Dk', ',Dk', ',Dk'], getline(1, 3))
    902  sunmap <F2>
    903 
    904  bwipe!
    905 endfunc
    906 
    907 " A mapping that ends recording should be removed from the recorded register.
    908 func Test_end_record_using_mapping()
    909  new
    910  call setline(1, 'aaa')
    911  nnoremap s q
    912  call feedkeys('safas', 'tx')
    913  call assert_equal('fa', @a)
    914  nunmap s
    915 
    916  nnoremap xx q
    917  call feedkeys('0xxafaxx', 'tx')
    918  call assert_equal('fa', @a)
    919  nunmap xx
    920 
    921  nnoremap xsx q
    922  call feedkeys('0qafaxsx', 'tx')
    923  call assert_equal('fa', @a)
    924  nunmap xsx
    925 
    926  bwipe!
    927 endfunc
    928 
    929 " Starting a new recording should work immediately after replaying a recording
    930 " that ends with a <Nop> mapping or a character search.
    931 func Test_end_reg_executing()
    932  new
    933  nnoremap s <Nop>
    934  let @a = 's'
    935  call feedkeys("@aqaq\<Esc>", 'tx')
    936  call assert_equal('', @a)
    937  call assert_equal('', getline(1))
    938 
    939  call setline(1, 'aaa')
    940  nnoremap s qa
    941  let @a = 'fa'
    942  call feedkeys("@asq\<Esc>", 'tx')
    943  call assert_equal('', @a)
    944  call assert_equal('aaa', getline(1))
    945 
    946  nunmap s
    947  bwipe!
    948 endfunc
    949 
    950 func Test_reg_executing_in_range_normal()
    951  new
    952  set showcmd
    953  call setline(1, range(10))
    954  let g:log = []
    955  nnoremap s <Cmd>let g:log += [reg_executing()]<CR>
    956  let @r = 's'
    957 
    958  %normal @r
    959  call assert_equal(repeat(['r'], 10), g:log)
    960 
    961  nunmap s
    962  unlet g:log
    963  set showcmd&
    964  bwipe!
    965 endfunc
    966 
    967 " An operator-pending mode mapping shouldn't be applied to keys typed in
    968 " Insert mode immediately after a character search when replaying.
    969 func Test_replay_charsearch_omap()
    970  CheckFeature timers
    971 
    972  new
    973  call setline(1, 'foo[blah]')
    974  onoremap , k
    975  call timer_start(10, {-> feedkeys(",bar\<Esc>q", 't')})
    976  call feedkeys('qrct[', 'xt!')
    977  call assert_equal(',bar[blah]', getline(1))
    978  call assert_equal("ct[\<Ignore>,bar\<Esc>", @r)
    979  call assert_equal('ct[<Ignore>,bar<Esc>', keytrans(@r))
    980  undo
    981  call assert_equal('foo[blah]', getline(1))
    982  call feedkeys('@r', 'xt!')
    983  call assert_equal(',bar[blah]', getline(1))
    984 
    985  ounmap ,
    986  bwipe!
    987 endfunc
    988 
    989 " Make sure that y_append is correctly reset
    990 " and the previous register is working as expected
    991 func Test_register_y_append_reset()
    992  new
    993  call setline(1, ['1',
    994    \ '2 ----------------------------------------------------',
    995    \ '3',
    996    \ '4',
    997    \ '5 ----------------------------------------------------',
    998    \ '6',
    999    \ '7',
   1000    \ '8 ----------------------------------------------------',
   1001    \ '9',
   1002    \ '10 aaaaaaa 4.',
   1003    \ '11 Game Dbl-Figures Leaders:',
   1004    \ '12 Player Pts FG% 3P% FT% RB AS BL ST TO PF EFF',
   1005    \ '13 bbbbbbbbb 12 (50 /0 /67 )/ 7/ 3/ 0/ 2/ 3/ 4/+15',
   1006    \ '14 cccccc 12 (57 /67 /100)/ 2/ 1/ 1/ 0/ 1/ 3/+12',
   1007    \ '15 ddddddd 10 (63 /0 /0 )/ 1/ 3/ 0/ 3/ 5/ 3/ +9',
   1008    \ '16 4 5-15 0-3 2-2 5-12 1-1 3-4 33.3 0.0 100 41.7 100 75 12 14',
   1009    \ '17 F 23-55 2-10 9-11 23-52 3-13 26-29 41.8 20 81.8 44.2 23.1 89.7 57 75',
   1010    \ '18 4 3 6 3 2 3 3 4 3 3 7 3 1 4 6 -1 -1 +2 -1 -2',
   1011    \ '19 F 13 19 5 10 4 17 22 9 14 32 13 4 20 17 -1 -13 -4 -3 -3 +5'])
   1012  11
   1013  exe "norm! \"a5dd"
   1014  norm! j
   1015  exe "norm! \"bY"
   1016  norm! 2j
   1017  exe "norm! \"BY"
   1018  norm! 4k
   1019  norm! 5dd
   1020  norm! 3k
   1021  " The next put should put the content of the unnamed register, not of
   1022  " register b!
   1023  norm! p
   1024  call assert_equal(['1',
   1025    \ '2 ----------------------------------------------------',
   1026    \ '3',
   1027    \ '4',
   1028    \ '5 ----------------------------------------------------',
   1029    \ '6',
   1030    \ '10 aaaaaaa 4.',
   1031    \ '16 4 5-15 0-3 2-2 5-12 1-1 3-4 33.3 0.0 100 41.7 100 75 12 14',
   1032    \ '17 F 23-55 2-10 9-11 23-52 3-13 26-29 41.8 20 81.8 44.2 23.1 89.7 57 75',
   1033    \ '18 4 3 6 3 2 3 3 4 3 3 7 3 1 4 6 -1 -1 +2 -1 -2',
   1034    \ '19 F 13 19 5 10 4 17 22 9 14 32 13 4 20 17 -1 -13 -4 -3 -3 +5',
   1035    \ '7',
   1036    \ '8 ----------------------------------------------------',
   1037    \ '9'], getline(1,'$'))
   1038  bwipe!
   1039 endfunc
   1040 
   1041 func Test_insert_small_delete_replace_mode()
   1042  new
   1043  call setline(1, ['foo', 'bar', 'foobar',  'bar'])
   1044  let @- = 'foo'
   1045  call cursor(2, 1)
   1046  exe ":norm! R\<C-R>-\<C-R>-"
   1047  call assert_equal('foofoo', getline(2))
   1048  call cursor(3, 1)
   1049  norm! D
   1050  call assert_equal(['foo', 'foofoo', '',  'bar'], getline(1, 4))
   1051  call cursor(4, 2)
   1052  exe ":norm! R\<C-R>-ZZZZ"
   1053  call assert_equal(['foo', 'foofoo', '',  'bfoobarZZZZ'], getline(1, 4))
   1054  call cursor(1, 1)
   1055  let @- = ''
   1056  exe ":norm! R\<C-R>-ZZZ"
   1057  call assert_equal(['ZZZ', 'foofoo', '',  'bfoobarZZZZ'], getline(1, 4))
   1058  let @- = 'βbβ'
   1059  call cursor(4, 1)
   1060  exe ":norm! R\<C-R>-"
   1061  call assert_equal(['ZZZ', 'foofoo', '',  'βbβobarZZZZ'], getline(1, 4))
   1062  let @- = 'bβb'
   1063  call cursor(4, 1)
   1064  exe ":norm! R\<C-R>-"
   1065  call assert_equal(['ZZZ', 'foofoo', '',  'bβbobarZZZZ'], getline(1, 4))
   1066  let @- = 'βbβ'
   1067  call cursor(4, 1)
   1068  exe ":norm! R\<C-R>-"
   1069  call assert_equal(['ZZZ', 'foofoo', '',  'βbβobarZZZZ'], getline(1, 4))
   1070  bwipe!
   1071 endfunc
   1072 
   1073 " this caused an illegal memory access and a crash
   1074 func Test_register_cursor_column_negative()
   1075  CheckRunVimInTerminal
   1076  let script =<< trim END
   1077    f XREGISTER
   1078    call setline(1, 'abcdef a')
   1079    call setreg("a", "\n", 'c')
   1080    call cursor(1, 7)
   1081    call feedkeys("i\<C-R>\<C-P>azyx$#\<esc>", 't')
   1082  END
   1083  call writefile(script, 'XRegister123', 'D')
   1084  let buf = RunVimInTerminal('-S XRegister123', {})
   1085  call term_sendkeys(buf, "\<c-g>")
   1086  call WaitForAssert({-> assert_match('XREGISTER', term_getline(buf, 19))})
   1087  call StopVimInTerminal(buf)
   1088 endfunc
   1089 
   1090 " test '] mark generated by op_yank
   1091 func Test_mark_from_yank()
   1092  new
   1093  " double quote object
   1094  call setline(1, 'test "yank"  mark')
   1095  normal! yi"
   1096  call assert_equal([0, 1, 10, 0], getpos("']"))
   1097  normal! ya"
   1098  call assert_equal([0, 1, 13, 0], getpos("']"))
   1099  " single quote object
   1100  call setline(1, 'test ''yank''  mark')
   1101  normal! yi'
   1102  call assert_equal([0, 1, 10, 0], getpos("']"))
   1103  normal! ya'
   1104  call assert_equal([0, 1, 13, 0], getpos("']"))
   1105  " paren object
   1106  call setline(1, 'test (yank)  mark')
   1107  call cursor(1, 9)
   1108  normal! yi(
   1109  call assert_equal([0, 1, 10, 0], getpos("']"))
   1110  call cursor(1, 9)
   1111  normal! ya(
   1112  call assert_equal([0, 1, 11, 0], getpos("']"))
   1113  " brace object
   1114  call setline(1, 'test {yank}  mark')
   1115  call cursor(1, 9)
   1116  normal! yi{
   1117  call assert_equal([0, 1, 10, 0], getpos("']"))
   1118  call cursor(1, 9)
   1119  normal! ya{
   1120  call assert_equal([0, 1, 11, 0], getpos("']"))
   1121  " bracket object
   1122  call setline(1, 'test [yank]  mark')
   1123  call cursor(1, 9)
   1124  normal! yi[
   1125  call assert_equal([0, 1, 10, 0], getpos("']"))
   1126  call cursor(1, 9)
   1127  normal! ya[
   1128  call assert_equal([0, 1, 11, 0], getpos("']"))
   1129  " block object
   1130  call setline(1, 'test <yank>  mark')
   1131  call cursor(1, 9)
   1132  normal! yi<
   1133  call assert_equal([0, 1, 10, 0], getpos("']"))
   1134  call cursor(1, 9)
   1135  normal! ya<
   1136  call assert_equal([0, 1, 11, 0], getpos("']"))
   1137  bw!
   1138 endfunc
   1139 
   1140 func Test_insert_small_delete_linewise()
   1141  new
   1142  call setline(1, ['foo'])
   1143  call cursor(1, 1)
   1144  exe ":norm! \"-cc\<C-R>-"
   1145  call assert_equal(['foo', ''], getline(1, '$'))
   1146  bwipe!
   1147 endfunc
   1148 
   1149 func Test_writing_readonly_regs()
   1150  call assert_fails('let @. = "foo"', 'E354:')
   1151  call assert_fails('let @% = "foo"', 'E354:')
   1152  call assert_fails('let @: = "foo"', 'E354:')
   1153  call assert_fails('let @~ = "foo"', 'E354:')
   1154 endfunc
   1155 
   1156 " vim: shiftwidth=2 sts=2 expandtab