Mercurial > vim
view src/testdir/test_registers.vim @ 33776:9503dc55b5ed v9.0.2108
patch 9.0.2108: [security]: overflow with count for :s command
Commit: https://github.com/vim/vim/commit/ac63787734fda2e294e477af52b3bd601517fa78
Author: Christian Brabandt <cb@256bit.org>
Date: Tue Nov 14 20:45:48 2023 +0100
patch 9.0.2108: [security]: overflow with count for :s command
Problem: [security]: overflow with count for :s command
Solution: Abort the :s command if the count is too large
If the count after the :s command is larger than what fits into a
(signed) long variable, abort with e_value_too_large.
Adds a test with INT_MAX as count and verify it correctly fails.
It seems the return value on Windows using mingw compiler wraps around,
so the initial test using :s/./b/9999999999999999999999999990 doesn't
fail there, since the count is wrapping around several times and finally
is no longer larger than 2147483647. So let's just use 2147483647 in the
test, which hopefully will always cause a failure
Signed-off-by: Christian Brabandt <cb@256bit.org>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Thu, 16 Nov 2023 22:15:10 +0100 |
parents | dfaddd6f039e |
children | 82e8284e60b7 |
line wrap: on
line source
" 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 " A mapping that ends recording should be removed from the recorded register. func Test_end_record_using_mapping() new 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 " Starting a new recording should work immediately after replaying a recording " that ends with a <Nop> mapping or a character search. func Test_end_reg_executing() new 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 " An operator-pending mode mapping shouldn't be applied to keys typed in " Insert mode immediately after a character search when replaying. func Test_replay_charsearch_omap() CheckFeature timers new call setline(1, 'foo[blah]') onoremap , k call timer_start(10, {-> feedkeys(",bar\<Esc>q", 't')}) call feedkeys('qrct[', 'xt!') call assert_equal(',bar[blah]', getline(1)) undo call assert_equal('foo[blah]', getline(1)) call feedkeys('@r', 'xt!') call assert_equal(',bar[blah]', getline(1)) ounmap , 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 0VPSP 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