xref: /vim-8.2.3635/src/testdir/test_tabpage.vim (revision 2d2970ea)
1" Tests for tabpage
2
3source screendump.vim
4source check.vim
5
6function Test_tabpage()
7  CheckFeature quickfix
8
9  bw!
10  " Simple test for opening and closing a tab page
11  tabnew
12  call assert_equal(2, tabpagenr())
13  quit
14
15  " Open three tab pages and use ":tabdo"
16  0tabnew
17  1tabnew
18  $tabnew
19  %del
20  tabdo call append(line('$'), tabpagenr())
21  tabclose! 2
22  tabrewind
23  let line1 = getline('$')
24  undo
25  q
26  tablast
27  let line2 = getline('$')
28  q!
29  call append(line('$'), line1)
30  call append(line('$'), line2)
31  unlet line1 line2
32  call assert_equal(['', '3', '1', '4'], getline(1, '$'))
33  "
34  " Test for settabvar() and gettabvar() functions. Open a new tab page and
35  " set 3 variables to a number, string and a list. Verify that the variables
36  " are correctly set.
37  tabnew
38  tabfirst
39  call settabvar(2, 'val_num', 100)
40  eval 'SetTabVar test'->settabvar(2, 'val_str')
41  call settabvar(2, 'val_list', ['red', 'blue', 'green'])
42  "
43  call assert_true(gettabvar(2, 'val_num') == 100 && gettabvar(2, 'val_str') == 'SetTabVar test' && gettabvar(2, 'val_list') == ['red', 'blue', 'green'])
44
45  tabnext 2
46  call assert_true(t:val_num == 100 && t:val_str == 'SetTabVar test'  && t:val_list == ['red', 'blue', 'green'])
47  tabclose
48
49  " Test for ":tab drop exist-file" to keep current window.
50  sp test1
51  tab drop test1
52  call assert_true(tabpagenr('$') == 1 && winnr('$') == 2 && winnr() == 1)
53  close
54  "
55  "
56  " Test for ":tab drop new-file" to keep current window of tabpage 1.
57  split
58  tab drop newfile
59  call assert_true(tabpagenr('$') == 2 && tabpagewinnr(1, '$') == 2 && tabpagewinnr(1) == 1)
60  tabclose
61  q
62  "
63  "
64  " Test for ":tab drop multi-opened-file" to keep current tabpage and window.
65  new test1
66  tabnew
67  new test1
68  tab drop test1
69  call assert_true(tabpagenr() == 2 && tabpagewinnr(2, '$') == 2 && tabpagewinnr(2) == 1)
70  tabclose
71  q
72  "
73  "
74  " Test for ":tab drop vertical-split-window" to jump test1 buffer
75  tabedit test1
76  vnew
77  tabfirst
78  tab drop test1
79  call assert_equal([2, 2, 2, 2], [tabpagenr('$'), tabpagenr(), tabpagewinnr(2, '$'), tabpagewinnr(2)])
80  1tabonly
81  "
82  "
83  for i in range(9) | tabnew | endfor
84  normal! 1gt
85  call assert_equal(1, tabpagenr())
86  tabmove 5
87  call assert_equal(5, tabpagenr())
88  .tabmove
89  call assert_equal(5, tabpagenr())
90  tabmove -
91  call assert_equal(4, tabpagenr())
92  tabmove +
93  call assert_equal(5, tabpagenr())
94  tabmove -2
95  call assert_equal(3, tabpagenr())
96  tabmove +4
97  call assert_equal(7, tabpagenr())
98  tabmove
99  call assert_equal(10, tabpagenr())
100  0tabmove
101  call assert_equal(1, tabpagenr())
102  $tabmove
103  call assert_equal(10, tabpagenr())
104  tabmove 0
105  call assert_equal(1, tabpagenr())
106  tabmove $
107  call assert_equal(10, tabpagenr())
108  3tabmove
109  call assert_equal(4, tabpagenr())
110  7tabmove 5
111  call assert_equal(5, tabpagenr())
112  -tabmove
113  call assert_equal(4, tabpagenr())
114  +tabmove
115  call assert_equal(5, tabpagenr())
116  -2tabmove
117  call assert_equal(3, tabpagenr())
118  +3tabmove
119  call assert_equal(6, tabpagenr())
120
121  " The following are a no-op
122  norm! 2gt
123  call assert_equal(2, tabpagenr())
124  tabmove 2
125  call assert_equal(2, tabpagenr())
126  2tabmove
127  call assert_equal(2, tabpagenr())
128  tabmove 1
129  call assert_equal(2, tabpagenr())
130  1tabmove
131  call assert_equal(2, tabpagenr())
132
133  call assert_fails('let t = tabpagenr("#")', 'E15:')
134  call assert_equal(0, tabpagewinnr(-1))
135  call assert_fails("99tabmove", 'E16:')
136  call assert_fails("+99tabmove", 'E16:')
137  call assert_fails("-99tabmove", 'E16:')
138  call assert_fails("tabmove foo", 'E474:')
139  call assert_fails("tabmove 99", 'E474:')
140  call assert_fails("tabmove +99", 'E474:')
141  call assert_fails("tabmove -99", 'E474:')
142  call assert_fails("tabmove -3+", 'E474:')
143  call assert_fails("tabmove $3", 'E474:')
144  call assert_fails("%tabonly", 'E16:')
145  1tabonly!
146  tabnew
147  call assert_fails("-2tabmove", 'E474:')
148  tabonly!
149endfunc
150
151" Test autocommands
152function Test_tabpage_with_autocmd()
153  command -nargs=1 -bar C :call add(s:li, '=== ' . <q-args> . ' ===')|<args>
154  augroup TestTabpageGroup
155    au!
156    autocmd TabEnter * call add(s:li, 'TabEnter')
157    autocmd WinEnter * call add(s:li, 'WinEnter')
158    autocmd BufEnter * call add(s:li, 'BufEnter')
159    autocmd TabLeave * call add(s:li, 'TabLeave')
160    autocmd WinLeave * call add(s:li, 'WinLeave')
161    autocmd BufLeave * call add(s:li, 'BufLeave')
162  augroup END
163
164  let s:li = []
165  let t:a='a'
166  C tab split
167  call assert_equal(['=== tab split ===', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter'], s:li)
168  let s:li = []
169  let t:a='b'
170  C tabnew
171  call assert_equal(['=== tabnew ===', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', 'BufLeave', 'BufEnter'], s:li)
172  let t:a='c'
173  let s:li = split(join(map(range(1, tabpagenr('$')), 'gettabvar(v:val, "a")')) , '\s\+')
174  call assert_equal(['a', 'b', 'c'], s:li)
175
176  let s:li = []
177  C call map(range(1, tabpagenr('$')), 'settabvar(v:val, ''a'', v:val*2)')
178  call assert_equal(["=== call map(range(1, tabpagenr('$')), 'settabvar(v:val, ''a'', v:val*2)') ==="], s:li)
179  let s:li = split(join(map(range(1, tabpagenr('$')), 'gettabvar(v:val, "a")')) , '\s\+')
180  call assert_equal(['2', '4', '6'], s:li)
181
182  let s:li = []
183  let w:a='a'
184  C vsplit
185  call assert_equal(['=== vsplit ===', 'WinLeave', 'WinEnter'], s:li)
186  let s:li = []
187  let w:a='a'
188  let tabn=tabpagenr()
189  let winr=range(1, winnr('$'))
190  C tabnext 1
191  call assert_equal(['=== tabnext 1 ===', 'BufLeave', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', 'BufEnter'], s:li)
192  let s:li = split(join(map(copy(winr), 'gettabwinvar('.tabn.', v:val, "a")')), '\s\+')
193  call assert_equal(['a', 'a'], s:li)
194  let s:li = []
195  C call map(copy(winr), '(v:val*2)->settabwinvar(' .. tabn .. ', v:val, ''a'')')
196  let s:li = split(join(map(copy(winr), 'gettabwinvar('.tabn.', v:val, "a")')), '\s\+')
197  call assert_equal(['2', '4'], s:li)
198
199  augroup TabDestructive
200    autocmd TabEnter * :C tabnext 2 | C tabclose 3
201  augroup END
202  let s:li = []
203  C tabnext 3
204  call assert_equal(['=== tabnext 3 ===', 'BufLeave', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', '=== tabnext 2 ===', '=== tabclose 3 ==='], s:li)
205  call assert_equal(['2/2'], [tabpagenr().'/'.tabpagenr('$')])
206
207  autocmd! TabDestructive TabEnter
208  let s:li = []
209  C tabnew
210  call assert_equal(['=== tabnew ===', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', 'BufLeave', 'BufEnter'], s:li)
211  let s:li = []
212  C tabnext 1
213  call assert_equal(['=== tabnext 1 ===', 'BufLeave', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', 'BufEnter'], s:li)
214
215  autocmd TabDestructive TabEnter * nested :C tabnext 2 | C tabclose 3
216  let s:li = []
217  call assert_equal(3, tabpagenr('$'))
218  C tabnext 2
219  call assert_equal(2, tabpagenr('$'))
220  call assert_equal(['=== tabnext 2 ===', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', '=== tabnext 2 ===', '=== tabclose 3 ==='], s:li)
221  call assert_equal(['2/2'], [tabpagenr().'/'.tabpagenr('$')])
222
223  delcommand C
224  autocmd! TabDestructive
225  augroup! TabDestructive
226  autocmd! TestTabpageGroup
227  augroup! TestTabpageGroup
228  1tabonly!
229endfunction
230
231" Test autocommands on tab drop
232function Test_tabpage_with_autocmd_tab_drop()
233  augroup TestTabpageGroup
234    au!
235    autocmd TabEnter * call add(s:li, 'TabEnter')
236    autocmd WinEnter * call add(s:li, 'WinEnter')
237    autocmd BufEnter * call add(s:li, 'BufEnter')
238    autocmd TabLeave * call add(s:li, 'TabLeave')
239    autocmd WinLeave * call add(s:li, 'WinLeave')
240    autocmd BufLeave * call add(s:li, 'BufLeave')
241  augroup END
242
243  let s:li = []
244  tab drop test1
245  call assert_equal(['BufLeave', 'BufEnter'], s:li)
246
247  let s:li = []
248  tab drop test2 test3
249  call assert_equal([
250        \ 'TabLeave', 'TabEnter', 'TabLeave', 'TabEnter',
251        \ 'TabLeave', 'WinEnter', 'TabEnter', 'BufEnter',
252        \ 'TabLeave', 'WinEnter', 'TabEnter', 'BufEnter'], s:li)
253
254  autocmd! TestTabpageGroup
255  augroup! TestTabpageGroup
256  1tabonly!
257endfunction
258
259function Test_tabpage_with_tab_modifier()
260  CheckFeature quickfix
261
262  for n in range(4)
263    tabedit
264  endfor
265
266  function s:check_tab(pre_nr, cmd, post_nr)
267    exec 'tabnext ' . a:pre_nr
268    exec a:cmd
269    call assert_equal(a:post_nr, tabpagenr())
270    call assert_equal('help', &buftype)
271    helpclose
272  endfunc
273
274  call s:check_tab(1, 'tab help', 2)
275  call s:check_tab(1, '3tab help', 4)
276  call s:check_tab(1, '.tab help', 2)
277  call s:check_tab(1, '.+1tab help', 3)
278  call s:check_tab(1, '0tab help', 1)
279  call s:check_tab(2, '+tab help', 4)
280  call s:check_tab(2, '+2tab help', 5)
281  call s:check_tab(4, '-tab help', 4)
282  call s:check_tab(4, '-2tab help', 3)
283  call s:check_tab(3, '$tab help', 6)
284  call assert_fails('99tab help', 'E16:')
285  call assert_fails('+99tab help', 'E16:')
286  call assert_fails('-99tab help', 'E16:')
287
288  delfunction s:check_tab
289  1tabonly!
290endfunction
291
292function Check_tab_count(pre_nr, cmd, post_nr)
293  exec 'tabnext' a:pre_nr
294  normal! G
295  exec a:cmd
296  call assert_equal(a:post_nr, tabpagenr(), a:cmd)
297endfunc
298
299" Test for [count] of tabnext
300function Test_tabpage_with_tabnext()
301  for n in range(4)
302    tabedit
303    call setline(1, ['', '', '3'])
304  endfor
305
306  call Check_tab_count(1, 'tabnext', 2)
307  call Check_tab_count(1, '3tabnext', 3)
308  call Check_tab_count(1, '.tabnext', 1)
309  call Check_tab_count(1, '.+1tabnext', 2)
310  call Check_tab_count(2, '+tabnext', 3)
311  call Check_tab_count(2, '+2tabnext', 4)
312  call Check_tab_count(4, '-tabnext', 3)
313  call Check_tab_count(4, '-2tabnext', 2)
314  call Check_tab_count(3, '$tabnext', 5)
315  call assert_fails('0tabnext', 'E16:')
316  call assert_fails('99tabnext', 'E16:')
317  call assert_fails('+99tabnext', 'E16:')
318  call assert_fails('-99tabnext', 'E16:')
319  call Check_tab_count(1, 'tabnext 3', 3)
320  call Check_tab_count(2, 'tabnext +', 3)
321  call Check_tab_count(2, 'tabnext +2', 4)
322  call Check_tab_count(4, 'tabnext -', 3)
323  call Check_tab_count(4, 'tabnext -2', 2)
324  call Check_tab_count(3, 'tabnext $', 5)
325  call assert_fails('tabnext 0', 'E474:')
326  call assert_fails('tabnext .', 'E474:')
327  call assert_fails('tabnext -+', 'E474:')
328  call assert_fails('tabnext +2-', 'E474:')
329  call assert_fails('tabnext $3', 'E474:')
330  call assert_fails('tabnext 99', 'E474:')
331  call assert_fails('tabnext +99', 'E474:')
332  call assert_fails('tabnext -99', 'E474:')
333
334  1tabonly!
335endfunction
336
337" Test for [count] of tabprevious
338function Test_tabpage_with_tabprevious()
339  for n in range(5)
340    tabedit
341    call setline(1, ['', '', '3'])
342  endfor
343
344  for cmd in ['tabNext', 'tabprevious']
345    call Check_tab_count(6, cmd, 5)
346    call Check_tab_count(6, '3' . cmd, 3)
347    call Check_tab_count(6, '8' . cmd, 4)
348    call Check_tab_count(6, cmd . ' 3', 3)
349    call Check_tab_count(6, cmd . ' 8', 4)
350    for n in range(2)
351      for c in ['0', '.+3', '+', '+2' , '-', '-2' , '$', '+99', '-99']
352        if n == 0 " pre count
353          let entire_cmd = c . cmd
354          let err_code = 'E16:'
355        else
356          let entire_cmd = cmd . ' ' . c
357          let err_code = 'E474:'
358        endif
359        call assert_fails(entire_cmd, err_code)
360      endfor
361    endfor
362  endfor
363
364  1tabonly!
365endfunction
366
367function s:reconstruct_tabpage_for_test(nr)
368  let n = (a:nr > 2) ? a:nr - 2 : 1
369  1tabonly!
370  0tabedit n0
371  for n in range(1, n)
372    exec '$tabedit n' . n
373    if n == 1
374      call setline(1, ['', '', '3'])
375    endif
376  endfor
377endfunc
378
379func Test_tabpage_ctrl_pgup_pgdown()
380  enew!
381  tabnew tab1
382  tabnew tab2
383
384  call assert_equal(3, tabpagenr())
385  exe "norm! \<C-PageUp>"
386  call assert_equal(2, tabpagenr())
387  exe "norm! \<C-PageDown>"
388  call assert_equal(3, tabpagenr())
389
390  " Check wrapping at last or first page.
391  exe "norm! \<C-PageDown>"
392  call assert_equal(1, tabpagenr())
393  exe "norm! \<C-PageUp>"
394  call assert_equal(3, tabpagenr())
395
396 " With a count, <C-PageUp> and <C-PageDown> are not symmetrical somehow:
397 " - {count}<C-PageUp> goes {count} pages downward (relative count)
398 " - {count}<C-PageDown> goes to page number {count} (absolute count)
399  exe "norm! 2\<C-PageUp>"
400  call assert_equal(1, tabpagenr())
401  exe "norm! 2\<C-PageDown>"
402  call assert_equal(2, tabpagenr())
403
404  1tabonly!
405endfunc
406
407" Test for [count] of tabclose
408function Test_tabpage_with_tabclose()
409
410  " pre count
411  call s:reconstruct_tabpage_for_test(6)
412  call Check_tab_count(3, 'tabclose!', 3)
413  call Check_tab_count(1, '3tabclose', 1)
414  call Check_tab_count(4, '4tabclose', 3)
415  call Check_tab_count(3, '1tabclose', 2)
416  call Check_tab_count(2, 'tabclose', 1)
417  call assert_equal(1, tabpagenr('$'))
418  call assert_equal('', bufname(''))
419
420  call s:reconstruct_tabpage_for_test(6)
421  call Check_tab_count(2, '$tabclose', 2)
422  call Check_tab_count(4, '.tabclose', 4)
423  call Check_tab_count(3, '.+tabclose', 3)
424  call Check_tab_count(3, '.-2tabclose', 2)
425  call Check_tab_count(1, '.+1tabclose!', 1)
426  call assert_equal(1, tabpagenr('$'))
427  call assert_equal('', bufname(''))
428
429  " post count
430  call s:reconstruct_tabpage_for_test(6)
431  call Check_tab_count(3, 'tabclose!', 3)
432  call Check_tab_count(1, 'tabclose 3', 1)
433  call Check_tab_count(4, 'tabclose 4', 3)
434  call Check_tab_count(3, 'tabclose 1', 2)
435  call Check_tab_count(2, 'tabclose', 1)
436  call assert_equal(1, tabpagenr('$'))
437  call assert_equal('', bufname(''))
438
439  call s:reconstruct_tabpage_for_test(6)
440  call Check_tab_count(2, 'tabclose $', 2)
441  call Check_tab_count(4, 'tabclose', 4)
442  call Check_tab_count(3, 'tabclose +', 3)
443  call Check_tab_count(3, 'tabclose -2', 2)
444  call Check_tab_count(1, 'tabclose! +1', 1)
445  call assert_equal(1, tabpagenr('$'))
446  call assert_equal('', bufname(''))
447
448  call s:reconstruct_tabpage_for_test(6)
449  for n in range(2)
450    for c in ['0', '$3', '99', '+99', '-99']
451      if n == 0 " pre count
452        let entire_cmd = c . 'tabclose'
453        let err_code = 'E16:'
454      else
455        let entire_cmd = 'tabclose ' . c
456        let err_code = 'E474:'
457      endif
458      call assert_fails(entire_cmd, err_code)
459      call assert_equal(6, tabpagenr('$'))
460    endfor
461  endfor
462
463  call assert_fails('3tabclose', 'E37:')
464  call assert_fails('tabclose 3', 'E37:')
465  call assert_fails('tabclose -+', 'E474:')
466  call assert_fails('tabclose +2-', 'E474:')
467  call assert_equal(6, tabpagenr('$'))
468
469  1tabonly!
470endfunction
471
472" Test for [count] of tabonly
473function Test_tabpage_with_tabonly()
474
475  " Test for the normal behavior (pre count only)
476  let tc = [ [4, '.', '!'], [2, '.+', ''], [3, '.-2', '!'], [1, '.+1', '!'] ]
477  for c in tc
478    call s:reconstruct_tabpage_for_test(6)
479    let entire_cmd = c[1] . 'tabonly' . c[2]
480    call Check_tab_count(c[0], entire_cmd, 1)
481    call assert_equal(1, tabpagenr('$'))
482  endfor
483
484  " Test for the normal behavior
485  let tc2 = [ [3, '', ''], [1, '3', ''], [4, '4', '!'], [3, '1', '!'],
486        \    [2, '', '!'],
487        \    [2, '$', '!'], [3, '+', '!'], [3, '-2', '!'], [3, '+1', '!']
488        \  ]
489  for n in range(2)
490    for c in tc2
491      call s:reconstruct_tabpage_for_test(6)
492      if n == 0 " pre count
493        let entire_cmd = c[1] . 'tabonly' . c[2]
494      else
495        let entire_cmd = 'tabonly' . c[2] . ' ' . c[1]
496      endif
497      call Check_tab_count(c[0], entire_cmd, 1)
498      call assert_equal(1, tabpagenr('$'))
499    endfor
500  endfor
501
502  " Test for the error behavior
503  for n in range(2)
504    for c in ['0', '$3', '99', '+99', '-99']
505      call s:reconstruct_tabpage_for_test(6)
506      if n == 0 " pre count
507        let entire_cmd = c . 'tabonly'
508        let err_code = 'E16:'
509      else
510        let entire_cmd = 'tabonly ' . c
511        let err_code = 'E474:'
512      endif
513      call assert_fails(entire_cmd, err_code)
514      call assert_equal(6, tabpagenr('$'))
515    endfor
516  endfor
517
518  " Test for the error behavior (post count only)
519  for c in tc
520    call s:reconstruct_tabpage_for_test(6)
521    let entire_cmd = 'tabonly' . c[2] . ' ' . c[1]
522    let err_code = 'E474:'
523    call assert_fails(entire_cmd, err_code)
524    call assert_equal(6, tabpagenr('$'))
525  endfor
526
527  call assert_fails('tabonly -+', 'E474:')
528  call assert_fails('tabonly +2-', 'E474:')
529  call assert_equal(6, tabpagenr('$'))
530
531  1tabonly!
532  new
533  only!
534endfunction
535
536func Test_tabnext_on_buf_unload1()
537  " This once caused a crash
538  new
539  tabedit
540  tabfirst
541  au BufUnload <buffer> tabnext
542  q
543
544  while tabpagenr('$') > 1
545    bwipe!
546  endwhile
547endfunc
548
549func Test_tabnext_on_buf_unload2()
550  " This once caused a crash
551  tabedit
552  autocmd BufUnload <buffer> tabnext
553  file x
554  edit y
555
556  while tabpagenr('$') > 1
557    bwipe!
558  endwhile
559endfunc
560
561func Test_close_on_quitpre()
562  " This once caused a crash
563  edit Xtest
564  new
565  only
566  set bufhidden=delete
567  au QuitPre <buffer> close
568  tabnew tab1
569  tabnew tab2
570  1tabn
571  q!
572  call assert_equal(1, tabpagenr())
573  call assert_equal(2, tabpagenr('$'))
574  " clean up
575  while tabpagenr('$') > 1
576    bwipe!
577  endwhile
578  buf Xtest
579endfunc
580
581func Test_tabs()
582  enew!
583  tabnew tab1
584  norm ixxx
585  let a=split(execute(':tabs'), "\n")
586  call assert_equal(['Tab page 1',
587      \              '    [No Name]',
588      \              'Tab page 2',
589      \              '> + tab1'], a)
590
591  1tabonly!
592  bw!
593endfunc
594
595func Test_tabpage_cmdheight()
596  if !CanRunVimInTerminal()
597    throw 'Skipped: cannot make screendumps'
598  endif
599  call writefile([
600        \ 'set laststatus=2',
601        \ 'set cmdheight=2',
602        \ 'tabnew',
603        \ 'set cmdheight=3',
604        \ 'tabnext',
605        \ 'redraw!',
606        \ 'echo "hello\nthere"',
607        \ 'tabnext',
608        \ 'redraw',
609	\ ], 'XTest_tabpage_cmdheight')
610  " Check that cursor line is concealed
611  let buf = RunVimInTerminal('-S XTest_tabpage_cmdheight', {'statusoff': 3})
612  call VerifyScreenDump(buf, 'Test_tabpage_cmdheight', {})
613
614  call StopVimInTerminal(buf)
615  call delete('XTest_tabpage_cmdheight')
616endfunc
617
618" Test for closing the tab page from a command window
619func Test_tabpage_close_cmdwin()
620  tabnew
621  call feedkeys("q/:tabclose\<CR>\<Esc>", 'xt')
622  call assert_equal(2, tabpagenr('$'))
623  call feedkeys("q/:tabonly\<CR>\<Esc>", 'xt')
624  call assert_equal(2, tabpagenr('$'))
625  tabonly
626endfunc
627
628" vim: shiftwidth=2 sts=2 expandtab
629