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