diff src/testdir/test_registers.vim @ 32670:695b50472e85

Fix line endings issue
author Christian Brabandt <cb@256bit.org>
date Mon, 26 Jun 2023 13:13:12 +0200
parents 448aef880252
children dfaddd6f039e
line wrap: on
line diff
--- a/src/testdir/test_registers.vim
+++ b/src/testdir/test_registers.vim
@@ -1,908 +1,908 @@
-" Tests for register operations
-
-source check.vim
-source view_util.vim
-
-" This test must be executed first to check for empty and unset registers.
-func Test_aaa_empty_reg_test()
-  call assert_fails('normal @@', 'E748:')
-  call assert_fails('normal @%', 'E354:')
-  call assert_fails('normal @#', 'E354:')
-  call assert_fails('normal @!', 'E354:')
-  call assert_fails('normal @:', 'E30:')
-  call assert_fails('normal @.', 'E29:')
-  call assert_fails('put /', 'E35:')
-  call assert_fails('put .', 'E29:')
-endfunc
-
-func Test_yank_shows_register()
-    enew
-    set report=0
-    call setline(1, ['foo', 'bar'])
-    " Line-wise
-    exe 'norm! yy'
-    call assert_equal('1 line yanked', v:statusmsg)
-    exe 'norm! "zyy'
-    call assert_equal('1 line yanked into "z', v:statusmsg)
-    exe 'norm! yj'
-    call assert_equal('2 lines yanked', v:statusmsg)
-    exe 'norm! "zyj'
-    call assert_equal('2 lines yanked into "z', v:statusmsg)
-
-    " Block-wise
-    exe "norm! \<C-V>y"
-    call assert_equal('block of 1 line yanked', v:statusmsg)
-    exe "norm! \<C-V>\"zy"
-    call assert_equal('block of 1 line yanked into "z', v:statusmsg)
-    exe "norm! \<C-V>jy"
-    call assert_equal('block of 2 lines yanked', v:statusmsg)
-    exe "norm! \<C-V>j\"zy"
-    call assert_equal('block of 2 lines yanked into "z', v:statusmsg)
-
-    bwipe!
-endfunc
-
-func Test_display_registers()
-    e file1
-    e file2
-    call setline(1, ['foo', 'bar'])
-    /bar
-    exe 'norm! y2l"axx'
-    call feedkeys("i\<C-R>=2*4\n\<esc>")
-    call feedkeys(":ls\n", 'xt')
-
-    " these commands work in the sandbox
-    let a = execute('sandbox display')
-    let b = execute('sandbox registers')
-
-    call assert_equal(a, b)
-    call assert_match('^\nType Name Content\n'
-          \ .         '  c  ""   a\n'
-          \ .         '  c  "0   ba\n'
-          \ .         '  c  "a   b\n'
-          \ .         '.*'
-          \ .         '  c  "-   a\n'
-          \ .         '.*'
-          \ .         '  c  ":   ls\n'
-          \ .         '  c  "%   file2\n'
-          \ .         '  c  "#   file1\n'
-          \ .         '  c  "/   bar\n'
-          \ .         '  c  "=   2\*4', a)
-
-    let a = execute('registers a')
-    call assert_match('^\nType Name Content\n'
-          \ .         '  c  "a   b', a)
-
-    let a = execute('registers :')
-    call assert_match('^\nType Name Content\n'
-          \ .         '  c  ":   ls', a)
-
-    bwipe!
-endfunc
-
-func Test_register_one()
-  " delete a line goes into register one
-  new
-  call setline(1, "one")
-  normal dd
-  call assert_equal("one\n", @1)
-
-  " delete a word does not change register one, does change "-
-  call setline(1, "two")
-  normal de
-  call assert_equal("one\n", @1)
-  call assert_equal("two", @-)
-
-  " delete a word with a register does not change register one
-  call setline(1, "three")
-  normal "ade
-  call assert_equal("three", @a)
-  call assert_equal("one\n", @1)
-
-  " delete a word with register DOES change register one with one of a list of
-  " operators
-  " %
-  call setline(1, ["(12)3"])
-  normal "ad%
-  call assert_equal("(12)", @a)
-  call assert_equal("(12)", @1)
-
-  " (
-  call setline(1, ["first second"])
-  normal $"ad(
-  call assert_equal("first secon", @a)
-  call assert_equal("first secon", @1)
-
-  " )
-  call setline(1, ["First Second."])
-  normal gg0"ad)
-  call assert_equal("First Second.", @a)
-  call assert_equal("First Second.", @1)
-
-  " `
-  call setline(1, ["start here."])
-  normal gg0fhmx0"ad`x
-  call assert_equal("start ", @a)
-  call assert_equal("start ", @1)
-
-  " /
-  call setline(1, ["searchX"])
-  exe "normal gg0\"ad/X\<CR>"
-  call assert_equal("search", @a)
-  call assert_equal("search", @1)
-
-  " ?
-  call setline(1, ["Ysearch"])
-  exe "normal gg$\"ad?Y\<CR>"
-  call assert_equal("Ysearc", @a)
-  call assert_equal("Ysearc", @1)
-
-  " n
-  call setline(1, ["Ynext"])
-  normal gg$"adn
-  call assert_equal("Ynex", @a)
-  call assert_equal("Ynex", @1)
-
-  " N
-  call setline(1, ["prevY"])
-  normal gg0"adN
-  call assert_equal("prev", @a)
-  call assert_equal("prev", @1)
-
-  " }
-  call setline(1, ["one", ""])
-  normal gg0"ad}
-  call assert_equal("one\n", @a)
-  call assert_equal("one\n", @1)
-
-  " {
-  call setline(1, ["", "two"])
-  normal 2G$"ad{
-  call assert_equal("\ntw", @a)
-  call assert_equal("\ntw", @1)
-
-  bwipe!
-endfunc
-
-func Test_recording_status_in_ex_line()
-  norm qx
-  redraw!
-  call assert_equal('recording @x', Screenline(&lines))
-  set shortmess=q
-  redraw!
-  call assert_equal('recording', Screenline(&lines))
-  set shortmess&
-  norm q
-  redraw!
-  call assert_equal('', Screenline(&lines))
-endfunc
-
-" Check that replaying a typed sequence does not use an Esc and following
-" characters as an escape sequence.
-func Test_recording_esc_sequence()
-  new
-  try
-    let save_F2 = &t_F2
-  catch
-  endtry
-  let t_F2 = "\<Esc>OQ"
-  call feedkeys("qqiTest\<Esc>", "xt")
-  call feedkeys("OQuirk\<Esc>q", "xt")
-  call feedkeys("Go\<Esc>@q", "xt")
-  call assert_equal(['Quirk', 'Test', 'Quirk', 'Test'], getline(1, 4))
-  bwipe!
-  if exists('save_F2')
-    let &t_F2 = save_F2
-  else
-    set t_F2=
-  endif
-endfunc
-
-func Test_recording_with_select_mode()
-  new
-  call feedkeys("qacc12345\<Esc>gH98765\<Esc>q", "tx")
-  call assert_equal("98765", getline(1))
-  call assert_equal("cc12345\<Esc>gH98765\<Esc>", @a)
-  call setline(1, 'asdf')
-  normal! @a
-  call assert_equal("98765", getline(1))
-  bwipe!
-endfunc
-
-" Test for executing the last used register (@)
-func Test_last_used_exec_reg()
-  " Test for the @: command
-  let a = ''
-  call feedkeys(":let a ..= 'Vim'\<CR>", 'xt')
-  normal @:
-  call assert_equal('VimVim', a)
-
-  " Test for the @= command
-  let x = ''
-  let a = ":let x ..= 'Vim'\<CR>"
-  exe "normal @=a\<CR>"
-  normal @@
-  call assert_equal('VimVim', x)
-
-  " Test for the @. command
-  let a = ''
-  call feedkeys("i:let a ..= 'Edit'\<CR>", 'xt')
-  normal @.
-  normal @@
-  call assert_equal('EditEdit', a)
-
-  " Test for repeating the last command-line in visual mode
-  call append(0, 'register')
-  normal gg
-  let @r = ''
-  call feedkeys("v:yank R\<CR>", 'xt')
-  call feedkeys("v@:", 'xt')
-  call assert_equal("\nregister\nregister\n", @r)
-
-  enew!
-endfunc
-
-func Test_get_register()
-  enew
-  edit Xfile1
-  edit Xfile2
-  call assert_equal('Xfile2', getreg('%'))
-  call assert_equal('Xfile1', getreg('#'))
-
-  call feedkeys("iTwo\<Esc>", 'xt')
-  call assert_equal('Two', getreg('.'))
-  call assert_equal('', getreg('_'))
-  call assert_beeps('normal ":yy')
-  call assert_beeps('normal "%yy')
-  call assert_beeps('normal ".yy')
-
-  call assert_equal('', getreg("\<C-F>"))
-  call assert_equal('', getreg("\<C-W>"))
-  call assert_equal('', getreg("\<C-L>"))
-  " Change the last used register to '"' for the next test
-  normal! ""yy
-  let @" = 'happy'
-  call assert_equal('happy', getreg())
-  call assert_equal('happy', getreg(''))
-
-  call assert_equal('', getregtype('!'))
-  call assert_fails('echo getregtype([])', 'E730:')
-  call assert_equal('v', getregtype())
-  call assert_equal('v', getregtype(''))
-
-  " Test for inserting an invalid register content
-  call assert_beeps('exe "normal i\<C-R>!"')
-
-  " Test for inserting a register with multiple lines
-  call deletebufline('', 1, '$')
-  call setreg('r', ['a', 'b'])
-  exe "normal i\<C-R>r"
-  call assert_equal(['a', 'b', ''], getline(1, '$'))
-
-  " Test for inserting a multi-line register in the command line
-  call feedkeys(":\<C-R>r\<Esc>", 'xt')
-  call assert_equal("a\rb\r", histget(':', -1))
-
-  call assert_fails('let r = getreg("=", [])', 'E745:')
-  call assert_fails('let r = getreg("=", 1, [])', 'E745:')
-  enew!
-
-  " Using a register in operator-pending mode should fail
-  call assert_beeps('norm! c"')
-endfunc
-
-func Test_set_register()
-  call assert_fails("call setreg('#', 200)", 'E86:')
-  call assert_fails("call setreg('a', test_unknown())", 'E908:')
-
-  edit Xfile_alt_1
-  let b1 = bufnr('')
-  edit Xfile_alt_2
-  let b2 = bufnr('')
-  edit Xfile_alt_3
-  let b3 = bufnr('')
-  call setreg('#', 'alt_1')
-  call assert_equal('Xfile_alt_1', getreg('#'))
-  call setreg('#', b2)
-  call assert_equal('Xfile_alt_2', getreg('#'))
-
-  let ab = 'regwrite'
-  call setreg('=', '')
-  call setreg('=', 'a', 'a')
-  call setreg('=', 'b', 'a')
-  call assert_equal('regwrite', getreg('='))
-
-  " Test for setting a list of lines to special registers
-  call setreg('/', [])
-  call assert_equal('', @/)
-  call setreg('=', [])
-  call assert_equal('', @=)
-  call assert_fails("call setreg('/', ['a', 'b'])", 'E883:')
-  call assert_fails("call setreg('=', ['a', 'b'])", 'E883:')
-  call assert_equal(0, setreg('_', ['a', 'b']))
-
-  " Test for recording to a invalid register
-  call assert_beeps('normal q$')
-
-  " Appending to a register when recording
-  call append(0, "text for clipboard test")
-  normal gg
-  call feedkeys('qrllq', 'xt')
-  call feedkeys('qRhhq', 'xt')
-  call assert_equal('llhh', getreg('r'))
-
-  " Appending a list of characters to a register from different lines
-  let @r = ''
-  call append(0, ['abcdef', '123456'])
-  normal gg"ry3l
-  call cursor(2, 4)
-  normal "Ry3l
-  call assert_equal('abc456', @r)
-
-  " Test for gP with multiple lines selected using characterwise motion
-  %delete
-  call append(0, ['vim editor', 'vim editor'])
-  let @r = ''
-  exe "normal ggwy/vim /e\<CR>gP"
-  call assert_equal(['vim editor', 'vim editor', 'vim editor'], getline(1, 3))
-
-  " Test for gP with . register
-  %delete
-  normal iabc
-  normal ".gp
-  call assert_equal('abcabc', getline(1))
-  normal 0".gP
-  call assert_equal('abcabcabc', getline(1))
-
-  let @"=''
-  call setreg('', '1')
-  call assert_equal('1', @")
-  call setreg('@', '2')
-  call assert_equal('2', @")
-
-  enew!
-endfunc
-
-" Test for clipboard registers (* and +)
-func Test_clipboard_regs()
-  CheckNotGui
-  CheckFeature clipboard_working
-
-  new
-  call append(0, "text for clipboard test")
-  normal gg"*yiw
-  call assert_equal('text', getreg('*'))
-  normal gg2w"+yiw
-  call assert_equal('clipboard', getreg('+'))
-
-  " Test for replacing the clipboard register contents
-  set clipboard=unnamed
-  let @* = 'food'
-  normal ggviw"*p
-  call assert_equal('text', getreg('*'))
-  call assert_equal('food for clipboard test', getline(1))
-  normal ggviw"*p
-  call assert_equal('food', getreg('*'))
-  call assert_equal('text for clipboard test', getline(1))
-
-  " Test for replacing the selection register contents
-  set clipboard=unnamedplus
-  let @+ = 'food'
-  normal ggviw"+p
-  call assert_equal('text', getreg('+'))
-  call assert_equal('food for clipboard test', getline(1))
-  normal ggviw"+p
-  call assert_equal('food', getreg('+'))
-  call assert_equal('text for clipboard test', getline(1))
-
-  " Test for auto copying visually selected text to clipboard register
-  call setline(1, "text for clipboard test")
-  let @* = ''
-  set clipboard=autoselect
-  normal ggwwviwy
-  call assert_equal('clipboard', @*)
-
-  " Test for auto copying visually selected text to selection register
-  let @+ = ''
-  set clipboard=autoselectplus
-  normal ggwviwy
-  call assert_equal('for', @+)
-
-  set clipboard&vim
-  bwipe!
-endfunc
-
-" Test unnamed for both clipboard registers (* and +)
-func Test_clipboard_regs_both_unnamed()
-  CheckNotGui
-  CheckFeature clipboard_working
-  CheckTwoClipboards
-
-  let @* = 'xxx'
-  let @+ = 'xxx'
-
-  new
-
-  set clipboard=unnamed,unnamedplus
-  call setline(1, ['foo', 'bar'])
-
-  " op_yank copies to both
-  :1
-  :normal yw
-  call assert_equal('foo', getreg('*'))
-  call assert_equal('foo', getreg('+'))
-
-  " op_delete only copies to '+'
-  :2
-  :normal dw
-  call assert_equal('foo', getreg('*'))
-  call assert_equal('bar', getreg('+'))
-
-  set clipboard&vim
-  bwipe!
-endfunc
-
-" Test for restarting the current mode (insert or virtual replace) after
-" executing the contents of a register
-func Test_put_reg_restart_mode()
-  new
-  call append(0, 'editor')
-  normal gg
-  let @r = "ivim \<Esc>"
-  call feedkeys("i\<C-O>@r\<C-R>=mode()\<CR>", 'xt')
-  call assert_equal('vimi editor', getline(1))
-
-  call setline(1, 'editor')
-  normal gg
-  call feedkeys("gR\<C-O>@r\<C-R>=mode()\<CR>", 'xt')
-  call assert_equal('vimReditor', getline(1))
-
-  bwipe!
-endfunc
-
-" Test for executing a register using :@ command
-func Test_execute_register()
-  call setreg('r', [])
-  call assert_beeps('@r')
-  let i = 1
-  let @q = 'let i+= 1'
-  @q
-  @
-  call assert_equal(3, i)
-
-  " try to execute expression register and use a backspace to cancel it
-  new
-  call feedkeys("@=\<BS>ax\<CR>y", 'xt')
-  call assert_equal(['x', 'y'], getline(1, '$'))
-  close!
-
-  " cannot execute a register in operator pending mode
-  call assert_beeps('normal! c@r')
-endfunc
-
-" Test for getting register info
-func Test_get_reginfo()
-  enew
-  call setline(1, ['foo', 'bar'])
-
-  exe 'norm! "zyy'
-  let info = getreginfo('"')
-  call assert_equal('z', info.points_to)
-  call setreg('y', 'baz')
-  call assert_equal('z', getreginfo('').points_to)
-  call setreg('y', { 'isunnamed': v:true })
-  call assert_equal('y', getreginfo('"').points_to)
-
-  exe '$put'
-  call assert_equal(getreg('y'), getline(3))
-  call setreg('', 'qux')
-  call assert_equal('0', getreginfo('').points_to)
-  call setreg('x', 'quux')
-  call assert_equal('0', getreginfo('').points_to)
-
-  let info = getreginfo('')
-  call assert_equal(getreg('', 1, 1), info.regcontents)
-  call assert_equal(getregtype(''), info.regtype)
-
-  exe "norm! 0\<c-v>e" .. '"zy'
-  let info = getreginfo('z')
-  call assert_equal(getreg('z', 1, 1), info.regcontents)
-  call assert_equal(getregtype('z'), info.regtype)
-  call assert_equal(1, +info.isunnamed)
-
-  let info = getreginfo('"')
-  call assert_equal('z', info.points_to)
-
-  let @a="a1b2"
-  nnoremap <F2> <Cmd>let g:RegInfo = getreginfo()<CR>
-  exe "normal \"a\<F2>"
-  call assert_equal({'regcontents': ['a1b2'], 'isunnamed': v:false,
-        \ 'regtype': 'v'}, g:RegInfo)
-  nunmap <F2>
-  unlet g:RegInfo
-
-  " The type of "isunnamed" was VAR_SPECIAL but should be VAR_BOOL.  Can only
-  " be noticed when using json_encod().
-  call setreg('a', 'foo')
-  let reginfo = getreginfo('a')
-  let expected = #{regcontents: ['foo'], isunnamed: v:false, regtype: 'v'}
-  call assert_equal(json_encode(expected), json_encode(reginfo))
-
-  bwipe!
-endfunc
-
-" Test for restoring register with dict from getreginfo
-func Test_set_register_dict()
-  enew!
-
-  call setreg('"', #{ regcontents: ['one', 'two'],
-        \ regtype: 'V', points_to: 'z' })
-  call assert_equal(['one', 'two'], getreg('"', 1, 1))
-  let info = getreginfo('"')
-  call assert_equal('z', info.points_to)
-  call assert_equal('V', info.regtype)
-  call assert_equal(1, +getreginfo('z').isunnamed)
-
-  call setreg('x', #{ regcontents: ['three', 'four'],
-        \ regtype: 'v', isunnamed: v:true })
-  call assert_equal(['three', 'four'], getreg('"', 1, 1))
-  let info = getreginfo('"')
-  call assert_equal('x', info.points_to)
-  call assert_equal('v', info.regtype)
-  call assert_equal(1, +getreginfo('x').isunnamed)
-
-  call setreg('y', #{ regcontents: 'five',
-        \ regtype: "\<c-v>", isunnamed: v:false })
-  call assert_equal("\<c-v>4", getreginfo('y').regtype)
-  call assert_equal(0, +getreginfo('y').isunnamed)
-  call assert_equal(['three', 'four'], getreg('"', 1, 1))
-  call assert_equal('x', getreginfo('"').points_to)
-
-  call setreg('"', #{ regcontents: 'six' })
-  call assert_equal('0', getreginfo('"').points_to)
-  call assert_equal(1, +getreginfo('0').isunnamed)
-  call assert_equal(['six'], getreginfo('0').regcontents)
-  call assert_equal(['six'], getreginfo('"').regcontents)
-
-  let @x = 'one'
-  call setreg('x', {})
-  call assert_equal(1, len(split(execute('reg x'), '\n')))
-
-  call assert_fails("call setreg('0', #{regtype: 'V'}, 'v')", 'E118:')
-  call assert_fails("call setreg('0', #{regtype: 'X'})", 'E475:')
-  call assert_fails("call setreg('0', #{regtype: 'vy'})", 'E475:')
-
-  bwipe!
-endfunc
-
-func Test_v_register()
-  enew
-  call setline(1, 'nothing')
-
-  func s:Put()
-    let s:register = v:register
-    exec 'normal! "' .. v:register .. 'P'
-  endfunc
-  nnoremap <buffer> <plug>(test) :<c-u>call s:Put()<cr>
-  nmap <buffer> S <plug>(test)
-
-  let @z = "testz\n"
-  let @" = "test@\n"
-
-  let s:register = ''
-  call feedkeys('"_ddS', 'mx')
-  call assert_equal('test@', getline('.'))  " fails before 8.2.0929
-  call assert_equal('"', s:register)        " fails before 8.2.0929
-
-  let s:register = ''
-  call feedkeys('"zS', 'mx')
-  call assert_equal('z', s:register)
-
-  let s:register = ''
-  call feedkeys('"zSS', 'mx')
-  call assert_equal('"', s:register)
-
-  let s:register = ''
-  call feedkeys('"_S', 'mx')
-  call assert_equal('_', s:register)
-
-  let s:register = ''
-  normal "_ddS
-  call assert_equal('"', s:register)        " fails before 8.2.0929
-  call assert_equal('test@', getline('.'))  " fails before 8.2.0929
-
-  let s:register = ''
-  execute 'normal "z:call' "s:Put()\n"
-  call assert_equal('z', s:register)
-  call assert_equal('testz', getline('.'))
-
-  " Test operator and omap
-  let @b = 'testb'
-  func s:OpFunc(...)
-    let s:register2 = v:register
-  endfunc
-  set opfunc=s:OpFunc
-
-  normal "bg@l
-  normal S
-  call assert_equal('"', s:register)        " fails before 8.2.0929
-  call assert_equal('b', s:register2)
-
-  func s:Motion()
-    let s:register1 = v:register
-    normal! l
-  endfunc
-  onoremap <buffer> Q :<c-u>call s:Motion()<cr>
-
-  normal "bg@Q
-  normal S
-  call assert_equal('"', s:register)
-  call assert_equal('b', s:register1)
-  call assert_equal('"', s:register2)
-
-  set opfunc&
-  bwipe!
-endfunc
-
-" Test for executing the contents of a register as an Ex command with line
-" continuation.
-func Test_execute_reg_as_ex_cmd()
-  " Line continuation with just two lines
-  let code =<< trim END
-    let l = [
-      \ 1]
-  END
-  let @r = code->join("\n")
-  let l = []
-  @r
-  call assert_equal([1], l)
-
-  " Line continuation with more than two lines
-  let code =<< trim END
-    let l = [
-      \ 1,
-      \ 2,
-      \ 3]
-  END
-  let @r = code->join("\n")
-  let l = []
-  @r
-  call assert_equal([1, 2, 3], l)
-
-  " use comments interspersed with code
-  let code =<< trim END
-    let l = [
-      "\ one
-      \ 1,
-      "\ two
-      \ 2,
-      "\ three
-      \ 3]
-  END
-  let @r = code->join("\n")
-  let l = []
-  @r
-  call assert_equal([1, 2, 3], l)
-
-  " use line continuation in the middle
-  let code =<< trim END
-    let a = "one"
-    let l = [
-      \ 1,
-      \ 2]
-    let b = "two"
-  END
-  let @r = code->join("\n")
-  let l = []
-  @r
-  call assert_equal([1, 2], l)
-  call assert_equal("one", a)
-  call assert_equal("two", b)
-
-  " only one line with a \
-  let @r = "\\let l = 1"
-  call assert_fails('@r', 'E10:')
-
-  " only one line with a "\
-  let @r = '   "\ let i = 1'
-  @r
-  call assert_false(exists('i'))
-
-  " first line also begins with a \
-  let @r = "\\let l = [\n\\ 1]"
-  call assert_fails('@r', 'E10:')
-
-  " Test with a large number of lines
-  let @r = "let str = \n"
-  let @r ..= repeat("  \\ 'abcdefghijklmnopqrstuvwxyz' ..\n", 312)
-  let @r ..= '  \ ""'
-  @r
-  call assert_equal(repeat('abcdefghijklmnopqrstuvwxyz', 312), str)
-endfunc
-
-" Test for clipboard registers with ASCII NUL
-func Test_clipboard_nul()
-  CheckFeature clipboard_working
-  new
-
-  " Test for putting ASCII NUL into the clipboard
-  set clipboard=unnamed
-  call append(0, "\ntest")
-  normal ggyyp
-  call assert_equal("^@test^@", strtrans(getreg('*')))
-  call assert_equal(getline(1), getline(2))
-  let b = split(execute(":reg *"), "\n")
-  call assert_match('"\*\s*\^@test\^J',b[1])
-
-  set clipboard&vim
-  bwipe!
-endfunc
-
-func Test_ve_blockpaste()
-  new
-  set ve=all
-  0put =['QWERTZ','ASDFGH']
-  call cursor(1,1)
-  exe ":norm! \<C-V>3ljdP"
-  call assert_equal(1, col('.'))
-  call assert_equal(getline(1, 2), ['QWERTZ', 'ASDFGH'])
-  call cursor(1,1)
-  exe ":norm! \<C-V>3ljd"
-  call cursor(1,1)
-  norm! $3lP
-  call assert_equal(5, col('.'))
-  call assert_equal(getline(1, 2), ['TZ  QWER', 'GH  ASDF'])
-  set ve&vim
-  bwipe!
-endfunc
-
-func Test_insert_small_delete()
-  new
-  call setline(1, ['foo foobar bar'])
-  call cursor(1,1)
-  exe ":norm! ciw'\<C-R>-'"
-  call assert_equal("'foo' foobar bar", getline(1))
-  exe ":norm! w.w."
-  call assert_equal("'foo' 'foobar' 'bar'", getline(1))
-  bwipe!
-endfunc
-
-" Record in insert mode using CTRL-O
-func Test_record_in_insert_mode()
-  new
-  let @r = ''
-  call setline(1, ['foo'])
-  call feedkeys("i\<C-O>qrbaz\<C-O>q", 'xt')
-  call assert_equal('baz', @r)
-  bwipe!
-endfunc
-
-func Test_record_in_select_mode()
-  new
-  call setline(1, 'text')
-  sil norm q00
-  sil norm q
-  call assert_equal('0ext', getline(1))
-
-  %delete
-  let @r = ''
-  call setline(1, ['abc', 'abc', 'abc'])
-  smap <F2> <Right><Right>,
-  call feedkeys("qrgh\<F2>Dk\<Esc>q", 'xt')
-  call assert_equal("gh\<F2>Dk\<Esc>", @r)
-  norm j0@rj0@@
-  call assert_equal([',Dk', ',Dk', ',Dk'], getline(1, 3))
-  sunmap <F2>
-
-  bwipe!
-endfunc
-
-" mapping that ends macro recording should be removed from recorded macro
-func Test_end_record_using_mapping()
-  call setline(1, 'aaa')
-  nnoremap s q
-  call feedkeys('safas', 'tx')
-  call assert_equal('fa', @a)
-  nunmap s
-
-  nnoremap xx q
-  call feedkeys('0xxafaxx', 'tx')
-  call assert_equal('fa', @a)
-  nunmap xx
-
-  nnoremap xsx q
-  call feedkeys('0qafaxsx', 'tx')
-  call assert_equal('fa', @a)
-  nunmap xsx
-
-  bwipe!
-endfunc
-
-func Test_end_reg_executing()
-  nnoremap s <Nop>
-  let @a = 's'
-  call feedkeys("@aqaq\<Esc>", 'tx')
-  call assert_equal('', @a)
-  call assert_equal('', getline(1))
-
-  call setline(1, 'aaa')
-  nnoremap s qa
-  let @a = 'fa'
-  call feedkeys("@asq\<Esc>", 'tx')
-  call assert_equal('', @a)
-  call assert_equal('aaa', getline(1))
-
-  nunmap s
-  bwipe!
-endfunc
-
-" This was causing a crash because y_append was ending up being NULL
-func Test_zero_y_append()
-  " Run in a separate Vim instance because changing 'encoding' may cause
-  " trouble for later tests.
-  let lines =<< trim END
-      d
-      silent ?n
-      next <sfile>
-      so
-      sil! norm 0V€PSP
-      set enc=latin1
-       
-  END
-  call writefile(lines, 'XTest_zero_y_append', 'D')
-  call RunVim([], [], '-u NONE -i NONE -e -s -S XTest_zero_y_append -c qa\!')
-endfunc
-
-" Make sure that y_append is correctly reset
-" and the previous register is working as expected
-func Test_register_y_append_reset()
-  new
-  call setline(1, ['1',
-    \ '2 ----------------------------------------------------',
-    \ '3',
-    \ '4',
-    \ '5 ----------------------------------------------------',
-    \ '6',
-    \ '7',
-    \ '8 ----------------------------------------------------',
-    \ '9',
-    \ '10 aaaaaaa 4.',
-    \ '11 Game Dbl-Figures Leaders:',
-    \ '12 Player Pts FG% 3P% FT% RB AS BL ST TO PF EFF',
-    \ '13 bbbbbbbbb 12 (50 /0 /67 )/ 7/ 3/ 0/ 2/ 3/ 4/+15',
-    \ '14 cccccc 12 (57 /67 /100)/ 2/ 1/ 1/ 0/ 1/ 3/+12',
-    \ '15 ddddddd 10 (63 /0 /0 )/ 1/ 3/ 0/ 3/ 5/ 3/ +9',
-    \ '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',
-    \ '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',
-    \ '18 4 3 6 3 2 3 3 4 3 3 7 3 1 4 6 -1 -1 +2 -1 -2',
-    \ '19 F 13 19 5 10 4 17 22 9 14 32 13 4 20 17 -1 -13 -4 -3 -3 +5'])
-  11
-  exe "norm! \"a5dd"
-  norm! j
-  exe "norm! \"bY"
-  norm! 2j
-  exe "norm! \"BY"
-  norm! 4k
-  norm! 5dd
-  norm! 3k
-  " The next put should put the content of the unnamed register, not of
-  " register b!
-  norm! p
-  call assert_equal(['1',
-    \ '2 ----------------------------------------------------',
-    \ '3',
-    \ '4',
-    \ '5 ----------------------------------------------------',
-    \ '6',
-    \ '10 aaaaaaa 4.',
-    \ '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',
-    \ '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',
-    \ '18 4 3 6 3 2 3 3 4 3 3 7 3 1 4 6 -1 -1 +2 -1 -2',
-    \ '19 F 13 19 5 10 4 17 22 9 14 32 13 4 20 17 -1 -13 -4 -3 -3 +5',
-    \ '7',
-    \ '8 ----------------------------------------------------',
-    \ '9'], getline(1,'$'))
-  bwipe!
-endfunc
-
-" vim: shiftwidth=2 sts=2 expandtab
+" Tests for register operations
+
+source check.vim
+source view_util.vim
+
+" This test must be executed first to check for empty and unset registers.
+func Test_aaa_empty_reg_test()
+  call assert_fails('normal @@', 'E748:')
+  call assert_fails('normal @%', 'E354:')
+  call assert_fails('normal @#', 'E354:')
+  call assert_fails('normal @!', 'E354:')
+  call assert_fails('normal @:', 'E30:')
+  call assert_fails('normal @.', 'E29:')
+  call assert_fails('put /', 'E35:')
+  call assert_fails('put .', 'E29:')
+endfunc
+
+func Test_yank_shows_register()
+    enew
+    set report=0
+    call setline(1, ['foo', 'bar'])
+    " Line-wise
+    exe 'norm! yy'
+    call assert_equal('1 line yanked', v:statusmsg)
+    exe 'norm! "zyy'
+    call assert_equal('1 line yanked into "z', v:statusmsg)
+    exe 'norm! yj'
+    call assert_equal('2 lines yanked', v:statusmsg)
+    exe 'norm! "zyj'
+    call assert_equal('2 lines yanked into "z', v:statusmsg)
+
+    " Block-wise
+    exe "norm! \<C-V>y"
+    call assert_equal('block of 1 line yanked', v:statusmsg)
+    exe "norm! \<C-V>\"zy"
+    call assert_equal('block of 1 line yanked into "z', v:statusmsg)
+    exe "norm! \<C-V>jy"
+    call assert_equal('block of 2 lines yanked', v:statusmsg)
+    exe "norm! \<C-V>j\"zy"
+    call assert_equal('block of 2 lines yanked into "z', v:statusmsg)
+
+    bwipe!
+endfunc
+
+func Test_display_registers()
+    e file1
+    e file2
+    call setline(1, ['foo', 'bar'])
+    /bar
+    exe 'norm! y2l"axx'
+    call feedkeys("i\<C-R>=2*4\n\<esc>")
+    call feedkeys(":ls\n", 'xt')
+
+    " these commands work in the sandbox
+    let a = execute('sandbox display')
+    let b = execute('sandbox registers')
+
+    call assert_equal(a, b)
+    call assert_match('^\nType Name Content\n'
+          \ .         '  c  ""   a\n'
+          \ .         '  c  "0   ba\n'
+          \ .         '  c  "a   b\n'
+          \ .         '.*'
+          \ .         '  c  "-   a\n'
+          \ .         '.*'
+          \ .         '  c  ":   ls\n'
+          \ .         '  c  "%   file2\n'
+          \ .         '  c  "#   file1\n'
+          \ .         '  c  "/   bar\n'
+          \ .         '  c  "=   2\*4', a)
+
+    let a = execute('registers a')
+    call assert_match('^\nType Name Content\n'
+          \ .         '  c  "a   b', a)
+
+    let a = execute('registers :')
+    call assert_match('^\nType Name Content\n'
+          \ .         '  c  ":   ls', a)
+
+    bwipe!
+endfunc
+
+func Test_register_one()
+  " delete a line goes into register one
+  new
+  call setline(1, "one")
+  normal dd
+  call assert_equal("one\n", @1)
+
+  " delete a word does not change register one, does change "-
+  call setline(1, "two")
+  normal de
+  call assert_equal("one\n", @1)
+  call assert_equal("two", @-)
+
+  " delete a word with a register does not change register one
+  call setline(1, "three")
+  normal "ade
+  call assert_equal("three", @a)
+  call assert_equal("one\n", @1)
+
+  " delete a word with register DOES change register one with one of a list of
+  " operators
+  " %
+  call setline(1, ["(12)3"])
+  normal "ad%
+  call assert_equal("(12)", @a)
+  call assert_equal("(12)", @1)
+
+  " (
+  call setline(1, ["first second"])
+  normal $"ad(
+  call assert_equal("first secon", @a)
+  call assert_equal("first secon", @1)
+
+  " )
+  call setline(1, ["First Second."])
+  normal gg0"ad)
+  call assert_equal("First Second.", @a)
+  call assert_equal("First Second.", @1)
+
+  " `
+  call setline(1, ["start here."])
+  normal gg0fhmx0"ad`x
+  call assert_equal("start ", @a)
+  call assert_equal("start ", @1)
+
+  " /
+  call setline(1, ["searchX"])
+  exe "normal gg0\"ad/X\<CR>"
+  call assert_equal("search", @a)
+  call assert_equal("search", @1)
+
+  " ?
+  call setline(1, ["Ysearch"])
+  exe "normal gg$\"ad?Y\<CR>"
+  call assert_equal("Ysearc", @a)
+  call assert_equal("Ysearc", @1)
+
+  " n
+  call setline(1, ["Ynext"])
+  normal gg$"adn
+  call assert_equal("Ynex", @a)
+  call assert_equal("Ynex", @1)
+
+  " N
+  call setline(1, ["prevY"])
+  normal gg0"adN
+  call assert_equal("prev", @a)
+  call assert_equal("prev", @1)
+
+  " }
+  call setline(1, ["one", ""])
+  normal gg0"ad}
+  call assert_equal("one\n", @a)
+  call assert_equal("one\n", @1)
+
+  " {
+  call setline(1, ["", "two"])
+  normal 2G$"ad{
+  call assert_equal("\ntw", @a)
+  call assert_equal("\ntw", @1)
+
+  bwipe!
+endfunc
+
+func Test_recording_status_in_ex_line()
+  norm qx
+  redraw!
+  call assert_equal('recording @x', Screenline(&lines))
+  set shortmess=q
+  redraw!
+  call assert_equal('recording', Screenline(&lines))
+  set shortmess&
+  norm q
+  redraw!
+  call assert_equal('', Screenline(&lines))
+endfunc
+
+" Check that replaying a typed sequence does not use an Esc and following
+" characters as an escape sequence.
+func Test_recording_esc_sequence()
+  new
+  try
+    let save_F2 = &t_F2
+  catch
+  endtry
+  let t_F2 = "\<Esc>OQ"
+  call feedkeys("qqiTest\<Esc>", "xt")
+  call feedkeys("OQuirk\<Esc>q", "xt")
+  call feedkeys("Go\<Esc>@q", "xt")
+  call assert_equal(['Quirk', 'Test', 'Quirk', 'Test'], getline(1, 4))
+  bwipe!
+  if exists('save_F2')
+    let &t_F2 = save_F2
+  else
+    set t_F2=
+  endif
+endfunc
+
+func Test_recording_with_select_mode()
+  new
+  call feedkeys("qacc12345\<Esc>gH98765\<Esc>q", "tx")
+  call assert_equal("98765", getline(1))
+  call assert_equal("cc12345\<Esc>gH98765\<Esc>", @a)
+  call setline(1, 'asdf')
+  normal! @a
+  call assert_equal("98765", getline(1))
+  bwipe!
+endfunc
+
+" Test for executing the last used register (@)
+func Test_last_used_exec_reg()
+  " Test for the @: command
+  let a = ''
+  call feedkeys(":let a ..= 'Vim'\<CR>", 'xt')
+  normal @:
+  call assert_equal('VimVim', a)
+
+  " Test for the @= command
+  let x = ''
+  let a = ":let x ..= 'Vim'\<CR>"
+  exe "normal @=a\<CR>"
+  normal @@
+  call assert_equal('VimVim', x)
+
+  " Test for the @. command
+  let a = ''
+  call feedkeys("i:let a ..= 'Edit'\<CR>", 'xt')
+  normal @.
+  normal @@
+  call assert_equal('EditEdit', a)
+
+  " Test for repeating the last command-line in visual mode
+  call append(0, 'register')
+  normal gg
+  let @r = ''
+  call feedkeys("v:yank R\<CR>", 'xt')
+  call feedkeys("v@:", 'xt')
+  call assert_equal("\nregister\nregister\n", @r)
+
+  enew!
+endfunc
+
+func Test_get_register()
+  enew
+  edit Xfile1
+  edit Xfile2
+  call assert_equal('Xfile2', getreg('%'))
+  call assert_equal('Xfile1', getreg('#'))
+
+  call feedkeys("iTwo\<Esc>", 'xt')
+  call assert_equal('Two', getreg('.'))
+  call assert_equal('', getreg('_'))
+  call assert_beeps('normal ":yy')
+  call assert_beeps('normal "%yy')
+  call assert_beeps('normal ".yy')
+
+  call assert_equal('', getreg("\<C-F>"))
+  call assert_equal('', getreg("\<C-W>"))
+  call assert_equal('', getreg("\<C-L>"))
+  " Change the last used register to '"' for the next test
+  normal! ""yy
+  let @" = 'happy'
+  call assert_equal('happy', getreg())
+  call assert_equal('happy', getreg(''))
+
+  call assert_equal('', getregtype('!'))
+  call assert_fails('echo getregtype([])', 'E730:')
+  call assert_equal('v', getregtype())
+  call assert_equal('v', getregtype(''))
+
+  " Test for inserting an invalid register content
+  call assert_beeps('exe "normal i\<C-R>!"')
+
+  " Test for inserting a register with multiple lines
+  call deletebufline('', 1, '$')
+  call setreg('r', ['a', 'b'])
+  exe "normal i\<C-R>r"
+  call assert_equal(['a', 'b', ''], getline(1, '$'))
+
+  " Test for inserting a multi-line register in the command line
+  call feedkeys(":\<C-R>r\<Esc>", 'xt')
+  call assert_equal("a\rb\r", histget(':', -1))
+
+  call assert_fails('let r = getreg("=", [])', 'E745:')
+  call assert_fails('let r = getreg("=", 1, [])', 'E745:')
+  enew!
+
+  " Using a register in operator-pending mode should fail
+  call assert_beeps('norm! c"')
+endfunc
+
+func Test_set_register()
+  call assert_fails("call setreg('#', 200)", 'E86:')
+  call assert_fails("call setreg('a', test_unknown())", 'E908:')
+
+  edit Xfile_alt_1
+  let b1 = bufnr('')
+  edit Xfile_alt_2
+  let b2 = bufnr('')
+  edit Xfile_alt_3
+  let b3 = bufnr('')
+  call setreg('#', 'alt_1')
+  call assert_equal('Xfile_alt_1', getreg('#'))
+  call setreg('#', b2)
+  call assert_equal('Xfile_alt_2', getreg('#'))
+
+  let ab = 'regwrite'
+  call setreg('=', '')
+  call setreg('=', 'a', 'a')
+  call setreg('=', 'b', 'a')
+  call assert_equal('regwrite', getreg('='))
+
+  " Test for setting a list of lines to special registers
+  call setreg('/', [])
+  call assert_equal('', @/)
+  call setreg('=', [])
+  call assert_equal('', @=)
+  call assert_fails("call setreg('/', ['a', 'b'])", 'E883:')
+  call assert_fails("call setreg('=', ['a', 'b'])", 'E883:')
+  call assert_equal(0, setreg('_', ['a', 'b']))
+
+  " Test for recording to a invalid register
+  call assert_beeps('normal q$')
+
+  " Appending to a register when recording
+  call append(0, "text for clipboard test")
+  normal gg
+  call feedkeys('qrllq', 'xt')
+  call feedkeys('qRhhq', 'xt')
+  call assert_equal('llhh', getreg('r'))
+
+  " Appending a list of characters to a register from different lines
+  let @r = ''
+  call append(0, ['abcdef', '123456'])
+  normal gg"ry3l
+  call cursor(2, 4)
+  normal "Ry3l
+  call assert_equal('abc456', @r)
+
+  " Test for gP with multiple lines selected using characterwise motion
+  %delete
+  call append(0, ['vim editor', 'vim editor'])
+  let @r = ''
+  exe "normal ggwy/vim /e\<CR>gP"
+  call assert_equal(['vim editor', 'vim editor', 'vim editor'], getline(1, 3))
+
+  " Test for gP with . register
+  %delete
+  normal iabc
+  normal ".gp
+  call assert_equal('abcabc', getline(1))
+  normal 0".gP
+  call assert_equal('abcabcabc', getline(1))
+
+  let @"=''
+  call setreg('', '1')
+  call assert_equal('1', @")
+  call setreg('@', '2')
+  call assert_equal('2', @")
+
+  enew!
+endfunc
+
+" Test for clipboard registers (* and +)
+func Test_clipboard_regs()
+  CheckNotGui
+  CheckFeature clipboard_working
+
+  new
+  call append(0, "text for clipboard test")
+  normal gg"*yiw
+  call assert_equal('text', getreg('*'))
+  normal gg2w"+yiw
+  call assert_equal('clipboard', getreg('+'))
+
+  " Test for replacing the clipboard register contents
+  set clipboard=unnamed
+  let @* = 'food'
+  normal ggviw"*p
+  call assert_equal('text', getreg('*'))
+  call assert_equal('food for clipboard test', getline(1))
+  normal ggviw"*p
+  call assert_equal('food', getreg('*'))
+  call assert_equal('text for clipboard test', getline(1))
+
+  " Test for replacing the selection register contents
+  set clipboard=unnamedplus
+  let @+ = 'food'
+  normal ggviw"+p
+  call assert_equal('text', getreg('+'))
+  call assert_equal('food for clipboard test', getline(1))
+  normal ggviw"+p
+  call assert_equal('food', getreg('+'))
+  call assert_equal('text for clipboard test', getline(1))
+
+  " Test for auto copying visually selected text to clipboard register
+  call setline(1, "text for clipboard test")
+  let @* = ''
+  set clipboard=autoselect
+  normal ggwwviwy
+  call assert_equal('clipboard', @*)
+
+  " Test for auto copying visually selected text to selection register
+  let @+ = ''
+  set clipboard=autoselectplus
+  normal ggwviwy
+  call assert_equal('for', @+)
+
+  set clipboard&vim
+  bwipe!
+endfunc
+
+" Test unnamed for both clipboard registers (* and +)
+func Test_clipboard_regs_both_unnamed()
+  CheckNotGui
+  CheckFeature clipboard_working
+  CheckTwoClipboards
+
+  let @* = 'xxx'
+  let @+ = 'xxx'
+
+  new
+
+  set clipboard=unnamed,unnamedplus
+  call setline(1, ['foo', 'bar'])
+
+  " op_yank copies to both
+  :1
+  :normal yw
+  call assert_equal('foo', getreg('*'))
+  call assert_equal('foo', getreg('+'))
+
+  " op_delete only copies to '+'
+  :2
+  :normal dw
+  call assert_equal('foo', getreg('*'))
+  call assert_equal('bar', getreg('+'))
+
+  set clipboard&vim
+  bwipe!
+endfunc
+
+" Test for restarting the current mode (insert or virtual replace) after
+" executing the contents of a register
+func Test_put_reg_restart_mode()
+  new
+  call append(0, 'editor')
+  normal gg
+  let @r = "ivim \<Esc>"
+  call feedkeys("i\<C-O>@r\<C-R>=mode()\<CR>", 'xt')
+  call assert_equal('vimi editor', getline(1))
+
+  call setline(1, 'editor')
+  normal gg
+  call feedkeys("gR\<C-O>@r\<C-R>=mode()\<CR>", 'xt')
+  call assert_equal('vimReditor', getline(1))
+
+  bwipe!
+endfunc
+
+" Test for executing a register using :@ command
+func Test_execute_register()
+  call setreg('r', [])
+  call assert_beeps('@r')
+  let i = 1
+  let @q = 'let i+= 1'
+  @q
+  @
+  call assert_equal(3, i)
+
+  " try to execute expression register and use a backspace to cancel it
+  new
+  call feedkeys("@=\<BS>ax\<CR>y", 'xt')
+  call assert_equal(['x', 'y'], getline(1, '$'))
+  close!
+
+  " cannot execute a register in operator pending mode
+  call assert_beeps('normal! c@r')
+endfunc
+
+" Test for getting register info
+func Test_get_reginfo()
+  enew
+  call setline(1, ['foo', 'bar'])
+
+  exe 'norm! "zyy'
+  let info = getreginfo('"')
+  call assert_equal('z', info.points_to)
+  call setreg('y', 'baz')
+  call assert_equal('z', getreginfo('').points_to)
+  call setreg('y', { 'isunnamed': v:true })
+  call assert_equal('y', getreginfo('"').points_to)
+
+  exe '$put'
+  call assert_equal(getreg('y'), getline(3))
+  call setreg('', 'qux')
+  call assert_equal('0', getreginfo('').points_to)
+  call setreg('x', 'quux')
+  call assert_equal('0', getreginfo('').points_to)
+
+  let info = getreginfo('')
+  call assert_equal(getreg('', 1, 1), info.regcontents)
+  call assert_equal(getregtype(''), info.regtype)
+
+  exe "norm! 0\<c-v>e" .. '"zy'
+  let info = getreginfo('z')
+  call assert_equal(getreg('z', 1, 1), info.regcontents)
+  call assert_equal(getregtype('z'), info.regtype)
+  call assert_equal(1, +info.isunnamed)
+
+  let info = getreginfo('"')
+  call assert_equal('z', info.points_to)
+
+  let @a="a1b2"
+  nnoremap <F2> <Cmd>let g:RegInfo = getreginfo()<CR>
+  exe "normal \"a\<F2>"
+  call assert_equal({'regcontents': ['a1b2'], 'isunnamed': v:false,
+        \ 'regtype': 'v'}, g:RegInfo)
+  nunmap <F2>
+  unlet g:RegInfo
+
+  " The type of "isunnamed" was VAR_SPECIAL but should be VAR_BOOL.  Can only
+  " be noticed when using json_encod().
+  call setreg('a', 'foo')
+  let reginfo = getreginfo('a')
+  let expected = #{regcontents: ['foo'], isunnamed: v:false, regtype: 'v'}
+  call assert_equal(json_encode(expected), json_encode(reginfo))
+
+  bwipe!
+endfunc
+
+" Test for restoring register with dict from getreginfo
+func Test_set_register_dict()
+  enew!
+
+  call setreg('"', #{ regcontents: ['one', 'two'],
+        \ regtype: 'V', points_to: 'z' })
+  call assert_equal(['one', 'two'], getreg('"', 1, 1))
+  let info = getreginfo('"')
+  call assert_equal('z', info.points_to)
+  call assert_equal('V', info.regtype)
+  call assert_equal(1, +getreginfo('z').isunnamed)
+
+  call setreg('x', #{ regcontents: ['three', 'four'],
+        \ regtype: 'v', isunnamed: v:true })
+  call assert_equal(['three', 'four'], getreg('"', 1, 1))
+  let info = getreginfo('"')
+  call assert_equal('x', info.points_to)
+  call assert_equal('v', info.regtype)
+  call assert_equal(1, +getreginfo('x').isunnamed)
+
+  call setreg('y', #{ regcontents: 'five',
+        \ regtype: "\<c-v>", isunnamed: v:false })
+  call assert_equal("\<c-v>4", getreginfo('y').regtype)
+  call assert_equal(0, +getreginfo('y').isunnamed)
+  call assert_equal(['three', 'four'], getreg('"', 1, 1))
+  call assert_equal('x', getreginfo('"').points_to)
+
+  call setreg('"', #{ regcontents: 'six' })
+  call assert_equal('0', getreginfo('"').points_to)
+  call assert_equal(1, +getreginfo('0').isunnamed)
+  call assert_equal(['six'], getreginfo('0').regcontents)
+  call assert_equal(['six'], getreginfo('"').regcontents)
+
+  let @x = 'one'
+  call setreg('x', {})
+  call assert_equal(1, len(split(execute('reg x'), '\n')))
+
+  call assert_fails("call setreg('0', #{regtype: 'V'}, 'v')", 'E118:')
+  call assert_fails("call setreg('0', #{regtype: 'X'})", 'E475:')
+  call assert_fails("call setreg('0', #{regtype: 'vy'})", 'E475:')
+
+  bwipe!
+endfunc
+
+func Test_v_register()
+  enew
+  call setline(1, 'nothing')
+
+  func s:Put()
+    let s:register = v:register
+    exec 'normal! "' .. v:register .. 'P'
+  endfunc
+  nnoremap <buffer> <plug>(test) :<c-u>call s:Put()<cr>
+  nmap <buffer> S <plug>(test)
+
+  let @z = "testz\n"
+  let @" = "test@\n"
+
+  let s:register = ''
+  call feedkeys('"_ddS', 'mx')
+  call assert_equal('test@', getline('.'))  " fails before 8.2.0929
+  call assert_equal('"', s:register)        " fails before 8.2.0929
+
+  let s:register = ''
+  call feedkeys('"zS', 'mx')
+  call assert_equal('z', s:register)
+
+  let s:register = ''
+  call feedkeys('"zSS', 'mx')
+  call assert_equal('"', s:register)
+
+  let s:register = ''
+  call feedkeys('"_S', 'mx')
+  call assert_equal('_', s:register)
+
+  let s:register = ''
+  normal "_ddS
+  call assert_equal('"', s:register)        " fails before 8.2.0929
+  call assert_equal('test@', getline('.'))  " fails before 8.2.0929
+
+  let s:register = ''
+  execute 'normal "z:call' "s:Put()\n"
+  call assert_equal('z', s:register)
+  call assert_equal('testz', getline('.'))
+
+  " Test operator and omap
+  let @b = 'testb'
+  func s:OpFunc(...)
+    let s:register2 = v:register
+  endfunc
+  set opfunc=s:OpFunc
+
+  normal "bg@l
+  normal S
+  call assert_equal('"', s:register)        " fails before 8.2.0929
+  call assert_equal('b', s:register2)
+
+  func s:Motion()
+    let s:register1 = v:register
+    normal! l
+  endfunc
+  onoremap <buffer> Q :<c-u>call s:Motion()<cr>
+
+  normal "bg@Q
+  normal S
+  call assert_equal('"', s:register)
+  call assert_equal('b', s:register1)
+  call assert_equal('"', s:register2)
+
+  set opfunc&
+  bwipe!
+endfunc
+
+" Test for executing the contents of a register as an Ex command with line
+" continuation.
+func Test_execute_reg_as_ex_cmd()
+  " Line continuation with just two lines
+  let code =<< trim END
+    let l = [
+      \ 1]
+  END
+  let @r = code->join("\n")
+  let l = []
+  @r
+  call assert_equal([1], l)
+
+  " Line continuation with more than two lines
+  let code =<< trim END
+    let l = [
+      \ 1,
+      \ 2,
+      \ 3]
+  END
+  let @r = code->join("\n")
+  let l = []
+  @r
+  call assert_equal([1, 2, 3], l)
+
+  " use comments interspersed with code
+  let code =<< trim END
+    let l = [
+      "\ one
+      \ 1,
+      "\ two
+      \ 2,
+      "\ three
+      \ 3]
+  END
+  let @r = code->join("\n")
+  let l = []
+  @r
+  call assert_equal([1, 2, 3], l)
+
+  " use line continuation in the middle
+  let code =<< trim END
+    let a = "one"
+    let l = [
+      \ 1,
+      \ 2]
+    let b = "two"
+  END
+  let @r = code->join("\n")
+  let l = []
+  @r
+  call assert_equal([1, 2], l)
+  call assert_equal("one", a)
+  call assert_equal("two", b)
+
+  " only one line with a \
+  let @r = "\\let l = 1"
+  call assert_fails('@r', 'E10:')
+
+  " only one line with a "\
+  let @r = '   "\ let i = 1'
+  @r
+  call assert_false(exists('i'))
+
+  " first line also begins with a \
+  let @r = "\\let l = [\n\\ 1]"
+  call assert_fails('@r', 'E10:')
+
+  " Test with a large number of lines
+  let @r = "let str = \n"
+  let @r ..= repeat("  \\ 'abcdefghijklmnopqrstuvwxyz' ..\n", 312)
+  let @r ..= '  \ ""'
+  @r
+  call assert_equal(repeat('abcdefghijklmnopqrstuvwxyz', 312), str)
+endfunc
+
+" Test for clipboard registers with ASCII NUL
+func Test_clipboard_nul()
+  CheckFeature clipboard_working
+  new
+
+  " Test for putting ASCII NUL into the clipboard
+  set clipboard=unnamed
+  call append(0, "\ntest")
+  normal ggyyp
+  call assert_equal("^@test^@", strtrans(getreg('*')))
+  call assert_equal(getline(1), getline(2))
+  let b = split(execute(":reg *"), "\n")
+  call assert_match('"\*\s*\^@test\^J',b[1])
+
+  set clipboard&vim
+  bwipe!
+endfunc
+
+func Test_ve_blockpaste()
+  new
+  set ve=all
+  0put =['QWERTZ','ASDFGH']
+  call cursor(1,1)
+  exe ":norm! \<C-V>3ljdP"
+  call assert_equal(1, col('.'))
+  call assert_equal(getline(1, 2), ['QWERTZ', 'ASDFGH'])
+  call cursor(1,1)
+  exe ":norm! \<C-V>3ljd"
+  call cursor(1,1)
+  norm! $3lP
+  call assert_equal(5, col('.'))
+  call assert_equal(getline(1, 2), ['TZ  QWER', 'GH  ASDF'])
+  set ve&vim
+  bwipe!
+endfunc
+
+func Test_insert_small_delete()
+  new
+  call setline(1, ['foo foobar bar'])
+  call cursor(1,1)
+  exe ":norm! ciw'\<C-R>-'"
+  call assert_equal("'foo' foobar bar", getline(1))
+  exe ":norm! w.w."
+  call assert_equal("'foo' 'foobar' 'bar'", getline(1))
+  bwipe!
+endfunc
+
+" Record in insert mode using CTRL-O
+func Test_record_in_insert_mode()
+  new
+  let @r = ''
+  call setline(1, ['foo'])
+  call feedkeys("i\<C-O>qrbaz\<C-O>q", 'xt')
+  call assert_equal('baz', @r)
+  bwipe!
+endfunc
+
+func Test_record_in_select_mode()
+  new
+  call setline(1, 'text')
+  sil norm q00
+  sil norm q
+  call assert_equal('0ext', getline(1))
+
+  %delete
+  let @r = ''
+  call setline(1, ['abc', 'abc', 'abc'])
+  smap <F2> <Right><Right>,
+  call feedkeys("qrgh\<F2>Dk\<Esc>q", 'xt')
+  call assert_equal("gh\<F2>Dk\<Esc>", @r)
+  norm j0@rj0@@
+  call assert_equal([',Dk', ',Dk', ',Dk'], getline(1, 3))
+  sunmap <F2>
+
+  bwipe!
+endfunc
+
+" mapping that ends macro recording should be removed from recorded macro
+func Test_end_record_using_mapping()
+  call setline(1, 'aaa')
+  nnoremap s q
+  call feedkeys('safas', 'tx')
+  call assert_equal('fa', @a)
+  nunmap s
+
+  nnoremap xx q
+  call feedkeys('0xxafaxx', 'tx')
+  call assert_equal('fa', @a)
+  nunmap xx
+
+  nnoremap xsx q
+  call feedkeys('0qafaxsx', 'tx')
+  call assert_equal('fa', @a)
+  nunmap xsx
+
+  bwipe!
+endfunc
+
+func Test_end_reg_executing()
+  nnoremap s <Nop>
+  let @a = 's'
+  call feedkeys("@aqaq\<Esc>", 'tx')
+  call assert_equal('', @a)
+  call assert_equal('', getline(1))
+
+  call setline(1, 'aaa')
+  nnoremap s qa
+  let @a = 'fa'
+  call feedkeys("@asq\<Esc>", 'tx')
+  call assert_equal('', @a)
+  call assert_equal('aaa', getline(1))
+
+  nunmap s
+  bwipe!
+endfunc
+
+" This was causing a crash because y_append was ending up being NULL
+func Test_zero_y_append()
+  " Run in a separate Vim instance because changing 'encoding' may cause
+  " trouble for later tests.
+  let lines =<< trim END
+      d
+      silent ?n
+      next <sfile>
+      so
+      sil! norm 0V€PSP
+      set enc=latin1
+       
+  END
+  call writefile(lines, 'XTest_zero_y_append', 'D')
+  call RunVim([], [], '-u NONE -i NONE -e -s -S XTest_zero_y_append -c qa\!')
+endfunc
+
+" Make sure that y_append is correctly reset
+" and the previous register is working as expected
+func Test_register_y_append_reset()
+  new
+  call setline(1, ['1',
+    \ '2 ----------------------------------------------------',
+    \ '3',
+    \ '4',
+    \ '5 ----------------------------------------------------',
+    \ '6',
+    \ '7',
+    \ '8 ----------------------------------------------------',
+    \ '9',
+    \ '10 aaaaaaa 4.',
+    \ '11 Game Dbl-Figures Leaders:',
+    \ '12 Player Pts FG% 3P% FT% RB AS BL ST TO PF EFF',
+    \ '13 bbbbbbbbb 12 (50 /0 /67 )/ 7/ 3/ 0/ 2/ 3/ 4/+15',
+    \ '14 cccccc 12 (57 /67 /100)/ 2/ 1/ 1/ 0/ 1/ 3/+12',
+    \ '15 ddddddd 10 (63 /0 /0 )/ 1/ 3/ 0/ 3/ 5/ 3/ +9',
+    \ '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',
+    \ '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',
+    \ '18 4 3 6 3 2 3 3 4 3 3 7 3 1 4 6 -1 -1 +2 -1 -2',
+    \ '19 F 13 19 5 10 4 17 22 9 14 32 13 4 20 17 -1 -13 -4 -3 -3 +5'])
+  11
+  exe "norm! \"a5dd"
+  norm! j
+  exe "norm! \"bY"
+  norm! 2j
+  exe "norm! \"BY"
+  norm! 4k
+  norm! 5dd
+  norm! 3k
+  " The next put should put the content of the unnamed register, not of
+  " register b!
+  norm! p
+  call assert_equal(['1',
+    \ '2 ----------------------------------------------------',
+    \ '3',
+    \ '4',
+    \ '5 ----------------------------------------------------',
+    \ '6',
+    \ '10 aaaaaaa 4.',
+    \ '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',
+    \ '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',
+    \ '18 4 3 6 3 2 3 3 4 3 3 7 3 1 4 6 -1 -1 +2 -1 -2',
+    \ '19 F 13 19 5 10 4 17 22 9 14 32 13 4 20 17 -1 -13 -4 -3 -3 +5',
+    \ '7',
+    \ '8 ----------------------------------------------------',
+    \ '9'], getline(1,'$'))
+  bwipe!
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab