1"
2" Tests for register operations
3"
4
5source check.vim
6source view_util.vim
7
8" This test must be executed first to check for empty and unset registers.
9func Test_aaa_empty_reg_test()
10  call assert_fails('normal @@', 'E748:')
11  call assert_fails('normal @%', 'E354:')
12  call assert_fails('normal @#', 'E354:')
13  call assert_fails('normal @!', 'E354:')
14  call assert_fails('normal @:', 'E30:')
15  call assert_fails('normal @.', 'E29:')
16  call assert_fails('put /', 'E35:')
17  call assert_fails('put .', 'E29:')
18endfunc
19
20func Test_yank_shows_register()
21    enew
22    set report=0
23    call setline(1, ['foo', 'bar'])
24    " Line-wise
25    exe 'norm! yy'
26    call assert_equal('1 line yanked', v:statusmsg)
27    exe 'norm! "zyy'
28    call assert_equal('1 line yanked into "z', v:statusmsg)
29    exe 'norm! yj'
30    call assert_equal('2 lines yanked', v:statusmsg)
31    exe 'norm! "zyj'
32    call assert_equal('2 lines yanked into "z', v:statusmsg)
33
34    " Block-wise
35    exe "norm! \<C-V>y"
36    call assert_equal('block of 1 line yanked', v:statusmsg)
37    exe "norm! \<C-V>\"zy"
38    call assert_equal('block of 1 line yanked into "z', v:statusmsg)
39    exe "norm! \<C-V>jy"
40    call assert_equal('block of 2 lines yanked', v:statusmsg)
41    exe "norm! \<C-V>j\"zy"
42    call assert_equal('block of 2 lines yanked into "z', v:statusmsg)
43
44    bwipe!
45endfunc
46
47func Test_display_registers()
48    e file1
49    e file2
50    call setline(1, ['foo', 'bar'])
51    /bar
52    exe 'norm! y2l"axx'
53    call feedkeys("i\<C-R>=2*4\n\<esc>")
54    call feedkeys(":ls\n", 'xt')
55
56    let a = execute('display')
57    let b = execute('registers')
58
59    call assert_equal(a, b)
60    call assert_match('^\nType Name Content\n'
61          \ .         '  c  ""   a\n'
62          \ .         '  c  "0   ba\n'
63          \ .         '  c  "a   b\n'
64          \ .         '.*'
65          \ .         '  c  "-   a\n'
66          \ .         '.*'
67          \ .         '  c  ":   ls\n'
68          \ .         '  c  "%   file2\n'
69          \ .         '  c  "#   file1\n'
70          \ .         '  c  "/   bar\n'
71          \ .         '  c  "=   2\*4', a)
72
73    let a = execute('registers a')
74    call assert_match('^\nType Name Content\n'
75          \ .         '  c  "a   b', a)
76
77    let a = execute('registers :')
78    call assert_match('^\nType Name Content\n'
79          \ .         '  c  ":   ls', a)
80
81    bwipe!
82endfunc
83
84func Test_register_one()
85  " delete a line goes into register one
86  new
87  call setline(1, "one")
88  normal dd
89  call assert_equal("one\n", @1)
90
91  " delete a word does not change register one, does change "-
92  call setline(1, "two")
93  normal de
94  call assert_equal("one\n", @1)
95  call assert_equal("two", @-)
96
97  " delete a word with a register does not change register one
98  call setline(1, "three")
99  normal "ade
100  call assert_equal("three", @a)
101  call assert_equal("one\n", @1)
102
103  " delete a word with register DOES change register one with one of a list of
104  " operators
105  " %
106  call setline(1, ["(12)3"])
107  normal "ad%
108  call assert_equal("(12)", @a)
109  call assert_equal("(12)", @1)
110
111  " (
112  call setline(1, ["first second"])
113  normal $"ad(
114  call assert_equal("first secon", @a)
115  call assert_equal("first secon", @1)
116
117  " )
118  call setline(1, ["First Second."])
119  normal gg0"ad)
120  call assert_equal("First Second.", @a)
121  call assert_equal("First Second.", @1)
122
123  " `
124  call setline(1, ["start here."])
125  normal gg0fhmx0"ad`x
126  call assert_equal("start ", @a)
127  call assert_equal("start ", @1)
128
129  " /
130  call setline(1, ["searchX"])
131  exe "normal gg0\"ad/X\<CR>"
132  call assert_equal("search", @a)
133  call assert_equal("search", @1)
134
135  " ?
136  call setline(1, ["Ysearch"])
137  exe "normal gg$\"ad?Y\<CR>"
138  call assert_equal("Ysearc", @a)
139  call assert_equal("Ysearc", @1)
140
141  " n
142  call setline(1, ["Ynext"])
143  normal gg$"adn
144  call assert_equal("Ynex", @a)
145  call assert_equal("Ynex", @1)
146
147  " N
148  call setline(1, ["prevY"])
149  normal gg0"adN
150  call assert_equal("prev", @a)
151  call assert_equal("prev", @1)
152
153  " }
154  call setline(1, ["one", ""])
155  normal gg0"ad}
156  call assert_equal("one\n", @a)
157  call assert_equal("one\n", @1)
158
159  " {
160  call setline(1, ["", "two"])
161  normal 2G$"ad{
162  call assert_equal("\ntw", @a)
163  call assert_equal("\ntw", @1)
164
165  bwipe!
166endfunc
167
168func Test_recording_status_in_ex_line()
169  norm qx
170  redraw!
171  call assert_equal('recording @x', Screenline(&lines))
172  set shortmess=q
173  redraw!
174  call assert_equal('recording', Screenline(&lines))
175  set shortmess&
176  norm q
177  redraw!
178  call assert_equal('', Screenline(&lines))
179endfunc
180
181" Check that replaying a typed sequence does not use an Esc and following
182" characters as an escape sequence.
183func Test_recording_esc_sequence()
184  new
185  try
186    let save_F2 = &t_F2
187  catch
188  endtry
189  let t_F2 = "\<Esc>OQ"
190  call feedkeys("qqiTest\<Esc>", "xt")
191  call feedkeys("OQuirk\<Esc>q", "xt")
192  call feedkeys("Go\<Esc>@q", "xt")
193  call assert_equal(['Quirk', 'Test', 'Quirk', 'Test'], getline(1, 4))
194  bwipe!
195  if exists('save_F2')
196    let &t_F2 = save_F2
197  else
198    set t_F2=
199  endif
200endfunc
201
202" Test for executing the last used register (@)
203func Test_last_used_exec_reg()
204  " Test for the @: command
205  let a = ''
206  call feedkeys(":let a ..= 'Vim'\<CR>", 'xt')
207  normal @:
208  call assert_equal('VimVim', a)
209
210  " Test for the @= command
211  let x = ''
212  let a = ":let x ..= 'Vim'\<CR>"
213  exe "normal @=a\<CR>"
214  normal @@
215  call assert_equal('VimVim', x)
216
217  " Test for the @. command
218  let a = ''
219  call feedkeys("i:let a ..= 'Edit'\<CR>", 'xt')
220  normal @.
221  normal @@
222  call assert_equal('EditEdit', a)
223
224  " Test for repeating the last command-line in visual mode
225  call append(0, 'register')
226  normal gg
227  let @r = ''
228  call feedkeys("v:yank R\<CR>", 'xt')
229  call feedkeys("v@:", 'xt')
230  call assert_equal("\nregister\nregister\n", @r)
231
232  enew!
233endfunc
234
235func Test_get_register()
236  enew
237  edit Xfile1
238  edit Xfile2
239  call assert_equal('Xfile2', getreg('%'))
240  call assert_equal('Xfile1', getreg('#'))
241
242  call feedkeys("iTwo\<Esc>", 'xt')
243  call assert_equal('Two', getreg('.'))
244  call assert_equal('', getreg('_'))
245  call assert_beeps('normal ":yy')
246  call assert_beeps('normal "%yy')
247  call assert_beeps('normal ".yy')
248
249  call assert_equal('', getreg("\<C-F>"))
250  call assert_equal('', getreg("\<C-W>"))
251  call assert_equal('', getreg("\<C-L>"))
252  " Change the last used register to '"' for the next test
253  normal! ""yy
254  let @" = 'happy'
255  call assert_equal('happy', getreg())
256  call assert_equal('happy', getreg(''))
257
258  call assert_equal('', getregtype('!'))
259  call assert_fails('echo getregtype([])', 'E730:')
260  call assert_equal('v', getregtype())
261  call assert_equal('v', getregtype(''))
262
263  " Test for inserting an invalid register content
264  call assert_beeps('exe "normal i\<C-R>!"')
265
266  " Test for inserting a register with multiple lines
267  call deletebufline('', 1, '$')
268  call setreg('r', ['a', 'b'])
269  exe "normal i\<C-R>r"
270  call assert_equal(['a', 'b', ''], getline(1, '$'))
271
272  " Test for inserting a multi-line register in the command line
273  call feedkeys(":\<C-R>r\<Esc>", 'xt')
274  call assert_equal("a\rb\r", histget(':', -1))
275
276  call assert_fails('let r = getreg("=", [])', 'E745:')
277  call assert_fails('let r = getreg("=", 1, [])', 'E745:')
278  enew!
279endfunc
280
281func Test_set_register()
282  call assert_fails("call setreg('#', 200)", 'E86:')
283
284  edit Xfile_alt_1
285  let b1 = bufnr('')
286  edit Xfile_alt_2
287  let b2 = bufnr('')
288  edit Xfile_alt_3
289  let b3 = bufnr('')
290  call setreg('#', 'alt_1')
291  call assert_equal('Xfile_alt_1', getreg('#'))
292  call setreg('#', b2)
293  call assert_equal('Xfile_alt_2', getreg('#'))
294
295  let ab = 'regwrite'
296  call setreg('=', '')
297  call setreg('=', 'a', 'a')
298  call setreg('=', 'b', 'a')
299  call assert_equal('regwrite', getreg('='))
300
301  " Test for setting a list of lines to special registers
302  call setreg('/', [])
303  call assert_equal('', @/)
304  call setreg('=', [])
305  call assert_equal('', @=)
306  call assert_fails("call setreg('/', ['a', 'b'])", 'E883:')
307  call assert_fails("call setreg('=', ['a', 'b'])", 'E883:')
308  call assert_equal(0, setreg('_', ['a', 'b']))
309
310  " Test for recording to a invalid register
311  call assert_beeps('normal q$')
312
313  " Appending to a register when recording
314  call append(0, "text for clipboard test")
315  normal gg
316  call feedkeys('qrllq', 'xt')
317  call feedkeys('qRhhq', 'xt')
318  call assert_equal('llhh', getreg('r'))
319
320  " Appending a list of characters to a register from different lines
321  let @r = ''
322  call append(0, ['abcdef', '123456'])
323  normal gg"ry3l
324  call cursor(2, 4)
325  normal "Ry3l
326  call assert_equal('abc456', @r)
327
328  " Test for gP with multiple lines selected using characterwise motion
329  %delete
330  call append(0, ['vim editor', 'vim editor'])
331  let @r = ''
332  exe "normal ggwy/vim /e\<CR>gP"
333  call assert_equal(['vim editor', 'vim editor', 'vim editor'], getline(1, 3))
334
335  " Test for gP with . register
336  %delete
337  normal iabc
338  normal ".gp
339  call assert_equal('abcabc', getline(1))
340  normal 0".gP
341  call assert_equal('abcabcabc', getline(1))
342
343  let @"=''
344  call setreg('', '1')
345  call assert_equal('1', @")
346  call setreg('@', '2')
347  call assert_equal('2', @")
348
349  enew!
350endfunc
351
352" Test for clipboard registers (* and +)
353func Test_clipboard_regs()
354  CheckNotGui
355  CheckFeature clipboard_working
356
357  new
358  call append(0, "text for clipboard test")
359  normal gg"*yiw
360  call assert_equal('text', getreg('*'))
361  normal gg2w"+yiw
362  call assert_equal('clipboard', getreg('+'))
363
364  " Test for replacing the clipboard register contents
365  set clipboard=unnamed
366  let @* = 'food'
367  normal ggviw"*p
368  call assert_equal('text', getreg('*'))
369  call assert_equal('food for clipboard test', getline(1))
370  normal ggviw"*p
371  call assert_equal('food', getreg('*'))
372  call assert_equal('text for clipboard test', getline(1))
373
374  " Test for replacing the selection register contents
375  set clipboard=unnamedplus
376  let @+ = 'food'
377  normal ggviw"+p
378  call assert_equal('text', getreg('+'))
379  call assert_equal('food for clipboard test', getline(1))
380  normal ggviw"+p
381  call assert_equal('food', getreg('+'))
382  call assert_equal('text for clipboard test', getline(1))
383
384  " Test for auto copying visually selected text to clipboard register
385  call setline(1, "text for clipboard test")
386  let @* = ''
387  set clipboard=autoselect
388  normal ggwwviwy
389  call assert_equal('clipboard', @*)
390
391  " Test for auto copying visually selected text to selection register
392  let @+ = ''
393  set clipboard=autoselectplus
394  normal ggwviwy
395  call assert_equal('for', @+)
396
397  set clipboard&vim
398  bwipe!
399endfunc
400
401" Test for restarting the current mode (insert or virtual replace) after
402" executing the contents of a register
403func Test_put_reg_restart_mode()
404  new
405  call append(0, 'editor')
406  normal gg
407  let @r = "ivim \<Esc>"
408  call feedkeys("i\<C-O>@r\<C-R>=mode()\<CR>", 'xt')
409  call assert_equal('vimi editor', getline(1))
410
411  call setline(1, 'editor')
412  normal gg
413  call feedkeys("gR\<C-O>@r\<C-R>=mode()\<CR>", 'xt')
414  call assert_equal('vimReditor', getline(1))
415
416  bwipe!
417endfunc
418
419" Test for executing a register using :@ command
420func Test_execute_register()
421  call setreg('r', [])
422  call assert_beeps('@r')
423  let i = 1
424  let @q = 'let i+= 1'
425  @q
426  @
427  call assert_equal(3, i)
428
429  " cannot execute a register in operator pending mode
430  call assert_beeps('normal! c@r')
431endfunc
432
433" Test for getting register info
434func Test_get_reginfo()
435  enew
436  call setline(1, ['foo', 'bar'])
437
438  exe 'norm! "zyy'
439  let info = getreginfo('"')
440  call assert_equal('z', info.points_to)
441  call setreg('y', 'baz')
442  call assert_equal('z', getreginfo('').points_to)
443  call setreg('y', { 'isunnamed': v:true })
444  call assert_equal('y', getreginfo('"').points_to)
445
446  exe '$put'
447  call assert_equal(getreg('y'), getline(3))
448  call setreg('', 'qux')
449  call assert_equal('0', getreginfo('').points_to)
450  call setreg('x', 'quux')
451  call assert_equal('0', getreginfo('').points_to)
452
453  let info = getreginfo('')
454  call assert_equal(getreg('', 1, 1), info.regcontents)
455  call assert_equal(getregtype(''), info.regtype)
456
457  exe "norm! 0\<c-v>e" .. '"zy'
458  let info = getreginfo('z')
459  call assert_equal(getreg('z', 1, 1), info.regcontents)
460  call assert_equal(getregtype('z'), info.regtype)
461  call assert_equal(1, +info.isunnamed)
462
463  let info = getreginfo('"')
464  call assert_equal('z', info.points_to)
465
466  bwipe!
467endfunc
468
469" Test for restoring register with dict from getreginfo
470func Test_set_register_dict()
471  enew!
472
473  call setreg('"', #{ regcontents: ['one', 'two'],
474        \ regtype: 'V', points_to: 'z' })
475  call assert_equal(['one', 'two'], getreg('"', 1, 1))
476  let info = getreginfo('"')
477  call assert_equal('z', info.points_to)
478  call assert_equal('V', info.regtype)
479  call assert_equal(1, +getreginfo('z').isunnamed)
480
481  call setreg('x', #{ regcontents: ['three', 'four'],
482        \ regtype: 'v', isunnamed: v:true })
483  call assert_equal(['three', 'four'], getreg('"', 1, 1))
484  let info = getreginfo('"')
485  call assert_equal('x', info.points_to)
486  call assert_equal('v', info.regtype)
487  call assert_equal(1, +getreginfo('x').isunnamed)
488
489  call setreg('y', #{ regcontents: 'five',
490        \ regtype: "\<c-v>", isunnamed: v:false })
491  call assert_equal("\<c-v>4", getreginfo('y').regtype)
492  call assert_equal(0, +getreginfo('y').isunnamed)
493  call assert_equal(['three', 'four'], getreg('"', 1, 1))
494  call assert_equal('x', getreginfo('"').points_to)
495
496  call setreg('"', #{ regcontents: 'six' })
497  call assert_equal('0', getreginfo('"').points_to)
498  call assert_equal(1, +getreginfo('0').isunnamed)
499  call assert_equal(['six'], getreginfo('0').regcontents)
500  call assert_equal(['six'], getreginfo('"').regcontents)
501
502  let @x = 'one'
503  call setreg('x', {})
504  call assert_equal(1, len(split(execute('reg x'), '\n')))
505
506  call assert_fails("call setreg('0', #{regtype: 'V'}, 'v')", 'E118:')
507  call assert_fails("call setreg('0', #{regtype: 'X'})", 'E475:')
508  call assert_fails("call setreg('0', #{regtype: 'vy'})", 'E475:')
509
510  bwipe!
511endfunc
512
513func Test_v_register()
514  enew
515  call setline(1, 'nothing')
516
517  func s:Put()
518    let s:register = v:register
519    exec 'normal! "' .. v:register .. 'P'
520  endfunc
521  nnoremap <buffer> <plug>(test) :<c-u>call s:Put()<cr>
522  nmap <buffer> S <plug>(test)
523
524  let @z = "testz\n"
525  let @" = "test@\n"
526
527  let s:register = ''
528  call feedkeys('"_ddS', 'mx')
529  call assert_equal('test@', getline('.'))  " fails before 8.2.0929
530  call assert_equal('"', s:register)        " fails before 8.2.0929
531
532  let s:register = ''
533  call feedkeys('"zS', 'mx')
534  call assert_equal('z', s:register)
535
536  let s:register = ''
537  call feedkeys('"zSS', 'mx')
538  call assert_equal('"', s:register)
539
540  let s:register = ''
541  call feedkeys('"_S', 'mx')
542  call assert_equal('_', s:register)
543
544  let s:register = ''
545  normal "_ddS
546  call assert_equal('"', s:register)        " fails before 8.2.0929
547  call assert_equal('test@', getline('.'))  " fails before 8.2.0929
548
549  let s:register = ''
550  execute 'normal "z:call' "s:Put()\n"
551  call assert_equal('z', s:register)
552  call assert_equal('testz', getline('.'))
553
554  " Test operator and omap
555  let @b = 'testb'
556  func s:OpFunc(...)
557    let s:register2 = v:register
558  endfunc
559  set opfunc=s:OpFunc
560
561  normal "bg@l
562  normal S
563  call assert_equal('"', s:register)        " fails before 8.2.0929
564  call assert_equal('b', s:register2)
565
566  func s:Motion()
567    let s:register1 = v:register
568    normal! l
569  endfunc
570  onoremap <buffer> Q :<c-u>call s:Motion()<cr>
571
572  normal "bg@Q
573  normal S
574  call assert_equal('"', s:register)
575  call assert_equal('b', s:register1)
576  call assert_equal('"', s:register2)
577
578  set opfunc&
579  bwipe!
580endfunc
581
582" Test for executing the contents of a register as an Ex command with line
583" continuation.
584func Test_execute_reg_as_ex_cmd()
585  " Line continuation with just two lines
586  let code =<< trim END
587    let l = [
588      \ 1]
589  END
590  let @r = code->join("\n")
591  let l = []
592  @r
593  call assert_equal([1], l)
594
595  " Line continuation with more than two lines
596  let code =<< trim END
597    let l = [
598      \ 1,
599      \ 2,
600      \ 3]
601  END
602  let @r = code->join("\n")
603  let l = []
604  @r
605  call assert_equal([1, 2, 3], l)
606
607  " use comments interspersed with code
608  let code =<< trim END
609    let l = [
610      "\ one
611      \ 1,
612      "\ two
613      \ 2,
614      "\ three
615      \ 3]
616  END
617  let @r = code->join("\n")
618  let l = []
619  @r
620  call assert_equal([1, 2, 3], l)
621
622  " use line continuation in the middle
623  let code =<< trim END
624    let a = "one"
625    let l = [
626      \ 1,
627      \ 2]
628    let b = "two"
629  END
630  let @r = code->join("\n")
631  let l = []
632  @r
633  call assert_equal([1, 2], l)
634  call assert_equal("one", a)
635  call assert_equal("two", b)
636
637  " only one line with a \
638  let @r = "\\let l = 1"
639  call assert_fails('@r', 'E10:')
640
641  " only one line with a "\
642  let @r = '   "\ let i = 1'
643  @r
644  call assert_false(exists('i'))
645
646  " first line also begins with a \
647  let @r = "\\let l = [\n\\ 1]"
648  call assert_fails('@r', 'E10:')
649
650  " Test with a large number of lines
651  let @r = "let str = \n"
652  let @r ..= repeat("  \\ 'abcdefghijklmnopqrstuvwxyz' ..\n", 312)
653  let @r ..= '  \ ""'
654  @r
655  call assert_equal(repeat('abcdefghijklmnopqrstuvwxyz', 312), str)
656endfunc
657
658" Test for clipboard registers with ASCII NUL
659func Test_clipboard_nul()
660  CheckFeature clipboard_working
661  new
662
663  " Test for putting ASCII NUL into the clipboard
664  set clipboard=unnamed
665  call append(0, "\ntest")
666  normal ggyyp
667  call assert_equal("^@test^@", strtrans(getreg('*')))
668  call assert_equal(getline(1), getline(2))
669  let b = split(execute(":reg *"), "\n")
670  call assert_match('"\*\s*\^@test\^J',b[1])
671
672  set clipboard&vim
673  bwipe!
674endfunc
675
676func Test_ve_blockpaste()
677  new
678  set ve=all
679  0put =['QWERTZ','ASDFGH']
680  call cursor(1,1)
681  exe ":norm! \<C-V>3ljdP"
682  call assert_equal(1, col('.'))
683  call assert_equal(getline(1, 2), ['QWERTZ', 'ASDFGH'])
684  call cursor(1,1)
685  exe ":norm! \<C-V>3ljd"
686  call cursor(1,1)
687  norm! $3lP
688  call assert_equal(5, col('.'))
689  call assert_equal(getline(1, 2), ['TZ  QWER', 'GH  ASDF'])
690  set ve&vim
691  bwipe!
692endfunc
693
694" vim: shiftwidth=2 sts=2 expandtab
695