1" Test for :mksession, :mkview and :loadview in latin1 encoding
2
3set encoding=latin1
4scriptencoding latin1
5
6if !has('mksession')
7  finish
8endif
9
10source shared.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
213func Test_mksession_blank_tabs()
214  tabnew
215  tabnew
216  tabnew
217  tabnext 3
218  mksession! Xtest_mks.out
219  tabnew
220  tabnew
221  tabnext 2
222  source Xtest_mks.out
223  call assert_equal(4, tabpagenr('$'), 'session restore should restore number of tabs')
224  call assert_equal(3, tabpagenr(), 'session restore should restore the active tab')
225  call delete('Xtest_mks.out')
226endfunc
227
228func Test_mksession_buffer_count()
229  set hidden
230
231  " Edit exactly three files in the current session.
232  %bwipe!
233  e Xfoo | tabe Xbar | tabe Xbaz
234  tabdo write
235  mksession! Xtest_mks.out
236
237  " Verify that loading the session does not create additional buffers.
238  %bwipe!
239  source Xtest_mks.out
240  call assert_equal(3, len(getbufinfo()))
241
242  " Clean up.
243  call delete('Xfoo')
244  call delete('Xbar')
245  call delete('Xbaz')
246  call delete('Xtest_mks.out')
247  %bwipe!
248  set hidden&
249endfunc
250
251if has('extra_search')
252
253func Test_mksession_hlsearch()
254  set hlsearch
255  mksession! Xtest_mks.out
256  nohlsearch
257  source Xtest_mks.out
258  call assert_equal(1, v:hlsearch, 'session should restore search highlighting state')
259  nohlsearch
260  mksession! Xtest_mks.out
261  source Xtest_mks.out
262  call assert_equal(0, v:hlsearch, 'session should restore search highlighting state')
263  call delete('Xtest_mks.out')
264endfunc
265
266endif
267
268
269func Test_mksession_blank_windows()
270  split
271  split
272  split
273  3 wincmd w
274  mksession! Xtest_mks.out
275  split
276  split
277  2 wincmd w
278  source Xtest_mks.out
279  call assert_equal(4, winnr('$'), 'session restore should restore number of windows')
280  call assert_equal(3, winnr(), 'session restore should restore the active window')
281  call delete('Xtest_mks.out')
282endfunc
283
284if has('terminal')
285
286func Test_mksession_terminal_shell()
287  terminal
288  mksession! Xtest_mks.out
289  let lines = readfile('Xtest_mks.out')
290  let term_cmd = ''
291  for line in lines
292    if line =~ '^terminal'
293      let term_cmd = line
294    elseif line =~ 'badd.*' . &shell
295      call assert_report('unexpected shell line: ' . line)
296    endif
297  endfor
298  call assert_match('terminal ++curwin ++cols=\d\+ ++rows=\d\+\s*.*$', term_cmd)
299
300  call Stop_shell_in_terminal(bufnr('%'))
301  call delete('Xtest_mks.out')
302endfunc
303
304func Test_mksession_terminal_no_restore_cmdarg()
305  terminal ++norestore
306  mksession! Xtest_mks.out
307  let lines = readfile('Xtest_mks.out')
308  let term_cmd = ''
309  for line in lines
310    if line =~ '^terminal'
311      call assert_report('session must not restore teminal')
312    endif
313  endfor
314
315  call Stop_shell_in_terminal(bufnr('%'))
316  call delete('Xtest_mks.out')
317endfunc
318
319func Test_mksession_terminal_no_restore_funcarg()
320  call term_start(&shell, {'norestore': 1})
321  mksession! Xtest_mks.out
322  let lines = readfile('Xtest_mks.out')
323  let term_cmd = ''
324  for line in lines
325    if line =~ '^terminal'
326      call assert_report('session must not restore teminal')
327    endif
328  endfor
329
330  call Stop_shell_in_terminal(bufnr('%'))
331  call delete('Xtest_mks.out')
332endfunc
333
334func Test_mksession_terminal_no_restore_func()
335  terminal
336  call term_setrestore(bufnr('%'), 'NONE')
337  mksession! Xtest_mks.out
338  let lines = readfile('Xtest_mks.out')
339  let term_cmd = ''
340  for line in lines
341    if line =~ '^terminal'
342      call assert_report('session must not restore teminal')
343    endif
344  endfor
345
346  call Stop_shell_in_terminal(bufnr('%'))
347  call delete('Xtest_mks.out')
348endfunc
349
350func Test_mksession_terminal_no_ssop()
351  terminal
352  set sessionoptions-=terminal
353  mksession! Xtest_mks.out
354  let lines = readfile('Xtest_mks.out')
355  let term_cmd = ''
356  for line in lines
357    if line =~ '^terminal'
358      call assert_report('session must not restore teminal')
359    endif
360  endfor
361
362  call Stop_shell_in_terminal(bufnr('%'))
363  call delete('Xtest_mks.out')
364  set sessionoptions&
365endfunc
366
367func Test_mksession_terminal_restore_other()
368  terminal
369  call term_setrestore(bufnr('%'), 'other')
370  mksession! Xtest_mks.out
371  let lines = readfile('Xtest_mks.out')
372  let term_cmd = ''
373  for line in lines
374    if line =~ '^terminal'
375      let term_cmd = line
376    endif
377  endfor
378  call assert_match('terminal ++curwin ++cols=\d\+ ++rows=\d\+.*other', term_cmd)
379
380  call Stop_shell_in_terminal(bufnr('%'))
381  call delete('Xtest_mks.out')
382endfunc
383
384endif " has('terminal')
385
386" Test :mkview with a file argument.
387func Test_mkview_file()
388  " Create a view with line number and a fold.
389  help :mkview
390  set number
391  norm! V}zf0
392  let pos = getpos('.')
393  let linefoldclosed1 = foldclosed('.')
394  mkview! Xview
395  set nonumber
396  norm! zrj
397  " We can close the help window, as mkview with a file name should
398  " generate a command to edit the file.
399  helpclose
400
401  source Xview
402  call assert_equal(1, &number)
403  call assert_match('\*:mkview\*$', getline('.'))
404  call assert_equal(pos, getpos('.'))
405  call assert_equal(linefoldclosed1, foldclosed('.'))
406
407  " Creating a view again with the same file name should fail (file
408  " already exists). But with a !, the previous view should be
409  " overwritten without error.
410  help :loadview
411  call assert_fails('mkview Xview', 'E189:')
412  call assert_match('\*:loadview\*$', getline('.'))
413  mkview! Xview
414  call assert_match('\*:loadview\*$', getline('.'))
415
416  call delete('Xview')
417  bwipe
418endfunc
419
420" Test :mkview and :loadview with a custom 'viewdir'.
421func Test_mkview_loadview_with_viewdir()
422  set viewdir=Xviewdir
423
424  help :mkview
425  set number
426  norm! V}zf
427  let pos = getpos('.')
428  let linefoldclosed1 = foldclosed('.')
429  mkview 1
430  set nonumber
431  norm! zrj
432
433  loadview 1
434
435  " The directory Xviewdir/ should have been created and the view
436  " should be stored in that directory.
437  call assert_equal('Xviewdir/' .
438        \           substitute(
439        \             substitute(
440        \               expand('%:p'), '/', '=+', 'g'), ':', '=-', 'g') . '=1.vim',
441        \           glob('Xviewdir/*'))
442  call assert_equal(1, &number)
443  call assert_match('\*:mkview\*$', getline('.'))
444  call assert_equal(pos, getpos('.'))
445  call assert_equal(linefoldclosed1, foldclosed('.'))
446
447  call delete('Xviewdir', 'rf')
448  set viewdir&
449  helpclose
450endfunc
451
452func Test_mkview_no_file_name()
453  new
454  " :mkview or :mkview {nr} should fail in a unnamed buffer.
455  call assert_fails('mkview', 'E32:')
456  call assert_fails('mkview 1', 'E32:')
457
458  " :mkview {file} should succeed in a unnamed buffer.
459  mkview Xview
460  help
461  source Xview
462  call assert_equal('', bufname('%'))
463
464  call delete('Xview')
465  %bwipe
466endfunc
467
468" A clean session (one empty buffer, one window, and one tab) should not
469" set any error messages when sourced because no commands should fail.
470func Test_mksession_no_errmsg()
471  let v:errmsg = ''
472  %bwipe!
473  mksession! Xtest_mks.out
474  source Xtest_mks.out
475  call assert_equal('', v:errmsg)
476  call delete('Xtest_mks.out')
477endfunc
478
479func Test_mksession_quote_in_filename()
480  if !has('unix')
481    " only Unix can handle this weird filename
482    return
483  endif
484  let v:errmsg = ''
485  %bwipe!
486  split another
487  split x'y\"z
488  mksession! Xtest_mks_quoted.out
489  %bwipe!
490  source Xtest_mks_quoted.out
491  call assert_true(bufexists("x'y\"z"))
492
493  %bwipe!
494  call delete('Xtest_mks_quoted.out')
495endfunc
496
497
498" vim: shiftwidth=2 sts=2 expandtab
499