1" Tests for window cmd (:wincmd, :split, :vsplit, :resize and etc...)
2
3so check.vim
4
5func Test_window_cmd_ls0_with_split()
6  set ls=0
7  set splitbelow
8  split
9  quit
10  call assert_equal(0, &lines - &cmdheight - winheight(0))
11  new | only!
12  "
13  set splitbelow&vim
14  botright split
15  quit
16  call assert_equal(0, &lines - &cmdheight - winheight(0))
17  new | only!
18  set ls&vim
19endfunc
20
21func Test_window_cmd_cmdwin_with_vsp()
22  let efmt = 'Expected 0 but got %d (in ls=%d, %s window)'
23  for v in range(0, 2)
24    exec "set ls=" . v
25    vsplit
26    call feedkeys("q:\<CR>")
27    let ac = &lines - (&cmdheight + winheight(0) + !!v)
28    let emsg = printf(efmt, ac, v, 'left')
29    call assert_equal(0, ac, emsg)
30    wincmd w
31    let ac = &lines - (&cmdheight + winheight(0) + !!v)
32    let emsg = printf(efmt, ac, v, 'right')
33    call assert_equal(0, ac, emsg)
34    new | only!
35  endfor
36  set ls&vim
37endfunc
38
39function Test_window_cmd_wincmd_gf()
40  let fname = 'test_gf.txt'
41  let swp_fname = '.' . fname . '.swp'
42  call writefile([], fname)
43  call writefile([], swp_fname)
44  function s:swap_exists()
45    let v:swapchoice = s:swap_choice
46  endfunc
47  " Remove the catch-all that runtest.vim adds
48  au! SwapExists
49  augroup test_window_cmd_wincmd_gf
50    autocmd!
51    exec "autocmd SwapExists " . fname . " call s:swap_exists()"
52  augroup END
53
54  call setline(1, fname)
55  " (E)dit anyway
56  let s:swap_choice = 'e'
57  wincmd gf
58  call assert_equal(2, tabpagenr())
59  call assert_equal(fname, bufname("%"))
60  quit!
61
62  " (Q)uit
63  let s:swap_choice = 'q'
64  wincmd gf
65  call assert_equal(1, tabpagenr())
66  call assert_notequal(fname, bufname("%"))
67  new | only!
68
69  call delete(fname)
70  call delete(swp_fname)
71  augroup! test_window_cmd_wincmd_gf
72endfunc
73
74func Test_window_quit()
75  e Xa
76  split Xb
77  call assert_equal(2, '$'->winnr())
78  call assert_equal('Xb', bufname(winbufnr(1)))
79  call assert_equal('Xa', bufname(winbufnr(2)))
80
81  wincmd q
82  call assert_equal(1, winnr('$'))
83  call assert_equal('Xa', bufname(winbufnr(1)))
84
85  bw Xa Xb
86endfunc
87
88func Test_window_horizontal_split()
89  call assert_equal(1, winnr('$'))
90  3wincmd s
91  call assert_equal(2, winnr('$'))
92  call assert_equal(3, winheight(0))
93  call assert_equal(winwidth(1), 2->winwidth())
94
95  call assert_fails('botright topleft wincmd s', 'E442:')
96  bw
97endfunc
98
99func Test_window_vertical_split()
100  call assert_equal(1, winnr('$'))
101  3wincmd v
102  call assert_equal(2, winnr('$'))
103  call assert_equal(3, winwidth(0))
104  call assert_equal(winheight(1), winheight(2))
105
106  call assert_fails('botright topleft wincmd v', 'E442:')
107  bw
108endfunc
109
110" Test the ":wincmd ^" and "<C-W>^" commands.
111func Test_window_split_edit_alternate()
112
113  " Test for failure when the alternate buffer/file no longer exists.
114  edit Xfoo | %bw
115  call assert_fails(':wincmd ^', 'E23')
116
117  " Test for the expected behavior when we have two named buffers.
118  edit Xfoo | edit Xbar
119  wincmd ^
120  call assert_equal('Xfoo', bufname(winbufnr(1)))
121  call assert_equal('Xbar', bufname(winbufnr(2)))
122  only
123
124  " Test for the expected behavior when the alternate buffer is not named.
125  enew | let l:nr1 = bufnr('%')
126  edit Xfoo | let l:nr2 = bufnr('%')
127  wincmd ^
128  call assert_equal(l:nr1, winbufnr(1))
129  call assert_equal(l:nr2, winbufnr(2))
130  only
131
132  " FIXME: this currently fails on AppVeyor, but passes locally
133  if !has('win32')
134    " Test the Normal mode command.
135    call feedkeys("\<C-W>\<C-^>", 'tx')
136    call assert_equal(l:nr2, winbufnr(1))
137    call assert_equal(l:nr1, winbufnr(2))
138  endif
139
140  %bw!
141endfunc
142
143" Test the ":[count]wincmd ^" and "[count]<C-W>^" commands.
144func Test_window_split_edit_bufnr()
145
146  %bwipeout
147  let l:nr = bufnr('%') + 1
148  call assert_fails(':execute "normal! ' . l:nr . '\<C-W>\<C-^>"', 'E92')
149  call assert_fails(':' . l:nr . 'wincmd ^', 'E16')
150  call assert_fails(':0wincmd ^', 'E16')
151
152  edit Xfoo | edit Xbar | edit Xbaz
153  let l:foo_nr = bufnr('Xfoo')
154  let l:bar_nr = bufnr('Xbar')
155  let l:baz_nr = bufnr('Xbaz')
156
157  " FIXME: this currently fails on AppVeyor, but passes locally
158  if !has('win32')
159    call feedkeys(l:foo_nr . "\<C-W>\<C-^>", 'tx')
160    call assert_equal('Xfoo', bufname(winbufnr(1)))
161    call assert_equal('Xbaz', bufname(winbufnr(2)))
162    only
163
164    call feedkeys(l:bar_nr . "\<C-W>\<C-^>", 'tx')
165    call assert_equal('Xbar', bufname(winbufnr(1)))
166    call assert_equal('Xfoo', bufname(winbufnr(2)))
167    only
168
169    execute l:baz_nr . 'wincmd ^'
170    call assert_equal('Xbaz', bufname(winbufnr(1)))
171    call assert_equal('Xbar', bufname(winbufnr(2)))
172  endif
173
174  %bw!
175endfunc
176
177func Test_window_split_no_room()
178  " N horizontal windows need >= 2*N + 1 lines:
179  " - 1 line + 1 status line in each window
180  " - 1 Ex command line
181  "
182  " 2*N + 1 <= &lines
183  " N <= (lines - 1)/2
184  "
185  " Beyond that number of windows, E36: Not enough room is expected.
186  let hor_win_count = (&lines - 1)/2
187  let hor_split_count = hor_win_count - 1
188  for s in range(1, hor_split_count) | split | endfor
189  call assert_fails('split', 'E36:')
190
191  " N vertical windows need >= 2*(N - 1) + 1 columns:
192  " - 1 column + 1 separator for each window (except last window)
193  " - 1 column for the last window which does not have separator
194  "
195  " 2*(N - 1) + 1 <= &columns
196  " 2*N - 1 <= &columns
197  " N <= (&columns + 1)/2
198  let ver_win_count = (&columns + 1)/2
199  let ver_split_count = ver_win_count - 1
200  for s in range(1, ver_split_count) | vsplit | endfor
201  call assert_fails('vsplit', 'E36:')
202
203  %bw!
204endfunc
205
206func Test_window_preview()
207  CheckFeature quickfix
208
209  " Open a preview window
210  pedit Xa
211  call assert_equal(2, winnr('$'))
212  call assert_equal(0, &previewwindow)
213
214  " Go to the preview window
215  wincmd P
216  call assert_equal(1, &previewwindow)
217
218  " Close preview window
219  wincmd z
220  call assert_equal(1, winnr('$'))
221  call assert_equal(0, &previewwindow)
222
223  call assert_fails('wincmd P', 'E441:')
224endfunc
225
226func Test_window_preview_from_help()
227  CheckFeature quickfix
228
229  filetype on
230  call writefile(['/* some C code */'], 'Xpreview.c')
231  help
232  pedit Xpreview.c
233  wincmd P
234  call assert_equal(1, &previewwindow)
235  call assert_equal('c', &filetype)
236  wincmd z
237
238  filetype off
239  close
240  call delete('Xpreview.c')
241endfunc
242
243func Test_window_exchange()
244  e Xa
245
246  " Nothing happens with window exchange when there is 1 window
247  wincmd x
248  call assert_equal(1, winnr('$'))
249
250  split Xb
251  split Xc
252
253  call assert_equal('Xc', bufname(winbufnr(1)))
254  call assert_equal('Xb', bufname(winbufnr(2)))
255  call assert_equal('Xa', bufname(winbufnr(3)))
256
257  " Exchange current window 1 with window 3
258  3wincmd x
259  call assert_equal('Xa', bufname(winbufnr(1)))
260  call assert_equal('Xb', bufname(winbufnr(2)))
261  call assert_equal('Xc', bufname(winbufnr(3)))
262
263  " Exchange window with next when at the top window
264  wincmd x
265  call assert_equal('Xb', bufname(winbufnr(1)))
266  call assert_equal('Xa', bufname(winbufnr(2)))
267  call assert_equal('Xc', bufname(winbufnr(3)))
268
269  " Exchange window with next when at the middle window
270  wincmd j
271  wincmd x
272  call assert_equal('Xb', bufname(winbufnr(1)))
273  call assert_equal('Xc', bufname(winbufnr(2)))
274  call assert_equal('Xa', bufname(winbufnr(3)))
275
276  " Exchange window with next when at the bottom window.
277  " When there is no next window, it exchanges with the previous window.
278  wincmd j
279  wincmd x
280  call assert_equal('Xb', bufname(winbufnr(1)))
281  call assert_equal('Xa', bufname(winbufnr(2)))
282  call assert_equal('Xc', bufname(winbufnr(3)))
283
284  bw Xa Xb Xc
285endfunc
286
287func Test_window_rotate()
288  e Xa
289  split Xb
290  split Xc
291  call assert_equal('Xc', bufname(winbufnr(1)))
292  call assert_equal('Xb', bufname(winbufnr(2)))
293  call assert_equal('Xa', bufname(winbufnr(3)))
294
295  " Rotate downwards
296  wincmd r
297  call assert_equal('Xa', bufname(winbufnr(1)))
298  call assert_equal('Xc', bufname(winbufnr(2)))
299  call assert_equal('Xb', bufname(winbufnr(3)))
300
301  2wincmd r
302  call assert_equal('Xc', bufname(winbufnr(1)))
303  call assert_equal('Xb', bufname(winbufnr(2)))
304  call assert_equal('Xa', bufname(winbufnr(3)))
305
306  " Rotate upwards
307  wincmd R
308  call assert_equal('Xb', bufname(winbufnr(1)))
309  call assert_equal('Xa', bufname(winbufnr(2)))
310  call assert_equal('Xc', bufname(winbufnr(3)))
311
312  2wincmd R
313  call assert_equal('Xc', bufname(winbufnr(1)))
314  call assert_equal('Xb', bufname(winbufnr(2)))
315  call assert_equal('Xa', bufname(winbufnr(3)))
316
317  bot vsplit
318  call assert_fails('wincmd R', 'E443:')
319
320  bw Xa Xb Xc
321endfunc
322
323func Test_window_height()
324  e Xa
325  split Xb
326
327  let [wh1, wh2] = [winheight(1), winheight(2)]
328  " Active window (1) should have the same height or 1 more
329  " than the other window.
330  call assert_inrange(wh2, wh2 + 1, wh1)
331
332  wincmd -
333  call assert_equal(wh1 - 1, winheight(1))
334  call assert_equal(wh2 + 1, winheight(2))
335
336  wincmd +
337  call assert_equal(wh1, winheight(1))
338  call assert_equal(wh2, 2->winheight())
339
340  2wincmd _
341  call assert_equal(2, winheight(1))
342  call assert_equal(wh1 + wh2 - 2, winheight(2))
343
344  wincmd =
345  call assert_equal(wh1, winheight(1))
346  call assert_equal(wh2, winheight(2))
347
348  2wincmd _
349  set winfixheight
350  split Xc
351  let [wh1, wh2, wh3] = [winheight(1), winheight(2), winheight(3)]
352  call assert_equal(2, winheight(2))
353  call assert_inrange(wh3, wh3 + 1, wh1)
354  3wincmd +
355  call assert_equal(2,       winheight(2))
356  call assert_equal(wh1 + 3, winheight(1))
357  call assert_equal(wh3 - 3, winheight(3))
358  wincmd =
359  call assert_equal(2,   winheight(2))
360  call assert_equal(wh1, winheight(1))
361  call assert_equal(wh3, winheight(3))
362
363  wincmd j
364  set winfixheight&
365
366  wincmd =
367  let [wh1, wh2, wh3] = [winheight(1), winheight(2), winheight(3)]
368  " Current window (2) should have the same height or 1 more
369  " than the other windows.
370  call assert_inrange(wh1, wh1 + 1, wh2)
371  call assert_inrange(wh3, wh3 + 1, wh2)
372
373  bw Xa Xb Xc
374endfunc
375
376func Test_window_width()
377  e Xa
378  vsplit Xb
379
380  let [ww1, ww2] = [winwidth(1), winwidth(2)]
381  " Active window (1) should have the same width or 1 more
382  " than the other window.
383  call assert_inrange(ww2, ww2 + 1, ww1)
384
385  wincmd <
386  call assert_equal(ww1 - 1, winwidth(1))
387  call assert_equal(ww2 + 1, winwidth(2))
388
389  wincmd >
390  call assert_equal(ww1, winwidth(1))
391  call assert_equal(ww2, winwidth(2))
392
393  2wincmd |
394  call assert_equal(2, winwidth(1))
395  call assert_equal(ww1 + ww2 - 2, winwidth(2))
396
397  wincmd =
398  call assert_equal(ww1, winwidth(1))
399  call assert_equal(ww2, winwidth(2))
400
401  2wincmd |
402  set winfixwidth
403  vsplit Xc
404  let [ww1, ww2, ww3] = [winwidth(1), winwidth(2), winwidth(3)]
405  call assert_equal(2, winwidth(2))
406  call assert_inrange(ww3, ww3 + 1, ww1)
407  3wincmd >
408  call assert_equal(2,       winwidth(2))
409  call assert_equal(ww1 + 3, winwidth(1))
410  call assert_equal(ww3 - 3, winwidth(3))
411  wincmd =
412  call assert_equal(2,   winwidth(2))
413  call assert_equal(ww1, winwidth(1))
414  call assert_equal(ww3, winwidth(3))
415
416  wincmd l
417  set winfixwidth&
418
419  wincmd =
420  let [ww1, ww2, ww3] = [winwidth(1), winwidth(2), winwidth(3)]
421  " Current window (2) should have the same width or 1 more
422  " than the other windows.
423  call assert_inrange(ww1, ww1 + 1, ww2)
424  call assert_inrange(ww3, ww3 + 1, ww2)
425
426  bw Xa Xb Xc
427endfunc
428
429func Test_equalalways_on_close()
430  set equalalways
431  vsplit
432  windo split
433  split
434  wincmd J
435  " now we have a frame top-left with two windows, a frame top-right with two
436  " windows and a frame at the bottom, full-width.
437  let height_1 = winheight(1)
438  let height_2 = winheight(2)
439  let height_3 = winheight(3)
440  let height_4 = winheight(4)
441  " closing the bottom window causes all windows to be resized.
442  close
443  call assert_notequal(height_1, winheight(1))
444  call assert_notequal(height_2, winheight(2))
445  call assert_notequal(height_3, winheight(3))
446  call assert_notequal(height_4, winheight(4))
447  call assert_equal(winheight(1), winheight(3))
448  call assert_equal(winheight(2), winheight(4))
449
450  1wincmd w
451  split
452  4wincmd w
453  resize + 5
454  " left column has three windows, equalized heights.
455  " right column has two windows, top one a bit higher
456  let height_1 = winheight(1)
457  let height_2 = winheight(2)
458  let height_4 = winheight(4)
459  let height_5 = winheight(5)
460  3wincmd w
461  " closing window in left column equalizes heights in left column but not in
462  " the right column
463  close
464  call assert_notequal(height_1, winheight(1))
465  call assert_notequal(height_2, winheight(2))
466  call assert_equal(height_4, winheight(3))
467  call assert_equal(height_5, winheight(4))
468
469  only
470  set equalalways&
471endfunc
472
473func Test_win_screenpos()
474  CheckFeature quickfix
475
476  call assert_equal(1, winnr('$'))
477  split
478  vsplit
479  10wincmd _
480  30wincmd |
481  call assert_equal([1, 1], win_screenpos(1))
482  call assert_equal([1, 32], win_screenpos(2))
483  call assert_equal([12, 1], win_screenpos(3))
484  call assert_equal([0, 0], win_screenpos(4))
485  only
486endfunc
487
488func Test_window_jump_tag()
489  CheckFeature quickfix
490
491  help
492  /iccf
493  call assert_match('^|iccf|',  getline('.'))
494  call assert_equal(2, winnr('$'))
495  2wincmd }
496  call assert_equal(3, winnr('$'))
497  call assert_match('^|iccf|',  getline('.'))
498  wincmd k
499  call assert_match('\*iccf\*',  getline('.'))
500  call assert_equal(2, winheight(0))
501
502  wincmd z
503  set previewheight=4
504  help
505  /bugs
506  wincmd }
507  wincmd k
508  call assert_match('\*bugs\*',  getline('.'))
509  call assert_equal(4, winheight(0))
510  set previewheight&
511
512  %bw!
513endfunc
514
515func Test_window_newtab()
516  e Xa
517
518  call assert_equal(1, tabpagenr('$'))
519  call assert_equal("\nAlready only one window", execute('wincmd T'))
520
521  split Xb
522  split Xc
523
524  wincmd T
525  call assert_equal(2, tabpagenr('$'))
526  call assert_equal(['Xb', 'Xa'], map(tabpagebuflist(1), 'bufname(v:val)'))
527  call assert_equal(['Xc'      ], map(2->tabpagebuflist(), 'bufname(v:val)'))
528  call assert_equal(['Xc'      ], map(tabpagebuflist(), 'bufname(v:val)'))
529
530  %bw!
531endfunc
532
533func Test_next_split_all()
534  " This was causing an illegal memory access.
535  n x
536  norm axxx
537  split
538  split
539  s/x
540  s/x
541  all
542  bwipe!
543endfunc
544
545" Tests for adjusting window and contents
546func GetScreenStr(row)
547   let str = ""
548   for c in range(1,3)
549       let str .= nr2char(screenchar(a:row, c))
550   endfor
551   return str
552endfunc
553
554func Test_window_contents()
555  enew! | only | new
556  call setline(1, range(1,256))
557
558  exe "norm! \<C-W>t\<C-W>=1Gzt\<C-W>w\<C-W>+"
559  redraw
560  let s3 = GetScreenStr(1)
561  wincmd p
562  call assert_equal(1, line("w0"))
563  call assert_equal('1  ', s3)
564
565  exe "norm! \<C-W>t\<C-W>=50Gzt\<C-W>w\<C-W>+"
566  redraw
567  let s3 = GetScreenStr(1)
568  wincmd p
569  call assert_equal(50, line("w0"))
570  call assert_equal('50 ', s3)
571
572  exe "norm! \<C-W>t\<C-W>=59Gzt\<C-W>w\<C-W>+"
573  redraw
574  let s3 = GetScreenStr(1)
575  wincmd p
576  call assert_equal(59, line("w0"))
577  call assert_equal('59 ', s3)
578
579  %d
580  call setline(1, ['one', 'two', 'three'])
581  call assert_equal(1, line('w0'))
582  call assert_equal(3, line('w$'))
583
584  bwipeout!
585  call test_garbagecollect_now()
586endfunc
587
588func Test_window_colon_command()
589  " This was reading invalid memory.
590  exe "norm! v\<C-W>:\<C-U>echo v:version"
591endfunc
592
593func Test_access_freed_mem()
594  call assert_equal(&columns, winwidth(0))
595  " This was accessing freed memory
596  au * 0 vs xxx
597  arg 0
598  argadd
599  call assert_fails("all", "E249:")
600  au!
601  bwipe xxx
602  call assert_equal(&columns, winwidth(0))
603endfunc
604
605func Test_insert_cleared_on_switch_to_term()
606  CheckFeature terminal
607
608  set showmode
609  terminal
610  wincmd p
611
612  call feedkeys("i\<C-O>", 'ntx')
613  redraw
614
615  " The "-- (insert) --" indicator should be visible.
616  let chars = map(range(1, &columns), 'nr2char(screenchar(&lines, v:val))')
617  let str = trim(join(chars, ''))
618  call assert_equal('-- (insert) --', str)
619
620  call feedkeys("\<C-W>p", 'ntx')
621  redraw
622
623  " The "-- (insert) --" indicator should have been cleared.
624  let chars = map(range(1, &columns), 'nr2char(screenchar(&lines, v:val))')
625  let str = trim(join(chars, ''))
626  call assert_equal('', str)
627
628  set showmode&
629  %bw!
630endfunc
631
632func Test_visual_cleared_after_window_split()
633  new | only!
634  let smd_save = &showmode
635  set showmode
636  let ls_save = &laststatus
637  set laststatus=1
638  call setline(1, ['a', 'b', 'c', 'd', ''])
639  norm! G
640  exe "norm! kkvk"
641  redraw
642  exe "norm! \<C-W>v"
643  redraw
644  " check if '-- VISUAL --' disappeared from command line
645  let columns = range(1, &columns)
646  let cmdlinechars = map(columns, 'nr2char(screenchar(&lines, v:val))')
647  let cmdline = join(cmdlinechars, '')
648  let cmdline_ltrim = substitute(cmdline, '^\s*', "", "")
649  let mode_shown = substitute(cmdline_ltrim, '\s*$', "", "")
650  call assert_equal('', mode_shown)
651  let &showmode = smd_save
652  let &laststatus = ls_save
653  bwipe!
654endfunc
655
656func Test_winrestcmd()
657  2split
658  3vsplit
659  let a = winrestcmd()
660  call assert_equal(2, winheight(0))
661  call assert_equal(3, winwidth(0))
662  wincmd =
663  call assert_notequal(2, winheight(0))
664  call assert_notequal(3, winwidth(0))
665  exe a
666  call assert_equal(2, winheight(0))
667  call assert_equal(3, winwidth(0))
668  only
669endfunc
670
671func Fun_RenewFile()
672  " Need to wait a bit for the timestamp to be older.
673  let old_ftime = getftime("tmp.txt")
674  while getftime("tmp.txt") == old_ftime
675    sleep 100m
676    silent execute '!echo "1" > tmp.txt'
677  endwhile
678  sp
679  wincmd p
680  edit! tmp.txt
681endfunc
682
683func Test_window_prevwin()
684  " Can we make this work on MS-Windows?
685  if !has('unix')
686    return
687  endif
688
689  set hidden autoread
690  call writefile(['2'], 'tmp.txt')
691  new tmp.txt
692  q
693  call Fun_RenewFile()
694  call assert_equal(2, winnr())
695  wincmd p
696  call assert_equal(1, winnr())
697  wincmd p
698  q
699  call Fun_RenewFile()
700  call assert_equal(2, winnr())
701  wincmd p
702  call assert_equal(1, winnr())
703  wincmd p
704  " reset
705  q
706  call delete('tmp.txt')
707  set hidden&vim autoread&vim
708  delfunc Fun_RenewFile
709endfunc
710
711func Test_relative_cursor_position_in_one_line_window()
712  new
713  only
714  call setline(1, range(1, 10000))
715  normal 50%
716  let lnum = getcurpos()[1]
717  split
718  split
719  " make third window take as many lines as possible, other windows will
720  " become one line
721  3wincmd w
722  for i in range(1, &lines - 6)
723    wincmd +
724    redraw!
725  endfor
726
727  " first and second window should show cursor line
728  let wininfo = getwininfo()
729  call assert_equal(lnum, wininfo[0].topline)
730  call assert_equal(lnum, wininfo[1].topline)
731
732  only!
733  bwipe!
734endfunc
735
736func Test_relative_cursor_position_after_move_and_resize()
737  let so_save = &so
738  set so=0
739  enew
740  call setline(1, range(1, 10000))
741  normal 50%
742  split
743  1wincmd w
744  " Move cursor to first line in window
745  normal H
746  redraw!
747  " Reduce window height to two lines
748  let height = winheight(0)
749  while winheight(0) > 2
750    wincmd -
751    redraw!
752  endwhile
753  " move cursor to second/last line in window
754  normal j
755  " restore previous height
756  while winheight(0) < height
757    wincmd +
758    redraw!
759  endwhile
760  " make window two lines again
761  while winheight(0) > 2
762    wincmd -
763    redraw!
764  endwhile
765
766  " cursor should be at bottom line
767  let info = getwininfo(win_getid())[0]
768  call assert_equal(info.topline + 1, getcurpos()[1])
769
770  only!
771  bwipe!
772  let &so = so_save
773endfunc
774
775func Test_relative_cursor_position_after_resize()
776  let so_save = &so
777  set so=0
778  enew
779  call setline(1, range(1, 10000))
780  normal 50%
781  split
782  1wincmd w
783  let winid1 = win_getid()
784  let info = getwininfo(winid1)[0]
785  " Move cursor to second line in window
786  exe "normal " . (info.topline + 1) . "G"
787  redraw!
788  let lnum = getcurpos()[1]
789
790  " Make the window only two lines high, cursor should end up in top line
791  2wincmd w
792  exe (info.height - 2) . "wincmd +"
793  redraw!
794  let info = getwininfo(winid1)[0]
795  call assert_equal(lnum, info.topline)
796
797  only!
798  bwipe!
799  let &so = so_save
800endfunc
801
802func Test_relative_cursor_second_line_after_resize()
803  let so_save = &so
804  set so=0
805  enew
806  call setline(1, range(1, 10000))
807  normal 50%
808  split
809  1wincmd w
810  let winid1 = win_getid()
811  let info = getwininfo(winid1)[0]
812
813  " Make the window only two lines high
814  2wincmd _
815
816  " Move cursor to second line in window
817  normal H
818  normal j
819
820  " Make window size bigger, then back to 2 lines
821  for i in range(1, 10)
822    wincmd +
823    redraw!
824  endfor
825  for i in range(1, 10)
826    wincmd -
827    redraw!
828  endfor
829
830  " cursor should end up in bottom line
831  let info = getwininfo(winid1)[0]
832  call assert_equal(info.topline + 1, getcurpos()[1])
833
834  only!
835  bwipe!
836  let &so = so_save
837endfunc
838
839func Test_split_noscroll()
840  let so_save = &so
841  enew
842  call setline(1, range(1, 8))
843  normal 100%
844  split
845
846  1wincmd w
847  let winid1 = win_getid()
848  let info1 = getwininfo(winid1)[0]
849
850  2wincmd w
851  let winid2 = win_getid()
852  let info2 = getwininfo(winid2)[0]
853
854  call assert_equal(1, info1.topline)
855  call assert_equal(1, info2.topline)
856
857  " window that fits all lines by itself, but not when split: closing other
858  " window should restore fraction.
859  only!
860  call setline(1, range(1, &lines - 10))
861  exe &lines / 4
862  let winid1 = win_getid()
863  let info1 = getwininfo(winid1)[0]
864  call assert_equal(1, info1.topline)
865  new
866  redraw
867  close
868  let info1 = getwininfo(winid1)[0]
869  call assert_equal(1, info1.topline)
870
871  bwipe!
872  let &so = so_save
873endfunc
874
875" Tests for the winnr() function
876func Test_winnr()
877  only | tabonly
878  call assert_equal(1, winnr('j'))
879  call assert_equal(1, winnr('k'))
880  call assert_equal(1, winnr('h'))
881  call assert_equal(1, winnr('l'))
882
883  " create a set of horizontally and vertically split windows
884  leftabove new | wincmd p
885  leftabove new | wincmd p
886  rightbelow new | wincmd p
887  rightbelow new | wincmd p
888  leftabove vnew | wincmd p
889  leftabove vnew | wincmd p
890  rightbelow vnew | wincmd p
891  rightbelow vnew | wincmd p
892
893  call assert_equal(8, winnr('j'))
894  call assert_equal(2, winnr('k'))
895  call assert_equal(4, winnr('h'))
896  call assert_equal(6, winnr('l'))
897  call assert_equal(9, winnr('2j'))
898  call assert_equal(1, winnr('2k'))
899  call assert_equal(3, winnr('2h'))
900  call assert_equal(7, winnr('2l'))
901
902  " Error cases
903  call assert_fails("echo winnr('0.2k')", 'E15:')
904  call assert_equal(2, winnr('-2k'))
905  call assert_fails("echo winnr('-2xj')", 'E15:')
906  call assert_fails("echo winnr('j2j')", 'E15:')
907  call assert_fails("echo winnr('ll')", 'E15:')
908  call assert_fails("echo winnr('5')", 'E15:')
909  call assert_equal(4, winnr('0h'))
910
911  tabnew
912  call assert_equal(8, tabpagewinnr(1, 'j'))
913  call assert_equal(2, 1->tabpagewinnr('k'))
914  call assert_equal(4, tabpagewinnr(1, 'h'))
915  call assert_equal(6, tabpagewinnr(1, 'l'))
916
917  only | tabonly
918endfunc
919
920func Test_winrestview()
921  split runtest.vim
922  normal 50%
923  let view = winsaveview()
924  close
925  split runtest.vim
926  eval view->winrestview()
927  call assert_equal(view, winsaveview())
928
929  bwipe!
930endfunc
931
932func Test_win_splitmove()
933  CheckFeature quickfix
934
935  edit a
936  leftabove split b
937  leftabove vsplit c
938  leftabove split d
939  call assert_equal(0, win_splitmove(winnr(), winnr('l')))
940  call assert_equal(bufname(winbufnr(1)), 'c')
941  call assert_equal(bufname(winbufnr(2)), 'd')
942  call assert_equal(bufname(winbufnr(3)), 'b')
943  call assert_equal(bufname(winbufnr(4)), 'a')
944  call assert_equal(0, win_splitmove(winnr(), winnr('j'), {'vertical': 1}))
945  call assert_equal(0, win_splitmove(winnr(), winnr('j'), {'vertical': 1}))
946  call assert_equal(bufname(winbufnr(1)), 'c')
947  call assert_equal(bufname(winbufnr(2)), 'b')
948  call assert_equal(bufname(winbufnr(3)), 'd')
949  call assert_equal(bufname(winbufnr(4)), 'a')
950  call assert_equal(0, win_splitmove(winnr(), winnr('k'), {'vertical': 1}))
951  call assert_equal(bufname(winbufnr(1)), 'd')
952  call assert_equal(bufname(winbufnr(2)), 'c')
953  call assert_equal(bufname(winbufnr(3)), 'b')
954  call assert_equal(bufname(winbufnr(4)), 'a')
955  call assert_equal(0, win_splitmove(winnr(), winnr('j'), {'rightbelow': v:true}))
956  call assert_equal(bufname(winbufnr(1)), 'c')
957  call assert_equal(bufname(winbufnr(2)), 'b')
958  call assert_equal(bufname(winbufnr(3)), 'a')
959  call assert_equal(bufname(winbufnr(4)), 'd')
960  only | bd
961
962  call assert_fails('call win_splitmove(winnr(), 123)', 'E957:')
963  call assert_fails('call win_splitmove(123, winnr())', 'E957:')
964  call assert_fails('call win_splitmove(winnr(), winnr())', 'E957:')
965
966  tabnew
967  call assert_fails('call win_splitmove(1, win_getid(1, 1))', 'E957:')
968  tabclose
969endfunc
970
971" Test for the :only command
972func Test_window_only()
973  new
974  set modified
975  new
976  call assert_fails('only', 'E445:')
977  only!
978  " Test for :only with a count
979  let wid = win_getid()
980  new
981  new
982  3only
983  call assert_equal(1, winnr('$'))
984  call assert_equal(wid, win_getid())
985  call assert_fails('close', 'E444:')
986  call assert_fails('%close', 'E16:')
987endfunc
988
989" Test for errors with :wincmd
990func Test_wincmd_errors()
991  call assert_fails('wincmd g', 'E474:')
992  call assert_fails('wincmd ab', 'E474:')
993endfunc
994
995" Test for errors with :winpos
996func Test_winpos_errors()
997  if !has("gui_running") && !has('win32')
998    call assert_fails('winpos', 'E188:')
999  endif
1000  call assert_fails('winpos 10', 'E466:')
1001endfunc
1002
1003" Test for +cmd in a :split command
1004func Test_split_cmd()
1005  split +set\ readonly
1006  call assert_equal(1, &readonly)
1007  call assert_equal(2, winnr('$'))
1008  close
1009endfunc
1010
1011" Create maximum number of horizontally or vertically split windows and then
1012" run commands that create a new horizontally/vertically split window
1013func Run_noroom_for_newwindow_test(dir_arg)
1014  let dir = (a:dir_arg == 'v') ? 'vert ' : ''
1015
1016  " Open as many windows as possible
1017  while v:true
1018    try
1019      exe dir . 'new'
1020    catch /E36:/
1021      break
1022    endtry
1023  endwhile
1024
1025  call writefile(['first', 'second', 'third'], 'Xfile1')
1026  call writefile([], 'Xfile2')
1027  call writefile([], 'Xfile3')
1028
1029  " Argument list related commands
1030  args Xfile1 Xfile2 Xfile3
1031  next
1032  for cmd in ['sargument 2', 'snext', 'sprevious', 'sNext', 'srewind',
1033			\ 'sfirst', 'slast']
1034    call assert_fails(dir .. cmd, 'E36:')
1035  endfor
1036  %argdelete
1037
1038  " Buffer related commands
1039  set modified
1040  hide enew
1041  for cmd in ['sbuffer Xfile1', 'sbnext', 'sbprevious', 'sbNext', 'sbrewind',
1042		\ 'sbfirst', 'sblast', 'sball', 'sbmodified', 'sunhide']
1043    call assert_fails(dir .. cmd, 'E36:')
1044  endfor
1045
1046  " Window related commands
1047  for cmd in ['split', 'split Xfile2', 'new', 'new Xfile3', 'sview Xfile1',
1048		\ 'sfind runtest.vim']
1049    call assert_fails(dir .. cmd, 'E36:')
1050  endfor
1051
1052  " Help
1053  call assert_fails(dir .. 'help', 'E36:')
1054  call assert_fails(dir .. 'helpgrep window', 'E36:')
1055
1056  " Command-line window
1057  if a:dir_arg == 'h'
1058    " Cmd-line window is always a horizontally split window
1059    call assert_beeps('call feedkeys("q:\<CR>", "xt")')
1060  endif
1061
1062  " Quickfix and location list window
1063  if has('quickfix')
1064    cexpr ''
1065    call assert_fails(dir .. 'copen', 'E36:')
1066    lexpr ''
1067    call assert_fails(dir .. 'lopen', 'E36:')
1068
1069    " Preview window
1070    call assert_fails(dir .. 'pedit Xfile2', 'E36:')
1071    call setline(1, 'abc')
1072    call assert_fails(dir .. 'psearch abc', 'E36:')
1073  endif
1074
1075  " Window commands (CTRL-W ^ and CTRL-W f)
1076  if a:dir_arg == 'h'
1077    call assert_fails('call feedkeys("\<C-W>^", "xt")', 'E36:')
1078    call setline(1, 'Xfile1')
1079    call assert_fails('call feedkeys("gg\<C-W>f", "xt")', 'E36:')
1080  endif
1081  enew!
1082
1083  " Tag commands (:stag, :stselect and :stjump)
1084  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
1085        \ "second\tXfile1\t2",
1086        \ "third\tXfile1\t3",],
1087        \ 'Xtags')
1088  set tags=Xtags
1089  call assert_fails(dir .. 'stag second', 'E36:')
1090  call assert_fails('call feedkeys(":" .. dir .. "stselect second\n1\n", "xt")', 'E36:')
1091  call assert_fails(dir .. 'stjump second', 'E36:')
1092  call assert_fails(dir .. 'ptag second', 'E36:')
1093  set tags&
1094  call delete('Xtags')
1095
1096  " :isplit and :dsplit
1097  call setline(1, ['#define FOO 1', 'FOO'])
1098  normal 2G
1099  call assert_fails(dir .. 'isplit FOO', 'E36:')
1100  call assert_fails(dir .. 'dsplit FOO', 'E36:')
1101
1102  " terminal
1103  if has('terminal')
1104    call assert_fails(dir .. 'terminal', 'E36:')
1105  endif
1106
1107  %bwipe!
1108  call delete('Xfile1')
1109  call delete('Xfile2')
1110  call delete('Xfile3')
1111  only
1112endfunc
1113
1114func Test_split_cmds_with_no_room()
1115  call Run_noroom_for_newwindow_test('h')
1116  call Run_noroom_for_newwindow_test('v')
1117endfunc
1118
1119" vim: shiftwidth=2 sts=2 expandtab
1120