xref: /vim-8.2.3635/src/testdir/test_viminfo.vim (revision f573c6e1)
1" Test for reading and writing .viminfo
2
3source check.vim
4source term_util.vim
5source shared.vim
6
7func Test_viminfo_read_and_write()
8  " First clear 'history', so that "hislen" is zero.  Then set it again,
9  " simulating Vim starting up.
10  set history=0
11  wviminfo Xviminfo
12  set history=1000
13
14  call histdel(':')
15  let @/=''
16  let lines = [
17	\ '# comment line',
18	\ '*encoding=utf-8',
19	\ '~MSle0~/asdf',
20	\ '|copied as-is',
21	\ '|and one more',
22	\ ]
23  call writefile(lines, 'Xviminfo')
24  rviminfo Xviminfo
25  call assert_equal('asdf', @/)
26
27  wviminfo Xviminfo
28  let lines = readfile('Xviminfo')
29  let done = 0
30  for line in lines
31    if line[0] == '|' && line !~ '^|[234],' && line !~ '^|<'
32      if done == 0
33	call assert_equal('|1,4', line)
34      elseif done == 1
35	call assert_equal('|copied as-is', line)
36      elseif done == 2
37	call assert_equal('|and one more', line)
38      endif
39      let done += 1
40    endif
41  endfor
42  call assert_equal(3, done)
43
44  call delete('Xviminfo')
45endfunc
46
47func Test_global_vars()
48  let g:MY_GLOBAL_STRING = "Vim Editor"
49  let g:MY_GLOBAL_NUM = 345
50  let g:MY_GLOBAL_FLOAT = 3.14
51  let test_dict = {'foo': 1, 'bar': 0, 'longvarible': 1000}
52  let g:MY_GLOBAL_DICT = test_dict
53  " store a really long list, so line wrapping will occur in viminfo file
54  let test_list = range(1,100)
55  let g:MY_GLOBAL_LIST = test_list
56  let test_blob = 0z00112233445566778899aabbccddeeff
57  let g:MY_GLOBAL_BLOB = test_blob
58  let test_false = v:false
59  let g:MY_GLOBAL_FALSE = test_false
60  let test_true = v:true
61  let g:MY_GLOBAL_TRUE = test_true
62  let test_null = v:null
63  let g:MY_GLOBAL_NULL = test_null
64  let test_none = v:none
65  let g:MY_GLOBAL_NONE = test_none
66
67  set viminfo='100,<50,s10,h,!,nviminfo
68  wv! Xviminfo
69
70  unlet g:MY_GLOBAL_STRING
71  unlet g:MY_GLOBAL_NUM
72  unlet g:MY_GLOBAL_FLOAT
73  unlet g:MY_GLOBAL_DICT
74  unlet g:MY_GLOBAL_LIST
75  unlet g:MY_GLOBAL_BLOB
76  unlet g:MY_GLOBAL_FALSE
77  unlet g:MY_GLOBAL_TRUE
78  unlet g:MY_GLOBAL_NULL
79  unlet g:MY_GLOBAL_NONE
80
81  rv! Xviminfo
82  call assert_equal("Vim Editor", g:MY_GLOBAL_STRING)
83  call assert_equal(345, g:MY_GLOBAL_NUM)
84  call assert_equal(3.14, g:MY_GLOBAL_FLOAT)
85  call assert_equal(test_dict, g:MY_GLOBAL_DICT)
86  call assert_equal(test_list, g:MY_GLOBAL_LIST)
87  call assert_equal(test_blob, g:MY_GLOBAL_BLOB)
88  call assert_equal(test_false, g:MY_GLOBAL_FALSE)
89  call assert_equal(test_true, g:MY_GLOBAL_TRUE)
90  call assert_equal(test_null, g:MY_GLOBAL_NULL)
91  call assert_equal(test_none, g:MY_GLOBAL_NONE)
92
93  " When reading global variables from viminfo, if a variable cannot be
94  " modified, then the value should not be changed.
95  unlet g:MY_GLOBAL_STRING
96  unlet g:MY_GLOBAL_NUM
97  unlet g:MY_GLOBAL_FLOAT
98  unlet g:MY_GLOBAL_DICT
99  unlet g:MY_GLOBAL_LIST
100  unlet g:MY_GLOBAL_BLOB
101
102  const g:MY_GLOBAL_STRING = 'New Value'
103  const g:MY_GLOBAL_NUM = 987
104  const g:MY_GLOBAL_FLOAT = 1.16
105  const g:MY_GLOBAL_DICT = {'editor': 'vim'}
106  const g:MY_GLOBAL_LIST = [5, 7, 13]
107  const g:MY_GLOBAL_BLOB = 0zDEADBEEF
108  call assert_fails('rv! Xviminfo', 'E741:')
109  call assert_equal('New Value', g:MY_GLOBAL_STRING)
110  call assert_equal(987, g:MY_GLOBAL_NUM)
111  call assert_equal(1.16, g:MY_GLOBAL_FLOAT)
112  call assert_equal({'editor': 'vim'}, g:MY_GLOBAL_DICT)
113  call assert_equal([5, 7 , 13], g:MY_GLOBAL_LIST)
114  call assert_equal(0zDEADBEEF, g:MY_GLOBAL_BLOB)
115
116  unlet g:MY_GLOBAL_STRING
117  unlet g:MY_GLOBAL_NUM
118  unlet g:MY_GLOBAL_FLOAT
119  unlet g:MY_GLOBAL_DICT
120  unlet g:MY_GLOBAL_LIST
121  unlet g:MY_GLOBAL_BLOB
122
123  " Test for invalid values for a blob, list, dict in a viminfo file
124  call writefile([
125        \ "!GLOB_BLOB_1\tBLO\t123",
126        \ "!GLOB_BLOB_2\tBLO\t012",
127        \ "!GLOB_BLOB_3\tBLO\t0z1x",
128        \ "!GLOB_BLOB_4\tBLO\t0z12 ab",
129        \ "!GLOB_LIST_1\tLIS\t1 2",
130        \ "!GLOB_DICT_1\tDIC\t1 2"], 'Xviminfo')
131  call assert_fails('rv! Xviminfo', 'E488:')
132  call assert_equal('123', g:GLOB_BLOB_1)
133  call assert_equal(1, type(g:GLOB_BLOB_1))
134  call assert_equal('012', g:GLOB_BLOB_2)
135  call assert_equal(1, type(g:GLOB_BLOB_2))
136  call assert_equal('0z1x', g:GLOB_BLOB_3)
137  call assert_equal(1, type(g:GLOB_BLOB_3))
138  call assert_equal('0z12 ab', g:GLOB_BLOB_4)
139  call assert_equal(1, type(g:GLOB_BLOB_4))
140  call assert_equal('1 2', g:GLOB_LIST_1)
141  call assert_equal(1, type(g:GLOB_LIST_1))
142  call assert_equal('1 2', g:GLOB_DICT_1)
143  call assert_equal(1, type(g:GLOB_DICT_1))
144
145  call delete('Xviminfo')
146  set viminfo-=!
147endfunc
148
149func Test_global_vars_with_circular_reference()
150  let g:MY_GLOBAL_LIST = []
151  call add(g:MY_GLOBAL_LIST, g:MY_GLOBAL_LIST)
152  let g:MY_GLOBAL_DICT = {}
153  let g:MY_GLOBAL_DICT['self'] = g:MY_GLOBAL_DICT
154
155  set viminfo='100,<50,s10,h,!,nviminfo
156  wv! Xviminfo
157  call assert_equal(v:errmsg, '')
158
159  unlet g:MY_GLOBAL_LIST
160  unlet g:MY_GLOBAL_DICT
161
162  rv! Xviminfo
163  call assert_equal(v:errmsg, '')
164  call assert_true(!exists('g:MY_GLOBAL_LIST'))
165  call assert_true(!exists('g:MY_GLOBAL_DICT'))
166
167  call delete('Xviminfo')
168  set viminfo-=!
169endfunc
170
171func Test_cmdline_history()
172  call histdel(':')
173  call test_settime(11)
174  call histadd(':', "echo 'one'")
175  call test_settime(12)
176  " split into two lines
177  let long800 = repeat(" 'eight'", 100)
178  call histadd(':', "echo " . long800)
179  call test_settime(13)
180  " split into three lines
181  let long1400 = repeat(" 'fourteeeeen'", 100)
182  call histadd(':', "echo " . long1400)
183  wviminfo Xviminfo
184  let lines = readfile('Xviminfo')
185  let done_colon = 0
186  let done_bar = 0
187  let lnum = 0
188  while lnum < len(lines)
189    let line = lines[lnum] | let lnum += 1
190    if line[0] == ':'
191      if done_colon == 0
192	call assert_equal(":\x161408", line)
193	let line = lines[lnum] | let lnum += 1
194	call assert_equal('<echo ' . long1400, line)
195      elseif done_colon == 1
196	call assert_equal(":\x16808", line)
197	let line = lines[lnum] | let lnum += 1
198	call assert_equal("<echo " . long800, line)
199      elseif done_colon == 2
200	call assert_equal(":echo 'one'", line)
201      endif
202      let done_colon += 1
203    elseif line[0:4] == '|2,0,'
204      if done_bar == 0
205	call assert_equal("|2,0,13,,>1407", line)
206	let line = lines[lnum] | let lnum += 1
207	call assert_equal('|<"echo ' . long1400[0:484], line)
208	let line = lines[lnum] | let lnum += 1
209	call assert_equal('|<' . long1400[485:974], line)
210	let line = lines[lnum] | let lnum += 1
211	call assert_equal('|<' . long1400[975:] . '"', line)
212      elseif done_bar == 1
213	call assert_equal('|2,0,12,,>807', line)
214	let line = lines[lnum] | let lnum += 1
215	call assert_equal('|<"echo ' . long800[0:484], line)
216	let line = lines[lnum] | let lnum += 1
217	call assert_equal('|<' . long800[485:] . '"', line)
218      elseif done_bar == 2
219	call assert_equal("|2,0,11,,\"echo 'one'\"", line)
220      endif
221      let done_bar += 1
222    endif
223  endwhile
224  call assert_equal(3, done_colon)
225  call assert_equal(3, done_bar)
226
227  call histdel(':')
228  rviminfo Xviminfo
229  call assert_equal("echo " . long1400, histget(':', -1))
230  call assert_equal("echo " . long800, histget(':', -2))
231  call assert_equal("echo 'one'", histget(':', -3))
232
233  call delete('Xviminfo')
234endfunc
235
236func Test_cmdline_history_order()
237  call histdel(':')
238  call test_settime(11)
239  call histadd(':', "echo '11'")
240  call test_settime(22)
241  call histadd(':', "echo '22'")
242  call test_settime(33)
243  call histadd(':', "echo '33'")
244  wviminfo Xviminfo
245
246  call histdel(':')
247  " items go in between
248  call test_settime(15)
249  call histadd(':', "echo '15'")
250  call test_settime(27)
251  call histadd(':', "echo '27'")
252
253  rviminfo Xviminfo
254  call assert_equal("echo '33'", histget(':', -1))
255  call assert_equal("echo '27'", histget(':', -2))
256  call assert_equal("echo '22'", histget(':', -3))
257  call assert_equal("echo '15'", histget(':', -4))
258  call assert_equal("echo '11'", histget(':', -5))
259
260  call histdel(':')
261  " items go before and after
262  eval 8->test_settime()
263  call histadd(':', "echo '8'")
264  call test_settime(39)
265  call histadd(':', "echo '39'")
266
267  rviminfo Xviminfo
268  call assert_equal("echo '39'", histget(':', -1))
269  call assert_equal("echo '33'", histget(':', -2))
270  call assert_equal("echo '22'", histget(':', -3))
271  call assert_equal("echo '11'", histget(':', -4))
272  call assert_equal("echo '8'", histget(':', -5))
273
274  " Check sorting works when writing with merge.
275  call histdel(':')
276  call test_settime(8)
277  call histadd(':', "echo '8'")
278  call test_settime(15)
279  call histadd(':', "echo '15'")
280  call test_settime(27)
281  call histadd(':', "echo '27'")
282  call test_settime(39)
283  call histadd(':', "echo '39'")
284  wviminfo Xviminfo
285
286  call histdel(':')
287  rviminfo Xviminfo
288  call assert_equal("echo '39'", histget(':', -1))
289  call assert_equal("echo '33'", histget(':', -2))
290  call assert_equal("echo '27'", histget(':', -3))
291  call assert_equal("echo '22'", histget(':', -4))
292  call assert_equal("echo '15'", histget(':', -5))
293  call assert_equal("echo '11'", histget(':', -6))
294  call assert_equal("echo '8'", histget(':', -7))
295
296  call delete('Xviminfo')
297endfunc
298
299func Test_viminfo_registers()
300  call test_settime(8)
301  call setreg('a', "eight", 'c')
302  call test_settime(20)
303  call setreg('b', ["twenty", "again"], 'l')
304  call test_settime(40)
305  call setreg('c', ["four", "agai"], 'b4')
306  let l = []
307  set viminfo='100,<600,s10,h,!,nviminfo
308  for i in range(500)
309    call add(l, 'something')
310  endfor
311  call setreg('d', l, 'l')
312  call setreg('e', "abc\<C-V>xyz")
313  wviminfo Xviminfo
314
315  call test_settime(10)
316  call setreg('a', '', 'b10')
317  call test_settime(15)
318  call setreg('b', 'drop')
319  call test_settime(50)
320  call setreg('c', 'keep', 'l')
321  call test_settime(30)
322  call setreg('d', 'drop', 'l')
323  call setreg('e', 'drop')
324  rviminfo Xviminfo
325
326  call assert_equal("", getreg('a'))
327  call assert_equal("\<C-V>10", getregtype('a'))
328  call assert_equal("twenty\nagain\n", getreg('b'))
329  call assert_equal("V", getregtype('b'))
330  call assert_equal("keep\n", getreg('c'))
331  call assert_equal("V", getregtype('c'))
332  call assert_equal(l, getreg('d', 1, 1))
333  call assert_equal("V", getregtype('d'))
334  call assert_equal("abc\<C-V>xyz", getreg('e'))
335
336  " Length around 440 switches to line continuation.
337  let len = 434
338  while len < 445
339    let s = repeat('a', len)
340    call setreg('"', s)
341    wviminfo Xviminfo
342    call setreg('"', '')
343    rviminfo Xviminfo
344    call assert_equal(s, getreg('"'), 'wrong register at length: ' . len)
345
346    let len += 1
347  endwhile
348
349  call delete('Xviminfo')
350endfunc
351
352func Test_viminfo_marks()
353  sp bufa
354  let bufa = bufnr('%')
355  sp bufb
356  let bufb = bufnr('%')
357
358  call test_settime(8)
359  call setpos("'A", [bufa, 1, 1, 0])
360  call test_settime(20)
361  call setpos("'B", [bufb, 9, 1, 0])
362  call setpos("'C", [bufa, 7, 1, 0])
363
364  delmark 0-9
365  call test_settime(25)
366  call setpos("'1", [bufb, 12, 1, 0])
367  call test_settime(35)
368  call setpos("'0", [bufa, 11, 1, 0])
369
370  call test_settime(45)
371  wviminfo Xviminfo
372
373  " Writing viminfo inserts the '0 mark.
374  call assert_equal([bufb, 1, 1, 0], getpos("'0"))
375  call assert_equal([bufa, 11, 1, 0], getpos("'1"))
376  call assert_equal([bufb, 12, 1, 0], getpos("'2"))
377
378  call test_settime(4)
379  call setpos("'A", [bufa, 9, 1, 0])
380  call test_settime(30)
381  call setpos("'B", [bufb, 2, 3, 0])
382  delmark C
383
384  delmark 0-9
385  call test_settime(30)
386  call setpos("'1", [bufb, 22, 1, 0])
387  call test_settime(55)
388  call setpos("'0", [bufa, 21, 1, 0])
389
390  rviminfo Xviminfo
391
392  call assert_equal([bufa, 1, 1, 0], getpos("'A"))
393  call assert_equal([bufb, 2, 3, 0], getpos("'B"))
394  call assert_equal([bufa, 7, 1, 0], getpos("'C"))
395
396  " numbered marks are merged
397  call assert_equal([bufa, 21, 1, 0], getpos("'0"))  " time 55
398  call assert_equal([bufb, 1, 1, 0], getpos("'1"))  " time 45
399  call assert_equal([bufa, 11, 1, 0], getpos("'2")) " time 35
400  call assert_equal([bufb, 22, 1, 0], getpos("'3")) " time 30
401  call assert_equal([bufb, 12, 1, 0], getpos("'4")) " time 25
402
403  " deleted file marks are removed from viminfo
404  delmark C
405  wviminfo Xviminfo
406  rviminfo Xviminfo
407  call assert_equal([0, 0, 0, 0], getpos("'C"))
408
409  " deleted file marks stay in viminfo if defined in another vim later
410  call test_settime(70)
411  call setpos("'D", [bufb, 8, 1, 0])
412  wviminfo Xviminfo
413  call test_settime(65)
414  delmark D
415  call assert_equal([0, 0, 0, 0], getpos("'D"))
416  call test_settime(75)
417  rviminfo Xviminfo
418  call assert_equal([bufb, 8, 1, 0], getpos("'D"))
419
420  call delete('Xviminfo')
421  exe 'bwipe ' . bufa
422  exe 'bwipe ' . bufb
423endfunc
424
425func Test_viminfo_jumplist()
426  split testbuf
427  clearjumps
428  call setline(1, ['time 05', 'time 10', 'time 15', 'time 20', 'time 30', 'last pos'])
429  call cursor(2, 1)
430  call test_settime(10)
431  exe "normal /20\r"
432  call test_settime(20)
433  exe "normal /30\r"
434  call test_settime(30)
435  exe "normal /last pos\r"
436  wviminfo Xviminfo
437
438  clearjumps
439  call cursor(1, 1)
440  call test_settime(5)
441  exe "normal /15\r"
442  call test_settime(15)
443  exe "normal /last pos\r"
444  call test_settime(40)
445  exe "normal ?30\r"
446  rviminfo Xviminfo
447
448  call assert_equal('time 30', getline('.'))
449  exe "normal \<C-O>"
450  call assert_equal('last pos', getline('.'))
451  exe "normal \<C-O>"
452  " duplicate for 'time 30' was removed
453  call assert_equal('time 20', getline('.'))
454  exe "normal \<C-O>"
455  call assert_equal('time 15', getline('.'))
456  exe "normal \<C-O>"
457  call assert_equal('time 10', getline('.'))
458  exe "normal \<C-O>"
459  call assert_equal('time 05', getline('.'))
460
461  clearjumps
462  call cursor(1, 1)
463  call test_settime(5)
464  exe "normal /15\r"
465  call test_settime(15)
466  exe "normal /last pos\r"
467  call test_settime(40)
468  exe "normal ?30\r"
469  " Test merge when writing
470  wviminfo Xviminfo
471  clearjumps
472  rviminfo Xviminfo
473
474  let last_line = line('.')
475  exe "normal \<C-O>"
476  call assert_equal('time 30', getline('.'))
477  exe "normal \<C-O>"
478  call assert_equal('last pos', getline('.'))
479  exe "normal \<C-O>"
480  " duplicate for 'time 30' was removed
481  call assert_equal('time 20', getline('.'))
482  exe "normal \<C-O>"
483  call assert_equal('time 15', getline('.'))
484  exe "normal \<C-O>"
485  call assert_equal('time 10', getline('.'))
486  exe "normal \<C-O>"
487  call assert_equal('time 05', getline('.'))
488
489  " Test with jumplist full.
490  clearjumps
491  call setline(1, repeat(['match here'], 101))
492  call cursor(1, 1)
493  call test_settime(10)
494  for i in range(100)
495    exe "normal /here\r"
496  endfor
497  rviminfo Xviminfo
498
499  " must be newest mark that comes from viminfo.
500  exe "normal \<C-O>"
501  call assert_equal(last_line, line('.'))
502
503  bwipe!
504  call delete('Xviminfo')
505endfunc
506
507func Test_viminfo_encoding()
508  set enc=latin1
509  call histdel(':')
510  call histadd(':', "echo '\xe9'")
511  wviminfo Xviminfo
512
513  set fencs=utf-8,latin1
514  set enc=utf-8
515  sp Xviminfo
516  call assert_equal('latin1', &fenc)
517  close
518
519  call histdel(':')
520  rviminfo Xviminfo
521  call assert_equal("echo 'é'", histget(':', -1))
522
523  call delete('Xviminfo')
524endfunc
525
526func Test_viminfo_bad_syntax()
527  let lines = []
528  call add(lines, '|<')  " empty continuation line
529  call add(lines, '|234234234234234324,nothing')
530  call add(lines, '|1+"no comma"')
531  call add(lines, '|1,2,3,4,5,6,7')  " too many items
532  call add(lines, '|1,"string version"')
533  call add(lines, '|1,>x') " bad continuation line
534  call add(lines, '|1,"x') " missing quote
535  call add(lines, '|1,"x\') " trailing backslash
536  call add(lines, '|1,,,,') "trailing comma
537  call add(lines, '|1,>234') " trailing continuation line
538  call writefile(lines, 'Xviminfo')
539  rviminfo Xviminfo
540
541  call delete('Xviminfo')
542endfunc
543
544func Test_viminfo_bad_register_syntax()
545  let lines = []
546  call add(lines, '|1,4')
547  call add(lines, '|3') " invalid number of fields for a register type
548  call add(lines, '|3,1,1,1,1,,1,"x"') " invalid value for the width field
549  call add(lines, '|3,0,80,1,1,1,1,"x"') " invalid register number
550  call add(lines, '|3,0,10,5,1,1,1,"x"') " invalid register type
551  call add(lines, '|3,0,10,1,20,1,1,"x"') " invalid line count
552  call add(lines, '|3,0,10,1,0,1,1') " zero line count
553  call writefile(lines, 'Xviminfo')
554  rviminfo Xviminfo
555  call delete('Xviminfo')
556endfunc
557
558func Test_viminfo_file_marks()
559  silent! bwipe test_viminfo.vim
560  silent! bwipe Xviminfo
561
562  call test_settime(10)
563  edit ten
564  call test_settime(25)
565  edit again
566  call test_settime(30)
567  edit thirty
568  wviminfo Xviminfo
569
570  call test_settime(20)
571  edit twenty
572  call test_settime(35)
573  edit again
574  call test_settime(40)
575  edit fourty
576  wviminfo Xviminfo
577
578  sp Xviminfo
579  1
580  for name in ['fourty', 'again', 'thirty', 'twenty', 'ten']
581    /^>
582    call assert_equal(name, substitute(getline('.'), '.*/', '', ''))
583  endfor
584  close
585
586  call delete('Xviminfo')
587endfunc
588
589func Test_viminfo_file_mark_tabclose()
590  tabnew Xtestfileintab
591  call setline(1, ['a','b','c','d','e'])
592  4
593  q!
594  wviminfo Xviminfo
595  sp Xviminfo
596  /^> .*Xtestfileintab
597  let lnum = line('.')
598  while 1
599    if lnum == line('$')
600      call assert_report('mark not found in Xtestfileintab')
601      break
602    endif
603    let lnum += 1
604    let line = getline(lnum)
605    if line == ''
606      call assert_report('mark not found in Xtestfileintab')
607      break
608    endif
609    if line =~ "^\t\""
610      call assert_equal('4', substitute(line, ".*\"\t\\(\\d\\).*", '\1', ''))
611      break
612    endif
613  endwhile
614
615  call delete('Xviminfo')
616  silent! bwipe Xtestfileintab
617endfunc
618
619func Test_viminfo_file_mark_zero_time()
620  let lines = [
621	\ '# Viminfo version',
622	\ '|1,4',
623	\ '',
624	\ '*encoding=utf-8',
625	\ '',
626	\ '# File marks:',
627	\ "'B  1  0  /tmp/nothing",
628	\ '|4,66,1,0,0,"/tmp/nothing"',
629	\ "",
630	\ ]
631  call writefile(lines, 'Xviminfo')
632  delmark B
633  rviminfo Xviminfo
634  call delete('Xviminfo')
635  call assert_equal(1, line("'B"))
636  delmark B
637endfunc
638
639" Test for saving and restoring file marks in unloaded buffers
640func Test_viminfo_file_mark_unloaded_buf()
641  let save_viminfo = &viminfo
642  set viminfo&vim
643  call writefile(repeat(['vim'], 10), 'Xfile1')
644  %bwipe
645  edit! Xfile1
646  call setpos("'u", [0, 3, 1, 0])
647  call setpos("'v", [0, 5, 1, 0])
648  enew
649  wviminfo Xviminfo
650  %bwipe
651  edit Xfile1
652  rviminfo! Xviminfo
653  call assert_equal([0, 3, 1, 0], getpos("'u"))
654  call assert_equal([0, 5, 1, 0], getpos("'v"))
655  %bwipe
656  call delete('Xfile1')
657  call delete('Xviminfo')
658  let &viminfo = save_viminfo
659endfunc
660
661func Test_viminfo_oldfiles()
662  let v:oldfiles = []
663  let lines = [
664	\ '# comment line',
665	\ '*encoding=utf-8',
666	\ '',
667	\ ':h viminfo',
668	\ '?/session',
669	\ '=myvar',
670	\ '@123',
671	\ '',
672	\ "'E  2  0  /tmp/nothing",
673	\ '',
674	\ "> /tmp/file_one.txt",
675	\ "\t\"\t11\t0",
676	\ "",
677	\ "> /tmp/file_two.txt",
678	\ "\t\"\t11\t0",
679	\ "",
680	\ "> /tmp/another.txt",
681	\ "\t\"\t11\t0",
682	\ "",
683	\ ]
684  call writefile(lines, 'Xviminfo')
685  delmark E
686  edit /tmp/file_two.txt
687  rviminfo! Xviminfo
688  call delete('Xviminfo')
689
690  call assert_equal('h viminfo', histget(':'))
691  call assert_equal('session', histget('/'))
692  call assert_equal('myvar', histget('='))
693  call assert_equal('123', histget('@'))
694  call assert_equal(2, line("'E"))
695  call assert_equal(['1: /tmp/file_one.txt', '2: /tmp/file_two.txt', '3: /tmp/another.txt'], filter(split(execute('oldfiles'), "\n"), {i, v -> v =~ '/tmp/'}))
696  call assert_equal(['1: /tmp/file_one.txt', '2: /tmp/file_two.txt'], filter(split(execute('filter file_ oldfiles'), "\n"), {i, v -> v =~ '/tmp/'}))
697  call assert_equal(['3: /tmp/another.txt'], filter(split(execute('filter /another/ oldfiles'), "\n"), {i, v -> v =~ '/tmp/'}))
698
699  new
700  call feedkeys("3\<CR>", 't')
701  browse oldfiles
702  call assert_equal("/tmp/another.txt", expand("%"))
703  bwipe
704  delmark E
705endfunc
706
707" Test for storing and restoring buffer list in 'viminfo'
708func Test_viminfo_bufferlist()
709  " If there are arguments, then :rviminfo doesn't read the buffer list.
710  " Need to delete all the arguments for :rviminfo to work.
711  %argdelete
712  set viminfo&vim
713
714  edit Xfile1
715  edit Xfile2
716  set viminfo-=%
717  wviminfo Xviminfo
718  %bwipe
719  rviminfo Xviminfo
720  call assert_equal(1, len(getbufinfo()))
721
722  edit Xfile1
723  edit Xfile2
724  set viminfo^=%
725  wviminfo Xviminfo
726  %bwipe
727  rviminfo Xviminfo
728  let l = getbufinfo()
729  call assert_equal(3, len(l))
730  call assert_equal('Xfile1', bufname(l[1].bufnr))
731  call assert_equal('Xfile2', bufname(l[2].bufnr))
732
733  " The quickfix, terminal, unlisted, unnamed buffers are not stored in the
734  " viminfo file
735  %bw!
736  edit Xfile1
737  new
738  setlocal nobuflisted
739  new
740  copen
741  if has('terminal')
742    terminal
743  endif
744  wviminfo! Xviminfo
745  %bwipe!
746  rviminfo Xviminfo
747  let l = getbufinfo()
748  call assert_equal(2, len(l))
749  call assert_true(bufexists('Xfile1'))
750
751  " If a count is specified for '%', then only that many buffers should be
752  " stored in the viminfo file.
753  %bw!
754  set viminfo&vim
755  new Xbuf1
756  new Xbuf2
757  set viminfo+=%1
758  wviminfo! Xviminfo
759  %bwipe!
760  rviminfo! Xviminfo
761  let l = getbufinfo()
762  call assert_equal(2, len(l))
763  call assert_true(bufexists('Xbuf1'))
764  call assert_false(bufexists('Xbuf2'))
765
766  call delete('Xviminfo')
767  %bwipe
768  set viminfo&vim
769endfunc
770
771" Test for errors in a viminfo file
772func Test_viminfo_error()
773  " Non-existing viminfo files
774  call assert_fails('rviminfo xyz', 'E195:')
775
776  " Illegal starting character
777  call writefile(["a 123"], 'Xviminfo')
778  call assert_fails('rv Xviminfo', 'E575:')
779
780  " Illegal register name in the viminfo file
781  call writefile(['"@	LINE	0'], 'Xviminfo')
782  call assert_fails('rv Xviminfo', 'E577:')
783
784  " Invalid file mark line
785  call writefile(['>', '@'], 'Xviminfo')
786  call assert_fails('rv Xviminfo', 'E576:')
787
788  " Too many errors in viminfo file
789  call writefile(repeat(["a 123"], 15), 'Xviminfo')
790  call assert_fails('rv Xviminfo', 'E575:')
791
792  call writefile(['>'] + repeat(['@'], 10), 'Xviminfo')
793  call assert_fails('rv Xviminfo', 'E576:')
794
795  call writefile(repeat(['"@'], 15), 'Xviminfo')
796  call assert_fails('rv Xviminfo', 'E577:')
797
798  call delete('Xviminfo')
799endfunc
800
801" Test for saving and restoring last substitute string in viminfo
802func Test_viminfo_lastsub()
803  enew
804  call append(0, "blue blue blue")
805  call cursor(1, 1)
806  s/blue/green/
807  wviminfo Xviminfo
808  s/blue/yellow/
809  rviminfo! Xviminfo
810  &
811  call assert_equal("green yellow green", getline(1))
812  enew!
813  call delete('Xviminfo')
814endfunc
815
816" Test saving and restoring the register values using the older method
817func Test_viminfo_registers_old()
818  let lines = [
819	\ '# Viminfo version',
820	\ '|1,1',
821	\ '',
822	\ '*encoding=utf-8',
823	\ '',
824	\ '# Registers:',
825	\ '""0 CHAR  0',
826	\ '	Vim',
827	\ '"a  CHAR  0',
828	\ '	red',
829	\ '"c  BLOCK  0',
830	\ '	a',
831	\ '	d',
832	\ '"d  LINE  0',
833	\ '	abc',
834	\ '	def',
835	\ '"m@ CHAR  0',
836	\ "	:echo 'Hello'\<CR>",
837	\ "",
838	\ ]
839  call writefile(lines, 'Xviminfo')
840  let @a = 'one'
841  let @b = 'two'
842  let @m = 'three'
843  let @" = 'four'
844  let @t = ":echo 'Unix'\<CR>"
845  silent! normal @t
846  rviminfo! Xviminfo
847  call assert_equal('red', getreg('a'))
848  call assert_equal("v", getregtype('a'))
849  call assert_equal('two', getreg('b'))
850  call assert_equal("a\nd", getreg('c'))
851  call assert_equal("\<C-V>1", getregtype('c'))
852  call assert_equal("abc\ndef\n", getreg('d'))
853  call assert_equal("V", getregtype('d'))
854  call assert_equal(":echo 'Hello'\<CR>", getreg('m'))
855  call assert_equal('Vim', getreg('"'))
856  call assert_equal("\nHello", execute('normal @@'))
857  call delete('Xviminfo')
858  let @" = ''
859endfunc
860
861" Test for saving and restoring large number of lines in a register
862func Test_viminfo_large_register()
863  let save_viminfo = &viminfo
864  set viminfo&vim
865  set viminfo-=<50
866  set viminfo+=<200
867  let lines = ['"r	CHAR	0']
868  call extend(lines, repeat(["\tsun is rising"], 200))
869  call writefile(lines, 'Xviminfo')
870  let @r = ''
871  rviminfo! Xviminfo
872  call assert_equal(join(repeat(["sun is rising"], 200), "\n"), @r)
873  call delete('Xviminfo')
874  let @r = ''
875  let &viminfo = save_viminfo
876endfunc
877
878" Test for setting 'viminfofile' to NONE
879func Test_viminfofile_none()
880  let save_vif = &viminfofile
881  set viminfofile=NONE
882  wviminfo Xviminfo
883  call assert_false(filereadable('Xviminfo'))
884  call writefile([''], 'Xviminfo')
885  call assert_fails('rviminfo Xviminfo', 'E195:')
886  call delete('Xviminfo')
887  let &viminfofile = save_vif
888endfunc
889
890" Test for an unwritable and unreadble 'viminfo' file
891func Test_viminfo_perm()
892  CheckUnix
893  CheckNotRoot
894  call writefile([''], 'Xviminfo')
895  call setfperm('Xviminfo', 'r-x------')
896  call assert_fails('wviminfo Xviminfo', 'E137:')
897  call setfperm('Xviminfo', '--x------')
898  call assert_fails('rviminfo Xviminfo', 'E195:')
899  call delete('Xviminfo')
900
901  " Try to write the viminfo to a directory
902  call mkdir('Xdir')
903  call assert_fails('wviminfo Xdir', 'E137:')
904  call delete('Xdir', 'rf')
905endfunc
906
907" Test for writing to an existing viminfo file merges the file marks
908func XTest_viminfo_marks_merge()
909  let save_viminfo = &viminfo
910  set viminfo&vim
911  set viminfo^=%
912  enew
913  %argdelete
914  %bwipe
915
916  call writefile(repeat(['editor'], 10), 'Xbufa')
917  call writefile(repeat(['Vim'], 10), 'Xbufb')
918
919  " set marks in buffers
920  call test_settime(10)
921  edit Xbufa
922  4mark a
923  wviminfo Xviminfo
924  edit Xbufb
925  4mark b
926  wviminfo Xviminfo
927  %bwipe
928
929  " set marks in buffers again
930  call test_settime(20)
931  edit Xbufb
932  6mark b
933  wviminfo Xviminfo
934  edit Xbufa
935  6mark a
936  wviminfo Xviminfo
937  %bwipe
938
939  " Load the buffer and check the marks
940  edit Xbufa
941  rviminfo! Xviminfo
942  call assert_equal(6, line("'a"))
943  edit Xbufb
944  rviminfo! Xviminfo
945  call assert_equal(6, line("'b"))
946
947  " cleanup
948  %bwipe
949  call delete('Xviminfo')
950  call delete('Xbufa')
951  call delete('Xbufb')
952  call test_settime(0)
953  let &viminfo=save_viminfo
954endfunc
955
956" Test for errors in setting 'viminfo'
957func Test_viminfo_option_error()
958  " Missing number
959  call assert_fails('set viminfo=\"', 'E526:')
960  for c in split("'/:<@s", '\zs')
961    call assert_fails('set viminfo=' .. c, 'E526:')
962  endfor
963
964  " Missing comma
965  call assert_fails('set viminfo=%10!', 'E527:')
966  call assert_fails('set viminfo=!%10', 'E527:')
967  call assert_fails('set viminfo=h%10', 'E527:')
968  call assert_fails('set viminfo=c%10', 'E527:')
969  call assert_fails('set viminfo=:10%10', 'E527:')
970
971  " Missing ' setting
972  call assert_fails('set viminfo=%10', 'E528:')
973endfunc
974
975func Test_viminfo_oldfiles_newfile()
976  CheckRunVimInTerminal
977
978  let save_viminfo = &viminfo
979  let save_viminfofile = &viminfofile
980  set viminfo&vim
981  let v:oldfiles = []
982  let commands =<< trim [CODE]
983    set viminfofile=Xviminfofile
984    set viminfo&vim
985    w! Xnew-file.txt
986    qall
987  [CODE]
988  call writefile(commands, 'Xviminfotest')
989  let buf = RunVimInTerminal('-S Xviminfotest', #{wait_for_ruler: 0})
990  call WaitForAssert({-> assert_equal("finished", term_getstatus(buf))})
991
992  let &viminfofile = 'Xviminfofile'
993  rviminfo! Xviminfofile
994  call assert_match('Xnew-file.txt$', v:oldfiles[0])
995  call assert_equal(1, len(v:oldfiles))
996  call delete('Xviminfofile')
997  call delete('Xviminfotest')
998  call delete('Xnew-file.txt')
999
1000  let v:oldfiles = test_null_list()
1001  call assert_equal("\nNo old files", execute('oldfiles'))
1002
1003  let &viminfo = save_viminfo
1004  let &viminfofile = save_viminfofile
1005endfunc
1006
1007" When writing CTRL-V or "\n" to a viminfo file, it is converted to CTRL-V
1008" CTRL-V and CTRL-V n respectively.
1009func Test_viminfo_with_Ctrl_V()
1010  silent! exe "normal! /\<C-V>\<C-V>\n"
1011  wviminfo Xviminfo
1012  call assert_notequal(-1, readfile('Xviminfo')->index("?/\<C-V>\<C-V>"))
1013  let @/ = 'abc'
1014  rviminfo! Xviminfo
1015  call assert_equal("\<C-V>", @/)
1016  silent! exe "normal! /\<C-V>\<C-J>\n"
1017  wviminfo Xviminfo
1018  call assert_notequal(-1, readfile('Xviminfo')->index("?/\<C-V>n"))
1019  let @/ = 'abc'
1020  rviminfo! Xviminfo
1021  call assert_equal("\n", @/)
1022  call delete('Xviminfo')
1023endfunc
1024
1025" Test for the 'r' field in 'viminfo' (removal media)
1026func Test_viminfo_removable_media()
1027  CheckUnix
1028  if !isdirectory('/tmp') || getftype('/tmp') != 'dir'
1029    return
1030  endif
1031  let save_viminfo = &viminfo
1032  set viminfo+=r/tmp
1033  edit /tmp/Xvima1b2c3
1034  wviminfo Xviminfo
1035  let matches = readfile('Xviminfo')->filter("v:val =~ 'Xvima1b2c3'")
1036  call assert_equal(0, matches->len())
1037  let &viminfo = save_viminfo
1038  call delete('Xviminfo')
1039endfunc
1040
1041" Test for the 'h' flag in 'viminfo'. If 'h' is not present, then the last
1042" search pattern read from 'viminfo' should be highlighted with 'hlsearch'.
1043" If 'h' is present, then the last search pattern should not be highlighted.
1044func Test_viminfo_hlsearch()
1045  set viminfo&vim
1046
1047  new
1048  call setline(1, ['one two three'])
1049  " save the screen attribute for the Search highlighted text and the normal
1050  " text for later comparison
1051  set hlsearch
1052  let @/ = 'three'
1053  redraw!
1054  let hiSearch = screenattr(1, 9)
1055  let hiNormal = screenattr(1, 1)
1056
1057  set viminfo-=h
1058  let @/='two'
1059  wviminfo! Xviminfo
1060  let @/='one'
1061  rviminfo! Xviminfo
1062  redraw!
1063  call assert_equal(hiSearch, screenattr(1, 5))
1064  call assert_equal(hiSearch, screenattr(1, 6))
1065  call assert_equal(hiSearch, screenattr(1, 7))
1066
1067  set viminfo+=h
1068  let @/='two'
1069  wviminfo! Xviminfo
1070  let @/='one'
1071  rviminfo! Xviminfo
1072  redraw!
1073  call assert_equal(hiNormal, screenattr(1, 5))
1074  call assert_equal(hiNormal, screenattr(1, 6))
1075  call assert_equal(hiNormal, screenattr(1, 7))
1076
1077  call delete('Xviminfo')
1078  set hlsearch& viminfo&vim
1079  bw!
1080endfunc
1081
1082" Test for restoring the magicness of the last search pattern from the viminfo
1083" file.
1084func Test_viminfo_last_spat_magic()
1085  set viminfo&vim
1086  new
1087  call setline(1, ' one abc a.c')
1088
1089  " restore 'nomagic'
1090  set nomagic
1091  exe "normal gg/a.c\<CR>"
1092  wviminfo! Xviminfo
1093  set magic
1094  exe "normal gg/one\<CR>"
1095  rviminfo! Xviminfo
1096  exe "normal! gg/\<CR>"
1097  call assert_equal(10, col('.'))
1098
1099  " restore 'magic'
1100  set magic
1101  exe "normal gg/a.c\<CR>"
1102  wviminfo! Xviminfo
1103  set nomagic
1104  exe "normal gg/one\<CR>"
1105  rviminfo! Xviminfo
1106  exe "normal! gg/\<CR>"
1107  call assert_equal(6, col('.'))
1108
1109  call delete('Xviminfo')
1110  set viminfo&vim magic&
1111  bw!
1112endfunc
1113
1114" Test for restoring the smartcase of the last search pattern from the viminfo
1115" file.
1116func Test_viminfo_last_spat_smartcase()
1117  new
1118  call setline(1, ' one abc Abc')
1119  set ignorecase smartcase
1120
1121  " Searching with * should disable smartcase
1122  exe "normal! gg$b*"
1123  wviminfo! Xviminfo
1124  exe "normal gg/one\<CR>"
1125  rviminfo! Xviminfo
1126  exe "normal! gg/\<CR>"
1127  call assert_equal(6, col('.'))
1128
1129  call delete('Xviminfo')
1130  set ignorecase& smartcase& viminfo&
1131  bw!
1132endfunc
1133
1134" Test for restoring the last search pattern with a line or character offset
1135" from the viminfo file.
1136func Test_viminfo_last_spat_offset()
1137  new
1138  call setline(1, ['one', 'two', 'three', 'four', 'five'])
1139  " line offset
1140  exe "normal! /two/+2\<CR>"
1141  wviminfo! Xviminfo
1142  exe "normal gg/five\<CR>"
1143  rviminfo! Xviminfo
1144  exe "normal! gg/\<CR>"
1145  call assert_equal(4, line('.'))
1146  " character offset
1147  exe "normal! gg/^th/e+2\<CR>"
1148  wviminfo! Xviminfo
1149  exe "normal gg/two\<CR>"
1150  rviminfo! Xviminfo
1151  exe "normal! gg/\<CR>"
1152  call assert_equal([3, 4], [line('.'), col('.')])
1153  call delete('Xviminfo')
1154  bw!
1155endfunc
1156
1157" Test for saving and restoring the last executed register (@ command)
1158" from the viminfo file
1159func Test_viminfo_last_exec_reg()
1160  let g:val = 1
1161  let @a = ":let g:val += 1\n"
1162  normal! @a
1163  wviminfo! Xviminfo
1164  let @b = ''
1165  normal! @b
1166  rviminfo! Xviminfo
1167  normal @@
1168  call assert_equal(3, g:val)
1169  call delete('Xviminfo')
1170endfunc
1171
1172" Test for merging file marks in a viminfo file
1173func Test_viminfo_merge_file_marks()
1174  for [f, l, t] in [['a.txt', 5, 10], ['b.txt', 10, 20]]
1175    call test_settime(t)
1176    exe 'edit ' .. f
1177    call setline(1, range(1, 20))
1178    exe l . 'mark a'
1179    wviminfo Xviminfo
1180    bw!
1181  endfor
1182  call test_settime(30)
1183  for [f, l] in [['a.txt', 5], ['b.txt', 10]]
1184    exe 'edit ' .. f
1185    rviminfo! Xviminfo
1186    call assert_equal(l, line("'a"))
1187    bw!
1188  endfor
1189  call delete('Xviminfo')
1190  call test_settime(0)
1191endfunc
1192
1193" Test for merging file marks from a old viminfo file
1194func Test_viminfo_merge_old_filemarks()
1195  let lines = []
1196  call add(lines, '|1,4')
1197  call add(lines, '> ' .. fnamemodify('a.txt', ':p:~'))
1198  call add(lines, "\tb\t7\t0\n")
1199  call writefile(lines, 'Xviminfo')
1200  edit b.txt
1201  call setline(1, range(1, 20))
1202  12mark b
1203  wviminfo Xviminfo
1204  bw!
1205  edit a.txt
1206  rviminfo! Xviminfo
1207  call assert_equal(7, line("'b"))
1208  edit b.txt
1209  rviminfo! Xviminfo
1210  call assert_equal(12, line("'b"))
1211  call delete('Xviminfo')
1212endfunc
1213
1214" Test for merging the jump list from a old viminfo file
1215func Test_viminfo_merge_old_jumplist()
1216  let lines = []
1217  call add(lines, "-'  10  1  " .. fnamemodify('a.txt', ':p:~'))
1218  call add(lines, "-'  20  1  " .. fnamemodify('a.txt', ':p:~'))
1219  call add(lines, "-'  30  1  " .. fnamemodify('b.txt', ':p:~'))
1220  call add(lines, "-'  40  1  " .. fnamemodify('b.txt', ':p:~'))
1221  call writefile(lines, 'Xviminfo')
1222  clearjumps
1223  rviminfo! Xviminfo
1224  let l = getjumplist()[0]
1225  call assert_equal([40, 30, 20, 10], [l[0].lnum, l[1].lnum, l[2].lnum,
1226        \ l[3].lnum])
1227  bw!
1228  call delete('Xviminfo')
1229endfunc
1230
1231" vim: shiftwidth=2 sts=2 expandtab
1232