1" Test for :mksession, :mkview and :loadview in latin1 encoding
2
3set encoding=latin1
4scriptencoding latin1
5
6source check.vim
7CheckFeature mksession
8
9source shared.vim
10source term_util.vim
11
12func Test_mksession()
13  tabnew
14  let wrap_save = &wrap
15  set sessionoptions=buffers splitbelow fileencoding=latin1
16  call setline(1, [
17    \   'start:',
18    \   'no multibyte chAracter',
19    \   '	one leaDing tab',
20    \   '    four leadinG spaces',
21    \   'two		consecutive tabs',
22    \   'two	tabs	in one line',
23    \   'one � multibyteCharacter',
24    \   'a� �  two multiByte characters',
25    \   'A���  three mulTibyte characters',
26    \   'short line',
27    \ ])
28  let tmpfile = 'Xtemp'
29  exec 'w! ' . tmpfile
30  /^start:
31  set wrap
32  vsplit
33  norm! j16|
34  split
35  norm! j16|
36  split
37  norm! j16|
38  split
39  norm! j8|
40  split
41  norm! j8|
42  split
43  norm! j16|
44  split
45  norm! j16|
46  split
47  norm! j16|
48  split
49  norm! j$
50  wincmd l
51
52  set nowrap
53  /^start:
54  norm! j16|3zl
55  split
56  norm! j016|3zl
57  split
58  norm! j016|3zl
59  split
60  norm! j08|3zl
61  split
62  norm! j08|3zl
63  split
64  norm! j016|3zl
65  split
66  norm! j016|3zl
67  split
68  norm! j016|3zl
69  split
70  call wincol()
71  mksession! Xtest_mks.out
72  let li = filter(readfile('Xtest_mks.out'), 'v:val =~# "\\(^ *normal! [0$]\\|^ *exe ''normal!\\)"')
73  let expected = [
74    \   'normal! 016|',
75    \   'normal! 016|',
76    \   'normal! 016|',
77    \   'normal! 08|',
78    \   'normal! 08|',
79    \   'normal! 016|',
80    \   'normal! 016|',
81    \   'normal! 016|',
82    \   'normal! $',
83    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
84    \   "  normal! 016|",
85    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
86    \   "  normal! 016|",
87    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
88    \   "  normal! 016|",
89    \   "  exe 'normal! ' . s:c . '|zs' . 8 . '|'",
90    \   "  normal! 08|",
91    \   "  exe 'normal! ' . s:c . '|zs' . 8 . '|'",
92    \   "  normal! 08|",
93    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
94    \   "  normal! 016|",
95    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
96    \   "  normal! 016|",
97    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
98    \   "  normal! 016|",
99    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
100    \   "  normal! 016|"
101    \ ]
102  call assert_equal(expected, li)
103  tabclose!
104
105  call delete('Xtest_mks.out')
106  call delete(tmpfile)
107  let &wrap = wrap_save
108  set sessionoptions&
109endfunc
110
111func Test_mksession_winheight()
112  new
113  set winheight=10
114  set winminheight=2
115  mksession! Xtest_mks.out
116  source Xtest_mks.out
117
118  call delete('Xtest_mks.out')
119endfunc
120
121func Test_mksession_large_winheight()
122  set winheight=999
123  mksession! Xtest_mks_winheight.out
124  set winheight&
125  source Xtest_mks_winheight.out
126  call delete('Xtest_mks_winheight.out')
127endfunc
128
129func Test_mksession_rtp()
130  if has('win32')
131    " TODO: fix problem with backslashes
132    return
133  endif
134  new
135  let _rtp=&rtp
136  " Make a real long (invalid) runtimepath value,
137  " that should exceed PATH_MAX (hopefully)
138  let newrtp=&rtp.',~'.repeat('/foobar', 1000)
139  let newrtp.=",".expand("$HOME")."/.vim"
140  let &rtp=newrtp
141
142  " determine expected value
143  let expected=split(&rtp, ',')
144  let expected = map(expected, '"set runtimepath+=".v:val')
145  let expected = ['set runtimepath='] + expected
146  let expected = map(expected, {v,w -> substitute(w, $HOME, "~", "g")})
147
148  mksession! Xtest_mks.out
149  let &rtp=_rtp
150  let li = filter(readfile('Xtest_mks.out'), 'v:val =~# "runtimepath"')
151  call assert_equal(expected, li)
152
153  call delete('Xtest_mks.out')
154endfunc
155
156func Test_mksession_arglist()
157  argdel *
158  next file1 file2 file3 file4
159  mksession! Xtest_mks.out
160  source Xtest_mks.out
161  call assert_equal(['file1', 'file2', 'file3', 'file4'], argv())
162
163  call delete('Xtest_mks.out')
164  argdel *
165endfunc
166
167func Test_mksession_one_buffer_two_windows()
168  edit Xtest1
169  new Xtest2
170  split
171  mksession! Xtest_mks.out
172  let lines = readfile('Xtest_mks.out')
173  let count1 = 0
174  let count2 = 0
175  let count2buf = 0
176  for line in lines
177    if line =~ 'edit \f*Xtest1$'
178      let count1 += 1
179    endif
180    if line =~ 'edit \f\{-}Xtest2'
181      let count2 += 1
182    endif
183    if line =~ 'buffer \f\{-}Xtest2'
184      let count2buf += 1
185    endif
186  endfor
187  call assert_equal(1, count1, 'Xtest1 count')
188  call assert_equal(2, count2, 'Xtest2 count')
189  call assert_equal(2, count2buf, 'Xtest2 buffer count')
190
191  close
192  bwipe!
193  call delete('Xtest_mks.out')
194endfunc
195
196func Test_mksession_lcd_multiple_tabs()
197  tabnew
198  tabnew
199  lcd .
200  tabfirst
201  lcd .
202  mksession! Xtest_mks.out
203  tabonly
204  source Xtest_mks.out
205  call assert_true(haslocaldir(), 'Tab 1 localdir')
206  tabnext 2
207  call assert_true(!haslocaldir(), 'Tab 2 localdir')
208  tabnext 3
209  call assert_true(haslocaldir(), 'Tab 3 localdir')
210  call delete('Xtest_mks.out')
211endfunc
212
213" Test for tabpage-local directory
214func Test_mksession_tcd_multiple_tabs()
215  let save_cwd = getcwd()
216  call mkdir('Xtopdir')
217  cd Xtopdir
218  call mkdir('Xtabdir1')
219  call mkdir('Xtabdir2')
220  call mkdir('Xtabdir3')
221  call mkdir('Xwindir1')
222  call mkdir('Xwindir2')
223  call mkdir('Xwindir3')
224  tcd Xtabdir1
225  botright new
226  wincmd t
227  lcd ../Xwindir1
228  tabnew
229  tcd ../Xtabdir2
230  botright new
231  lcd ../Xwindir2
232  tabnew
233  tcd ../Xtabdir3
234  botright new
235  lcd ../Xwindir3
236  tabfirst
237  1wincmd w
238  mksession! Xtest_mks.out
239  only | tabonly
240  source Xtest_mks.out
241  call assert_equal('Xtabdir1', fnamemodify(getcwd(-1, 1), ':t'))
242  call assert_equal('Xwindir1', fnamemodify(getcwd(1, 1), ':t'))
243  call assert_equal('Xtabdir1', fnamemodify(getcwd(2, 1), ':t'))
244  call assert_equal('Xtabdir2', fnamemodify(getcwd(-1, 2), ':t'))
245  call assert_equal('Xtabdir2', fnamemodify(getcwd(1, 2), ':t'))
246  call assert_equal('Xwindir2', fnamemodify(getcwd(2, 2), ':t'))
247  call assert_equal('Xtabdir3', fnamemodify(getcwd(-1, 3), ':t'))
248  call assert_equal('Xtabdir3', fnamemodify(getcwd(1, 3), ':t'))
249  call assert_equal('Xwindir3', fnamemodify(getcwd(2, 3), ':t'))
250  only | tabonly
251  exe 'cd ' . save_cwd
252  call delete("Xtopdir", "rf")
253endfunc
254
255func Test_mksession_blank_tabs()
256  tabnew
257  tabnew
258  tabnew
259  tabnext 3
260  mksession! Xtest_mks.out
261  tabnew
262  tabnew
263  tabnext 2
264  source Xtest_mks.out
265  call assert_equal(4, tabpagenr('$'), 'session restore should restore number of tabs')
266  call assert_equal(3, tabpagenr(), 'session restore should restore the active tab')
267  call delete('Xtest_mks.out')
268endfunc
269
270func Test_mksession_buffer_count()
271  set hidden
272
273  " Edit exactly three files in the current session.
274  %bwipe!
275  e Xfoo | tabe Xbar | tabe Xbaz
276  tabdo write
277  mksession! Xtest_mks.out
278
279  " Verify that loading the session does not create additional buffers.
280  %bwipe!
281  source Xtest_mks.out
282  call assert_equal(3, len(getbufinfo()))
283
284  " Clean up.
285  call delete('Xfoo')
286  call delete('Xbar')
287  call delete('Xbaz')
288  call delete('Xtest_mks.out')
289  %bwipe!
290  set hidden&
291endfunc
292
293if has('extra_search')
294
295func Test_mksession_hlsearch()
296  set hlsearch
297  mksession! Xtest_mks.out
298  nohlsearch
299  source Xtest_mks.out
300  call assert_equal(1, v:hlsearch, 'session should restore search highlighting state')
301  nohlsearch
302  mksession! Xtest_mks.out
303  source Xtest_mks.out
304  call assert_equal(0, v:hlsearch, 'session should restore search highlighting state')
305  call delete('Xtest_mks.out')
306endfunc
307
308endif
309
310
311func Test_mksession_blank_windows()
312  split
313  split
314  split
315  3 wincmd w
316  mksession! Xtest_mks.out
317  split
318  split
319  2 wincmd w
320  source Xtest_mks.out
321  call assert_equal(4, winnr('$'), 'session restore should restore number of windows')
322  call assert_equal(3, winnr(), 'session restore should restore the active window')
323  call delete('Xtest_mks.out')
324endfunc
325
326if has('terminal')
327
328func Test_mksession_terminal_shell()
329  terminal
330  mksession! Xtest_mks.out
331  let lines = readfile('Xtest_mks.out')
332  let term_cmd = ''
333  for line in lines
334    if line =~ '^terminal'
335      let term_cmd = line
336    elseif line =~ 'badd.*' . &shell
337      call assert_report('unexpected shell line: ' . line)
338    endif
339  endfor
340  call assert_match('terminal ++curwin ++cols=\d\+ ++rows=\d\+\s*.*$', term_cmd)
341
342  call StopShellInTerminal(bufnr('%'))
343  call delete('Xtest_mks.out')
344endfunc
345
346func Test_mksession_terminal_no_restore_cmdarg()
347  terminal ++norestore
348  mksession! Xtest_mks.out
349  let lines = readfile('Xtest_mks.out')
350  let term_cmd = ''
351  for line in lines
352    if line =~ '^terminal'
353      call assert_report('session must not restore teminal')
354    endif
355  endfor
356
357  call StopShellInTerminal(bufnr('%'))
358  call delete('Xtest_mks.out')
359endfunc
360
361func Test_mksession_terminal_no_restore_funcarg()
362  call term_start(&shell, {'norestore': 1})
363  mksession! Xtest_mks.out
364  let lines = readfile('Xtest_mks.out')
365  let term_cmd = ''
366  for line in lines
367    if line =~ '^terminal'
368      call assert_report('session must not restore teminal')
369    endif
370  endfor
371
372  call StopShellInTerminal(bufnr('%'))
373  call delete('Xtest_mks.out')
374endfunc
375
376func Test_mksession_terminal_no_restore_func()
377  terminal
378  call term_setrestore(bufnr('%'), 'NONE')
379  mksession! Xtest_mks.out
380  let lines = readfile('Xtest_mks.out')
381  let term_cmd = ''
382  for line in lines
383    if line =~ '^terminal'
384      call assert_report('session must not restore teminal')
385    endif
386  endfor
387
388  call StopShellInTerminal(bufnr('%'))
389  call delete('Xtest_mks.out')
390endfunc
391
392func Test_mksession_terminal_no_ssop()
393  terminal
394  set sessionoptions-=terminal
395  mksession! Xtest_mks.out
396  let lines = readfile('Xtest_mks.out')
397  let term_cmd = ''
398  for line in lines
399    if line =~ '^terminal'
400      call assert_report('session must not restore teminal')
401    endif
402  endfor
403
404  call StopShellInTerminal(bufnr('%'))
405  call delete('Xtest_mks.out')
406  set sessionoptions&
407endfunc
408
409func Test_mksession_terminal_restore_other()
410  terminal
411  call term_setrestore(bufnr('%'), 'other')
412  mksession! Xtest_mks.out
413  let lines = readfile('Xtest_mks.out')
414  let term_cmd = ''
415  for line in lines
416    if line =~ '^terminal'
417      let term_cmd = line
418    endif
419  endfor
420  call assert_match('terminal ++curwin ++cols=\d\+ ++rows=\d\+.*other', term_cmd)
421
422  call StopShellInTerminal(bufnr('%'))
423  call delete('Xtest_mks.out')
424endfunc
425
426endif " has('terminal')
427
428" Test :mkview with a file argument.
429func Test_mkview_file()
430  " Create a view with line number and a fold.
431  help :mkview
432  set number
433  norm! V}zf0
434  let pos = getpos('.')
435  let linefoldclosed1 = foldclosed('.')
436  mkview! Xview
437  set nonumber
438  norm! zrj
439  " We can close the help window, as mkview with a file name should
440  " generate a command to edit the file.
441  helpclose
442
443  source Xview
444  call assert_equal(1, &number)
445  call assert_match('\*:mkview\*$', getline('.'))
446  call assert_equal(pos, getpos('.'))
447  call assert_equal(linefoldclosed1, foldclosed('.'))
448
449  " Creating a view again with the same file name should fail (file
450  " already exists). But with a !, the previous view should be
451  " overwritten without error.
452  help :loadview
453  call assert_fails('mkview Xview', 'E189:')
454  call assert_match('\*:loadview\*$', getline('.'))
455  mkview! Xview
456  call assert_match('\*:loadview\*$', getline('.'))
457
458  call delete('Xview')
459  bwipe
460endfunc
461
462" Test :mkview and :loadview with a custom 'viewdir'.
463func Test_mkview_loadview_with_viewdir()
464  set viewdir=Xviewdir
465
466  help :mkview
467  set number
468  norm! V}zf
469  let pos = getpos('.')
470  let linefoldclosed1 = foldclosed('.')
471  mkview 1
472  set nonumber
473  norm! zrj
474
475  loadview 1
476
477  " The directory Xviewdir/ should have been created and the view
478  " should be stored in that directory.
479  call assert_equal('Xviewdir/' .
480        \           substitute(
481        \             substitute(
482        \               expand('%:p'), '/', '=+', 'g'), ':', '=-', 'g') . '=1.vim',
483        \           glob('Xviewdir/*'))
484  call assert_equal(1, &number)
485  call assert_match('\*:mkview\*$', getline('.'))
486  call assert_equal(pos, getpos('.'))
487  call assert_equal(linefoldclosed1, foldclosed('.'))
488
489  call delete('Xviewdir', 'rf')
490  set viewdir&
491  helpclose
492endfunc
493
494func Test_mkview_no_file_name()
495  new
496  " :mkview or :mkview {nr} should fail in a unnamed buffer.
497  call assert_fails('mkview', 'E32:')
498  call assert_fails('mkview 1', 'E32:')
499
500  " :mkview {file} should succeed in a unnamed buffer.
501  mkview Xview
502  help
503  source Xview
504  call assert_equal('', bufname('%'))
505
506  call delete('Xview')
507  %bwipe
508endfunc
509
510" A clean session (one empty buffer, one window, and one tab) should not
511" set any error messages when sourced because no commands should fail.
512func Test_mksession_no_errmsg()
513  let v:errmsg = ''
514  %bwipe!
515  mksession! Xtest_mks.out
516  source Xtest_mks.out
517  call assert_equal('', v:errmsg)
518  call delete('Xtest_mks.out')
519endfunc
520
521func Test_mksession_quote_in_filename()
522  if !has('unix')
523    " only Unix can handle this weird filename
524    return
525  endif
526  let v:errmsg = ''
527  %bwipe!
528  split another
529  split x'y\"z
530  mksession! Xtest_mks_quoted.out
531  %bwipe!
532  source Xtest_mks_quoted.out
533  call assert_true(bufexists("x'y\"z"))
534
535  %bwipe!
536  call delete('Xtest_mks_quoted.out')
537endfunc
538
539func s:ClearMappings()
540  mapclear
541  omapclear
542  mapclear!
543  lmapclear
544  tmapclear
545endfunc
546
547func Test_mkvimrc()
548  let entries = [
549        \ ['', 'nothing', '<Nop>'],
550        \ ['n', 'normal', 'NORMAL'],
551        \ ['v', 'visual', 'VISUAL'],
552        \ ['s', 'select', 'SELECT'],
553        \ ['x', 'visualonly', 'VISUALONLY'],
554        \ ['o', 'operator', 'OPERATOR'],
555        \ ['i', 'insert', 'INSERT'],
556        \ ['l', 'lang', 'LANG'],
557        \ ['c', 'command', 'COMMAND'],
558        \ ['t', 'terminal', 'TERMINAL'],
559        \ ]
560  for entry in entries
561    exe entry[0] .. 'map ' .. entry[1] .. ' ' .. entry[2]
562  endfor
563
564  mkvimrc Xtestvimrc
565
566  call s:ClearMappings()
567  for entry in entries
568    call assert_equal('', maparg(entry[1], entry[0]))
569  endfor
570
571  source Xtestvimrc
572
573  for entry in entries
574    call assert_equal(entry[2], maparg(entry[1], entry[0]))
575  endfor
576
577  call s:ClearMappings()
578  call delete('Xtestvimrc')
579endfunc
580
581
582" vim: shiftwidth=2 sts=2 expandtab
583