summaryrefslogtreecommitdiffstats
path: root/src/testdir/test_window_cmd.vim
diff options
context:
space:
mode:
Diffstat (limited to 'src/testdir/test_window_cmd.vim')
-rw-r--r--src/testdir/test_window_cmd.vim1340
1 files changed, 1340 insertions, 0 deletions
diff --git a/src/testdir/test_window_cmd.vim b/src/testdir/test_window_cmd.vim
new file mode 100644
index 0000000..07347a3
--- /dev/null
+++ b/src/testdir/test_window_cmd.vim
@@ -0,0 +1,1340 @@
+" Tests for window cmd (:wincmd, :split, :vsplit, :resize and etc...)
+
+source check.vim
+
+func Test_window_cmd_ls0_with_split()
+ set ls=0
+ set splitbelow
+ split
+ quit
+ call assert_equal(0, &lines - &cmdheight - winheight(0))
+ new | only!
+ "
+ set splitbelow&vim
+ botright split
+ quit
+ call assert_equal(0, &lines - &cmdheight - winheight(0))
+ new | only!
+ set ls&vim
+endfunc
+
+func Test_window_cmd_cmdwin_with_vsp()
+ CheckFeature cmdwin
+
+ let efmt = 'Expected 0 but got %d (in ls=%d, %s window)'
+ for v in range(0, 2)
+ exec "set ls=" . v
+ vsplit
+ call feedkeys("q:\<CR>")
+ let ac = &lines - (&cmdheight + winheight(0) + !!v)
+ let emsg = printf(efmt, ac, v, 'left')
+ call assert_equal(0, ac, emsg)
+ wincmd w
+ let ac = &lines - (&cmdheight + winheight(0) + !!v)
+ let emsg = printf(efmt, ac, v, 'right')
+ call assert_equal(0, ac, emsg)
+ new | only!
+ endfor
+ set ls&vim
+endfunc
+
+" Test for jumping to windows
+func Test_window_jump()
+ new
+ " jumping to a window with a count greater than the max windows
+ exe "normal 4\<C-W>w"
+ call assert_equal(2, winnr())
+ only
+endfunc
+
+func Test_window_cmd_wincmd_gf()
+ let fname = 'test_gf.txt'
+ let swp_fname = '.' . fname . '.swp'
+ call writefile([], fname)
+ call writefile([], swp_fname)
+ function s:swap_exists()
+ let v:swapchoice = s:swap_choice
+ endfunc
+ " Remove the catch-all that runtest.vim adds
+ au! SwapExists
+ augroup test_window_cmd_wincmd_gf
+ autocmd!
+ exec "autocmd SwapExists " . fname . " call s:swap_exists()"
+ augroup END
+
+ call setline(1, fname)
+ " (E)dit anyway
+ let s:swap_choice = 'e'
+ wincmd gf
+ call assert_equal(2, tabpagenr())
+ call assert_equal(fname, bufname("%"))
+ quit!
+
+ " (Q)uit
+ let s:swap_choice = 'q'
+ wincmd gf
+ call assert_equal(1, tabpagenr())
+ call assert_notequal(fname, bufname("%"))
+ new | only!
+
+ call delete(fname)
+ call delete(swp_fname)
+ augroup! test_window_cmd_wincmd_gf
+endfunc
+
+func Test_window_quit()
+ e Xa
+ split Xb
+ call assert_equal(2, '$'->winnr())
+ call assert_equal('Xb', bufname(winbufnr(1)))
+ call assert_equal('Xa', bufname(winbufnr(2)))
+
+ wincmd q
+ call assert_equal(1, winnr('$'))
+ call assert_equal('Xa', bufname(winbufnr(1)))
+
+ bw Xa Xb
+endfunc
+
+func Test_window_horizontal_split()
+ call assert_equal(1, winnr('$'))
+ 3wincmd s
+ call assert_equal(2, winnr('$'))
+ call assert_equal(3, winheight(0))
+ call assert_equal(winwidth(1), 2->winwidth())
+
+ call assert_fails('botright topleft wincmd s', 'E442:')
+ bw
+endfunc
+
+func Test_window_vertical_split()
+ call assert_equal(1, winnr('$'))
+ 3wincmd v
+ call assert_equal(2, winnr('$'))
+ call assert_equal(3, winwidth(0))
+ call assert_equal(winheight(1), winheight(2))
+
+ call assert_fails('botright topleft wincmd v', 'E442:')
+ bw
+endfunc
+
+" Test the ":wincmd ^" and "<C-W>^" commands.
+func Test_window_split_edit_alternate()
+
+ " Test for failure when the alternate buffer/file no longer exists.
+ edit Xfoo | %bw
+ call assert_fails(':wincmd ^', 'E23:')
+
+ " Test for the expected behavior when we have two named buffers.
+ edit Xfoo | edit Xbar
+ wincmd ^
+ call assert_equal('Xfoo', bufname(winbufnr(1)))
+ call assert_equal('Xbar', bufname(winbufnr(2)))
+ only
+
+ " Test for the expected behavior when the alternate buffer is not named.
+ enew | let l:nr1 = bufnr('%')
+ edit Xfoo | let l:nr2 = bufnr('%')
+ wincmd ^
+ call assert_equal(l:nr1, winbufnr(1))
+ call assert_equal(l:nr2, winbufnr(2))
+ only
+
+ " FIXME: this currently fails on AppVeyor, but passes locally
+ if !has('win32')
+ " Test the Normal mode command.
+ call feedkeys("\<C-W>\<C-^>", 'tx')
+ call assert_equal(l:nr2, winbufnr(1))
+ call assert_equal(l:nr1, winbufnr(2))
+ endif
+
+ %bw!
+endfunc
+
+" Test the ":[count]wincmd ^" and "[count]<C-W>^" commands.
+func Test_window_split_edit_bufnr()
+
+ %bwipeout
+ let l:nr = bufnr('%') + 1
+ call assert_fails(':execute "normal! ' . l:nr . '\<C-W>\<C-^>"', 'E92:')
+ call assert_fails(':' . l:nr . 'wincmd ^', 'E16:')
+ call assert_fails(':0wincmd ^', 'E16:')
+
+ edit Xfoo | edit Xbar | edit Xbaz
+ let l:foo_nr = bufnr('Xfoo')
+ let l:bar_nr = bufnr('Xbar')
+ let l:baz_nr = bufnr('Xbaz')
+
+ " FIXME: this currently fails on AppVeyor, but passes locally
+ if !has('win32')
+ call feedkeys(l:foo_nr . "\<C-W>\<C-^>", 'tx')
+ call assert_equal('Xfoo', bufname(winbufnr(1)))
+ call assert_equal('Xbaz', bufname(winbufnr(2)))
+ only
+
+ call feedkeys(l:bar_nr . "\<C-W>\<C-^>", 'tx')
+ call assert_equal('Xbar', bufname(winbufnr(1)))
+ call assert_equal('Xfoo', bufname(winbufnr(2)))
+ only
+
+ execute l:baz_nr . 'wincmd ^'
+ call assert_equal('Xbaz', bufname(winbufnr(1)))
+ call assert_equal('Xbar', bufname(winbufnr(2)))
+ endif
+
+ %bw!
+endfunc
+
+func Test_window_split_no_room()
+ " N horizontal windows need >= 2*N + 1 lines:
+ " - 1 line + 1 status line in each window
+ " - 1 Ex command line
+ "
+ " 2*N + 1 <= &lines
+ " N <= (lines - 1)/2
+ "
+ " Beyond that number of windows, E36: Not enough room is expected.
+ let hor_win_count = (&lines - 1)/2
+ let hor_split_count = hor_win_count - 1
+ for s in range(1, hor_split_count) | split | endfor
+ call assert_fails('split', 'E36:')
+
+ " N vertical windows need >= 2*(N - 1) + 1 columns:
+ " - 1 column + 1 separator for each window (except last window)
+ " - 1 column for the last window which does not have separator
+ "
+ " 2*(N - 1) + 1 <= &columns
+ " 2*N - 1 <= &columns
+ " N <= (&columns + 1)/2
+ let ver_win_count = (&columns + 1)/2
+ let ver_split_count = ver_win_count - 1
+ for s in range(1, ver_split_count) | vsplit | endfor
+ call assert_fails('vsplit', 'E36:')
+
+ %bw!
+endfunc
+
+func Test_window_exchange()
+ e Xa
+
+ " Nothing happens with window exchange when there is 1 window
+ wincmd x
+ call assert_equal(1, winnr('$'))
+
+ split Xb
+ split Xc
+
+ call assert_equal('Xc', bufname(winbufnr(1)))
+ call assert_equal('Xb', bufname(winbufnr(2)))
+ call assert_equal('Xa', bufname(winbufnr(3)))
+
+ " Exchange current window 1 with window 3
+ 3wincmd x
+ call assert_equal('Xa', bufname(winbufnr(1)))
+ call assert_equal('Xb', bufname(winbufnr(2)))
+ call assert_equal('Xc', bufname(winbufnr(3)))
+
+ " Exchange window with next when at the top window
+ wincmd x
+ call assert_equal('Xb', bufname(winbufnr(1)))
+ call assert_equal('Xa', bufname(winbufnr(2)))
+ call assert_equal('Xc', bufname(winbufnr(3)))
+
+ " Exchange window with next when at the middle window
+ wincmd j
+ wincmd x
+ call assert_equal('Xb', bufname(winbufnr(1)))
+ call assert_equal('Xc', bufname(winbufnr(2)))
+ call assert_equal('Xa', bufname(winbufnr(3)))
+
+ " Exchange window with next when at the bottom window.
+ " When there is no next window, it exchanges with the previous window.
+ wincmd j
+ wincmd x
+ call assert_equal('Xb', bufname(winbufnr(1)))
+ call assert_equal('Xa', bufname(winbufnr(2)))
+ call assert_equal('Xc', bufname(winbufnr(3)))
+
+ bw Xa Xb Xc
+endfunc
+
+func Test_window_rotate()
+ e Xa
+ split Xb
+ split Xc
+ call assert_equal('Xc', bufname(winbufnr(1)))
+ call assert_equal('Xb', bufname(winbufnr(2)))
+ call assert_equal('Xa', bufname(winbufnr(3)))
+
+ " Rotate downwards
+ wincmd r
+ call assert_equal('Xa', bufname(winbufnr(1)))
+ call assert_equal('Xc', bufname(winbufnr(2)))
+ call assert_equal('Xb', bufname(winbufnr(3)))
+
+ 2wincmd r
+ call assert_equal('Xc', bufname(winbufnr(1)))
+ call assert_equal('Xb', bufname(winbufnr(2)))
+ call assert_equal('Xa', bufname(winbufnr(3)))
+
+ " Rotate upwards
+ wincmd R
+ call assert_equal('Xb', bufname(winbufnr(1)))
+ call assert_equal('Xa', bufname(winbufnr(2)))
+ call assert_equal('Xc', bufname(winbufnr(3)))
+
+ 2wincmd R
+ call assert_equal('Xc', bufname(winbufnr(1)))
+ call assert_equal('Xb', bufname(winbufnr(2)))
+ call assert_equal('Xa', bufname(winbufnr(3)))
+
+ bot vsplit
+ call assert_fails('wincmd R', 'E443:')
+
+ bw Xa Xb Xc
+endfunc
+
+func Test_window_height()
+ e Xa
+ split Xb
+
+ let [wh1, wh2] = [winheight(1), winheight(2)]
+ " Active window (1) should have the same height or 1 more
+ " than the other window.
+ call assert_inrange(wh2, wh2 + 1, wh1)
+
+ wincmd -
+ call assert_equal(wh1 - 1, winheight(1))
+ call assert_equal(wh2 + 1, winheight(2))
+
+ wincmd +
+ call assert_equal(wh1, winheight(1))
+ call assert_equal(wh2, 2->winheight())
+
+ 2wincmd _
+ call assert_equal(2, winheight(1))
+ call assert_equal(wh1 + wh2 - 2, winheight(2))
+
+ wincmd =
+ call assert_equal(wh1, winheight(1))
+ call assert_equal(wh2, winheight(2))
+
+ 2wincmd _
+ set winfixheight
+ split Xc
+ let [wh1, wh2, wh3] = [winheight(1), winheight(2), winheight(3)]
+ call assert_equal(2, winheight(2))
+ call assert_inrange(wh3, wh3 + 1, wh1)
+ 3wincmd +
+ call assert_equal(2, winheight(2))
+ call assert_equal(wh1 + 3, winheight(1))
+ call assert_equal(wh3 - 3, winheight(3))
+ wincmd =
+ call assert_equal(2, winheight(2))
+ call assert_equal(wh1, winheight(1))
+ call assert_equal(wh3, winheight(3))
+
+ wincmd j
+ set winfixheight&
+
+ wincmd =
+ let [wh1, wh2, wh3] = [winheight(1), winheight(2), winheight(3)]
+ " Current window (2) should have the same height or 1 more
+ " than the other windows.
+ call assert_inrange(wh1, wh1 + 1, wh2)
+ call assert_inrange(wh3, wh3 + 1, wh2)
+
+ bw Xa Xb Xc
+endfunc
+
+func Test_window_width()
+ e Xa
+ vsplit Xb
+
+ let [ww1, ww2] = [winwidth(1), winwidth(2)]
+ " Active window (1) should have the same width or 1 more
+ " than the other window.
+ call assert_inrange(ww2, ww2 + 1, ww1)
+
+ wincmd <
+ call assert_equal(ww1 - 1, winwidth(1))
+ call assert_equal(ww2 + 1, winwidth(2))
+
+ wincmd >
+ call assert_equal(ww1, winwidth(1))
+ call assert_equal(ww2, winwidth(2))
+
+ 2wincmd |
+ call assert_equal(2, winwidth(1))
+ call assert_equal(ww1 + ww2 - 2, winwidth(2))
+
+ wincmd =
+ call assert_equal(ww1, winwidth(1))
+ call assert_equal(ww2, winwidth(2))
+
+ 2wincmd |
+ set winfixwidth
+ vsplit Xc
+ let [ww1, ww2, ww3] = [winwidth(1), winwidth(2), winwidth(3)]
+ call assert_equal(2, winwidth(2))
+ call assert_inrange(ww3, ww3 + 1, ww1)
+ 3wincmd >
+ call assert_equal(2, winwidth(2))
+ call assert_equal(ww1 + 3, winwidth(1))
+ call assert_equal(ww3 - 3, winwidth(3))
+ wincmd =
+ call assert_equal(2, winwidth(2))
+ call assert_equal(ww1, winwidth(1))
+ call assert_equal(ww3, winwidth(3))
+
+ wincmd l
+ set winfixwidth&
+
+ wincmd =
+ let [ww1, ww2, ww3] = [winwidth(1), winwidth(2), winwidth(3)]
+ " Current window (2) should have the same width or 1 more
+ " than the other windows.
+ call assert_inrange(ww1, ww1 + 1, ww2)
+ call assert_inrange(ww3, ww3 + 1, ww2)
+
+ bw Xa Xb Xc
+endfunc
+
+func Test_equalalways_on_close()
+ set equalalways
+ vsplit
+ windo split
+ split
+ wincmd J
+ " now we have a frame top-left with two windows, a frame top-right with two
+ " windows and a frame at the bottom, full-width.
+ let height_1 = winheight(1)
+ let height_2 = winheight(2)
+ let height_3 = winheight(3)
+ let height_4 = winheight(4)
+ " closing the bottom window causes all windows to be resized.
+ close
+ call assert_notequal(height_1, winheight(1))
+ call assert_notequal(height_2, winheight(2))
+ call assert_notequal(height_3, winheight(3))
+ call assert_notequal(height_4, winheight(4))
+ call assert_equal(winheight(1), winheight(3))
+ call assert_equal(winheight(2), winheight(4))
+
+ 1wincmd w
+ split
+ 4wincmd w
+ resize + 5
+ " left column has three windows, equalized heights.
+ " right column has two windows, top one a bit higher
+ let height_1 = winheight(1)
+ let height_2 = winheight(2)
+ let height_4 = winheight(4)
+ let height_5 = winheight(5)
+ 3wincmd w
+ " closing window in left column equalizes heights in left column but not in
+ " the right column
+ close
+ call assert_notequal(height_1, winheight(1))
+ call assert_notequal(height_2, winheight(2))
+ call assert_equal(height_4, winheight(3))
+ call assert_equal(height_5, winheight(4))
+
+ only
+ set equalalways&
+endfunc
+
+func Test_win_screenpos()
+ CheckFeature quickfix
+
+ call assert_equal(1, winnr('$'))
+ split
+ vsplit
+ 10wincmd _
+ 30wincmd |
+ call assert_equal([1, 1], win_screenpos(1))
+ call assert_equal([1, 32], win_screenpos(2))
+ call assert_equal([12, 1], win_screenpos(3))
+ call assert_equal([0, 0], win_screenpos(4))
+ call assert_fails('let l = win_screenpos([])', 'E745:')
+ only
+endfunc
+
+func Test_window_jump_tag()
+ CheckFeature quickfix
+
+ help
+ /iccf
+ call assert_match('^|iccf|', getline('.'))
+ call assert_equal(2, winnr('$'))
+ 2wincmd }
+ call assert_equal(3, winnr('$'))
+ call assert_match('^|iccf|', getline('.'))
+ wincmd k
+ call assert_match('\*iccf\*', getline('.'))
+ call assert_equal(2, winheight(0))
+
+ wincmd z
+ set previewheight=4
+ help
+ /bugs
+ wincmd }
+ wincmd k
+ call assert_match('\*bugs\*', getline('.'))
+ call assert_equal(4, winheight(0))
+ set previewheight&
+
+ %bw!
+endfunc
+
+func Test_window_newtab()
+ e Xa
+
+ call assert_equal(1, tabpagenr('$'))
+ call assert_equal("\nAlready only one window", execute('wincmd T'))
+
+ split Xb
+ split Xc
+
+ wincmd T
+ call assert_equal(2, tabpagenr('$'))
+ call assert_equal(['Xb', 'Xa'], map(tabpagebuflist(1), 'bufname(v:val)'))
+ call assert_equal(['Xc' ], map(2->tabpagebuflist(), 'bufname(v:val)'))
+ call assert_equal(['Xc' ], map(tabpagebuflist(), 'bufname(v:val)'))
+
+ %bw!
+endfunc
+
+func Test_next_split_all()
+ " This was causing an illegal memory access.
+ n x
+ norm axxx
+ split
+ split
+ s/x
+ s/x
+ all
+ bwipe!
+endfunc
+
+" Tests for adjusting window and contents
+func GetScreenStr(row)
+ let str = ""
+ for c in range(1,3)
+ let str .= nr2char(screenchar(a:row, c))
+ endfor
+ return str
+endfunc
+
+func Test_window_contents()
+ enew! | only | new
+ call setline(1, range(1,256))
+
+ exe "norm! \<C-W>t\<C-W>=1Gzt\<C-W>w\<C-W>+"
+ redraw
+ let s3 = GetScreenStr(1)
+ wincmd p
+ call assert_equal(1, line("w0"))
+ call assert_equal('1 ', s3)
+
+ exe "norm! \<C-W>t\<C-W>=50Gzt\<C-W>w\<C-W>+"
+ redraw
+ let s3 = GetScreenStr(1)
+ wincmd p
+ call assert_equal(50, line("w0"))
+ call assert_equal('50 ', s3)
+
+ exe "norm! \<C-W>t\<C-W>=59Gzt\<C-W>w\<C-W>+"
+ redraw
+ let s3 = GetScreenStr(1)
+ wincmd p
+ call assert_equal(59, line("w0"))
+ call assert_equal('59 ', s3)
+
+ %d
+ call setline(1, ['one', 'two', 'three'])
+ call assert_equal(1, line('w0'))
+ call assert_equal(3, line('w$'))
+
+ bwipeout!
+ call test_garbagecollect_now()
+endfunc
+
+func Test_window_colon_command()
+ " This was reading invalid memory.
+ exe "norm! v\<C-W>:\<C-U>echo v:version"
+endfunc
+
+func Test_access_freed_mem()
+ call assert_equal(&columns, winwidth(0))
+ " This was accessing freed memory (but with what events?)
+ au BufEnter,BufLeave,WinEnter,WinLeave 0 vs xxx
+ arg 0
+ argadd
+ call assert_fails("all", "E242:")
+ au!
+ bwipe xxx
+ call assert_equal(&columns, winwidth(0))
+endfunc
+
+func Test_insert_cleared_on_switch_to_term()
+ CheckFeature terminal
+
+ set showmode
+ terminal
+ wincmd p
+
+ call feedkeys("i\<C-O>", 'ntx')
+ redraw
+
+ " The "-- (insert) --" indicator should be visible.
+ let chars = map(range(1, &columns), 'nr2char(screenchar(&lines, v:val))')
+ let str = trim(join(chars, ''))
+ call assert_equal('-- (insert) --', str)
+
+ call feedkeys("\<C-W>p", 'ntx')
+ redraw
+
+ " The "-- (insert) --" indicator should have been cleared.
+ let chars = map(range(1, &columns), 'nr2char(screenchar(&lines, v:val))')
+ let str = trim(join(chars, ''))
+ call assert_equal('', str)
+
+ set showmode&
+ %bw!
+endfunc
+
+func Test_visual_cleared_after_window_split()
+ new | only!
+ let smd_save = &showmode
+ set showmode
+ let ls_save = &laststatus
+ set laststatus=1
+ call setline(1, ['a', 'b', 'c', 'd', ''])
+ norm! G
+ exe "norm! kkvk"
+ redraw
+ exe "norm! \<C-W>v"
+ redraw
+ " check if '-- VISUAL --' disappeared from command line
+ let columns = range(1, &columns)
+ let cmdlinechars = map(columns, 'nr2char(screenchar(&lines, v:val))')
+ let cmdline = join(cmdlinechars, '')
+ let cmdline_ltrim = substitute(cmdline, '^\s*', "", "")
+ let mode_shown = substitute(cmdline_ltrim, '\s*$', "", "")
+ call assert_equal('', mode_shown)
+ let &showmode = smd_save
+ let &laststatus = ls_save
+ bwipe!
+endfunc
+
+func Test_winrestcmd()
+ 2split
+ 3vsplit
+ let a = winrestcmd()
+ call assert_equal(2, winheight(0))
+ call assert_equal(3, winwidth(0))
+ wincmd =
+ call assert_notequal(2, winheight(0))
+ call assert_notequal(3, winwidth(0))
+ exe a
+ call assert_equal(2, winheight(0))
+ call assert_equal(3, winwidth(0))
+ only
+endfunc
+
+func Fun_RenewFile()
+ " Need to wait a bit for the timestamp to be older.
+ let old_ftime = getftime("tmp.txt")
+ while getftime("tmp.txt") == old_ftime
+ sleep 100m
+ silent execute '!echo "1" > tmp.txt'
+ endwhile
+ sp
+ wincmd p
+ edit! tmp.txt
+endfunc
+
+func Test_window_prevwin()
+ " Can we make this work on MS-Windows?
+ CheckUnix
+
+ set hidden autoread
+ call writefile(['2'], 'tmp.txt')
+ new tmp.txt
+ q
+ call Fun_RenewFile()
+ call assert_equal(2, winnr())
+ wincmd p
+ call assert_equal(1, winnr())
+ wincmd p
+ q
+ call Fun_RenewFile()
+ call assert_equal(2, winnr())
+ wincmd p
+ call assert_equal(1, winnr())
+ wincmd p
+ " reset
+ q
+ call delete('tmp.txt')
+ set hidden&vim autoread&vim
+ delfunc Fun_RenewFile
+endfunc
+
+func Test_relative_cursor_position_in_one_line_window()
+ new
+ only
+ call setline(1, range(1, 10000))
+ normal 50%
+ let lnum = getcurpos()[1]
+ split
+ split
+ " make third window take as many lines as possible, other windows will
+ " become one line
+ 3wincmd w
+ for i in range(1, &lines - 6)
+ wincmd +
+ redraw!
+ endfor
+
+ " first and second window should show cursor line
+ let wininfo = getwininfo()
+ call assert_equal(lnum, wininfo[0].topline)
+ call assert_equal(lnum, wininfo[1].topline)
+
+ only!
+ bwipe!
+ call assert_fails('call winrestview(test_null_dict())', 'E474:')
+endfunc
+
+func Test_relative_cursor_position_after_move_and_resize()
+ let so_save = &so
+ set so=0
+ enew
+ call setline(1, range(1, 10000))
+ normal 50%
+ split
+ 1wincmd w
+ " Move cursor to first line in window
+ normal H
+ redraw!
+ " Reduce window height to two lines
+ let height = winheight(0)
+ while winheight(0) > 2
+ wincmd -
+ redraw!
+ endwhile
+ " move cursor to second/last line in window
+ normal j
+ " restore previous height
+ while winheight(0) < height
+ wincmd +
+ redraw!
+ endwhile
+ " make window two lines again
+ while winheight(0) > 2
+ wincmd -
+ redraw!
+ endwhile
+
+ " cursor should be at bottom line
+ let info = getwininfo(win_getid())[0]
+ call assert_equal(info.topline + 1, getcurpos()[1])
+
+ only!
+ bwipe!
+ let &so = so_save
+endfunc
+
+func Test_relative_cursor_position_after_resize()
+ let so_save = &so
+ set so=0
+ enew
+ call setline(1, range(1, 10000))
+ normal 50%
+ split
+ 1wincmd w
+ let winid1 = win_getid()
+ let info = getwininfo(winid1)[0]
+ " Move cursor to second line in window
+ exe "normal " . (info.topline + 1) . "G"
+ redraw!
+ let lnum = getcurpos()[1]
+
+ " Make the window only two lines high, cursor should end up in top line
+ 2wincmd w
+ exe (info.height - 2) . "wincmd +"
+ redraw!
+ let info = getwininfo(winid1)[0]
+ call assert_equal(lnum, info.topline)
+
+ only!
+ bwipe!
+ let &so = so_save
+endfunc
+
+func Test_relative_cursor_second_line_after_resize()
+ let so_save = &so
+ set so=0
+ enew
+ call setline(1, range(1, 10000))
+ normal 50%
+ split
+ 1wincmd w
+ let winid1 = win_getid()
+ let info = getwininfo(winid1)[0]
+
+ " Make the window only two lines high
+ 2wincmd _
+
+ " Move cursor to second line in window
+ normal H
+ normal j
+
+ " Make window size bigger, then back to 2 lines
+ for i in range(1, 10)
+ wincmd +
+ redraw!
+ endfor
+ for i in range(1, 10)
+ wincmd -
+ redraw!
+ endfor
+
+ " cursor should end up in bottom line
+ let info = getwininfo(winid1)[0]
+ call assert_equal(info.topline + 1, getcurpos()[1])
+
+ only!
+ bwipe!
+ let &so = so_save
+endfunc
+
+func Test_split_noscroll()
+ let so_save = &so
+ enew
+ call setline(1, range(1, 8))
+ normal 100%
+ split
+
+ 1wincmd w
+ let winid1 = win_getid()
+ let info1 = getwininfo(winid1)[0]
+
+ 2wincmd w
+ let winid2 = win_getid()
+ let info2 = getwininfo(winid2)[0]
+
+ call assert_equal(1, info1.topline)
+ call assert_equal(1, info2.topline)
+
+ " window that fits all lines by itself, but not when split: closing other
+ " window should restore fraction.
+ only!
+ call setline(1, range(1, &lines - 10))
+ exe &lines / 4
+ let winid1 = win_getid()
+ let info1 = getwininfo(winid1)[0]
+ call assert_equal(1, info1.topline)
+ new
+ redraw
+ close
+ let info1 = getwininfo(winid1)[0]
+ call assert_equal(1, info1.topline)
+
+ bwipe!
+ let &so = so_save
+endfunc
+
+" Tests for the winnr() function
+func Test_winnr()
+ only | tabonly
+ call assert_equal(1, winnr('j'))
+ call assert_equal(1, winnr('k'))
+ call assert_equal(1, winnr('h'))
+ call assert_equal(1, winnr('l'))
+
+ " create a set of horizontally and vertically split windows
+ leftabove new | wincmd p
+ leftabove new | wincmd p
+ rightbelow new | wincmd p
+ rightbelow new | wincmd p
+ leftabove vnew | wincmd p
+ leftabove vnew | wincmd p
+ rightbelow vnew | wincmd p
+ rightbelow vnew | wincmd p
+
+ call assert_equal(8, winnr('j'))
+ call assert_equal(2, winnr('k'))
+ call assert_equal(4, winnr('h'))
+ call assert_equal(6, winnr('l'))
+ call assert_equal(9, winnr('2j'))
+ call assert_equal(1, winnr('2k'))
+ call assert_equal(3, winnr('2h'))
+ call assert_equal(7, winnr('2l'))
+
+ " Error cases
+ call assert_fails("echo winnr('0.2k')", 'E15:')
+ call assert_equal(2, winnr('-2k'))
+ call assert_fails("echo winnr('-2xj')", 'E15:')
+ call assert_fails("echo winnr('j2j')", 'E15:')
+ call assert_fails("echo winnr('ll')", 'E15:')
+ call assert_fails("echo winnr('5')", 'E15:')
+ call assert_equal(4, winnr('0h'))
+ call assert_fails("let w = winnr([])", 'E730:')
+ call assert_equal('unknown', win_gettype(-1))
+ call assert_equal(-1, winheight(-1))
+ call assert_equal(-1, winwidth(-1))
+
+ tabnew
+ call assert_equal(8, tabpagewinnr(1, 'j'))
+ call assert_equal(2, 1->tabpagewinnr('k'))
+ call assert_equal(4, tabpagewinnr(1, 'h'))
+ call assert_equal(6, tabpagewinnr(1, 'l'))
+
+ only | tabonly
+endfunc
+
+func Test_winrestview()
+ split runtest.vim
+ normal 50%
+ let view = winsaveview()
+ close
+ split runtest.vim
+ eval view->winrestview()
+ call assert_equal(view, winsaveview())
+
+ bwipe!
+ call assert_fails('call winrestview(test_null_dict())', 'E474:')
+endfunc
+
+func Test_win_splitmove()
+ CheckFeature quickfix
+
+ edit a
+ leftabove split b
+ leftabove vsplit c
+ leftabove split d
+ call assert_equal(0, win_splitmove(winnr(), winnr('l')))
+ call assert_equal(bufname(winbufnr(1)), 'c')
+ call assert_equal(bufname(winbufnr(2)), 'd')
+ call assert_equal(bufname(winbufnr(3)), 'b')
+ call assert_equal(bufname(winbufnr(4)), 'a')
+ call assert_equal(0, win_splitmove(winnr(), winnr('j'), {'vertical': 1}))
+ call assert_equal(0, win_splitmove(winnr(), winnr('j'), {'vertical': 1}))
+ call assert_equal(bufname(winbufnr(1)), 'c')
+ call assert_equal(bufname(winbufnr(2)), 'b')
+ call assert_equal(bufname(winbufnr(3)), 'd')
+ call assert_equal(bufname(winbufnr(4)), 'a')
+ call assert_equal(0, win_splitmove(winnr(), winnr('k'), {'vertical': 1}))
+ call assert_equal(bufname(winbufnr(1)), 'd')
+ call assert_equal(bufname(winbufnr(2)), 'c')
+ call assert_equal(bufname(winbufnr(3)), 'b')
+ call assert_equal(bufname(winbufnr(4)), 'a')
+ call assert_equal(0, win_splitmove(winnr(), winnr('j'), {'rightbelow': v:true}))
+ call assert_equal(bufname(winbufnr(1)), 'c')
+ call assert_equal(bufname(winbufnr(2)), 'b')
+ call assert_equal(bufname(winbufnr(3)), 'a')
+ call assert_equal(bufname(winbufnr(4)), 'd')
+ call assert_fails('call win_splitmove(winnr(), winnr("k"), test_null_dict())', 'E474:')
+ only | bd
+
+ call assert_fails('call win_splitmove(winnr(), 123)', 'E957:')
+ call assert_fails('call win_splitmove(123, winnr())', 'E957:')
+ call assert_fails('call win_splitmove(winnr(), winnr())', 'E957:')
+
+ tabnew
+ call assert_fails('call win_splitmove(1, win_getid(1, 1))', 'E957:')
+ tabclose
+endfunc
+
+" Test for the :only command
+func Test_window_only()
+ new
+ set modified
+ new
+ call assert_fails('only', 'E445:')
+ only!
+ " Test for :only with a count
+ let wid = win_getid()
+ new
+ new
+ 3only
+ call assert_equal(1, winnr('$'))
+ call assert_equal(wid, win_getid())
+ call assert_fails('close', 'E444:')
+ call assert_fails('%close', 'E16:')
+endfunc
+
+" Test for errors with :wincmd
+func Test_wincmd_errors()
+ call assert_fails('wincmd g', 'E474:')
+ call assert_fails('wincmd ab', 'E474:')
+endfunc
+
+" Test for errors with :winpos
+func Test_winpos_errors()
+ if !has("gui_running") && !has('win32')
+ call assert_fails('winpos', 'E188:')
+ endif
+ call assert_fails('winpos 10', 'E466:')
+endfunc
+
+" Test for +cmd in a :split command
+func Test_split_cmd()
+ split +set\ readonly
+ call assert_equal(1, &readonly)
+ call assert_equal(2, winnr('$'))
+ close
+endfunc
+
+" Create maximum number of horizontally or vertically split windows and then
+" run commands that create a new horizontally/vertically split window
+func Run_noroom_for_newwindow_test(dir_arg)
+ let dir = (a:dir_arg == 'v') ? 'vert ' : ''
+
+ " Open as many windows as possible
+ while v:true
+ try
+ exe dir . 'new'
+ catch /E36:/
+ break
+ endtry
+ endwhile
+
+ call writefile(['first', 'second', 'third'], 'Xfile1')
+ call writefile([], 'Xfile2')
+ call writefile([], 'Xfile3')
+
+ " Argument list related commands
+ args Xfile1 Xfile2 Xfile3
+ next
+ for cmd in ['sargument 2', 'snext', 'sprevious', 'sNext', 'srewind',
+ \ 'sfirst', 'slast']
+ call assert_fails(dir .. cmd, 'E36:')
+ endfor
+ %argdelete
+
+ " Buffer related commands
+ set modified
+ hide enew
+ for cmd in ['sbuffer Xfile1', 'sbnext', 'sbprevious', 'sbNext', 'sbrewind',
+ \ 'sbfirst', 'sblast', 'sball', 'sbmodified', 'sunhide']
+ call assert_fails(dir .. cmd, 'E36:')
+ endfor
+
+ " Window related commands
+ for cmd in ['split', 'split Xfile2', 'new', 'new Xfile3', 'sview Xfile1',
+ \ 'sfind runtest.vim']
+ call assert_fails(dir .. cmd, 'E36:')
+ endfor
+
+ " Help
+ call assert_fails(dir .. 'help', 'E36:')
+ call assert_fails(dir .. 'helpgrep window', 'E36:')
+
+ " Command-line window
+ if a:dir_arg == 'h'
+ " Cmd-line window is always a horizontally split window
+ call assert_beeps('call feedkeys("q:\<CR>", "xt")')
+ endif
+
+ " Quickfix and location list window
+ if has('quickfix')
+ cexpr ''
+ call assert_fails(dir .. 'copen', 'E36:')
+ lexpr ''
+ call assert_fails(dir .. 'lopen', 'E36:')
+
+ " Preview window
+ call assert_fails(dir .. 'pedit Xfile2', 'E36:')
+ call setline(1, 'abc')
+ call assert_fails(dir .. 'psearch abc', 'E36:')
+ endif
+
+ " Window commands (CTRL-W ^ and CTRL-W f)
+ if a:dir_arg == 'h'
+ call assert_fails('call feedkeys("\<C-W>^", "xt")', 'E36:')
+ call setline(1, 'Xfile1')
+ call assert_fails('call feedkeys("gg\<C-W>f", "xt")', 'E36:')
+ endif
+ enew!
+
+ " Tag commands (:stag, :stselect and :stjump)
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "second\tXfile1\t2",
+ \ "third\tXfile1\t3",],
+ \ 'Xtags')
+ set tags=Xtags
+ call assert_fails(dir .. 'stag second', 'E36:')
+ call assert_fails('call feedkeys(":" .. dir .. "stselect second\n1\n", "xt")', 'E36:')
+ call assert_fails(dir .. 'stjump second', 'E36:')
+ call assert_fails(dir .. 'ptag second', 'E36:')
+ set tags&
+ call delete('Xtags')
+
+ " :isplit and :dsplit
+ call setline(1, ['#define FOO 1', 'FOO'])
+ normal 2G
+ call assert_fails(dir .. 'isplit FOO', 'E36:')
+ call assert_fails(dir .. 'dsplit FOO', 'E36:')
+
+ " terminal
+ if has('terminal')
+ call assert_fails(dir .. 'terminal', 'E36:')
+ endif
+
+ %bwipe!
+ call delete('Xfile1')
+ call delete('Xfile2')
+ call delete('Xfile3')
+ only
+endfunc
+
+func Test_split_cmds_with_no_room()
+ call Run_noroom_for_newwindow_test('h')
+ call Run_noroom_for_newwindow_test('v')
+endfunc
+
+" Test for various wincmd failures
+func Test_wincmd_fails()
+ only!
+ call assert_beeps("normal \<C-W>w")
+ call assert_beeps("normal \<C-W>p")
+ call assert_beeps("normal \<C-W>gk")
+ call assert_beeps("normal \<C-W>r")
+ call assert_beeps("normal \<C-W>K")
+ call assert_beeps("normal \<C-W>H")
+ call assert_beeps("normal \<C-W>2gt")
+endfunc
+
+func Test_window_resize()
+ " Vertical :resize (absolute, relative, min and max size).
+ vsplit
+ vert resize 8
+ call assert_equal(8, winwidth(0))
+ vert resize +2
+ call assert_equal(10, winwidth(0))
+ vert resize -2
+ call assert_equal(8, winwidth(0))
+ vert resize
+ call assert_equal(&columns - 2, winwidth(0))
+ vert resize 0
+ call assert_equal(1, winwidth(0))
+ vert resize 99999
+ call assert_equal(&columns - 2, winwidth(0))
+
+ %bwipe!
+
+ " Horizontal :resize (with absolute, relative size, min and max size).
+ split
+ resize 8
+ call assert_equal(8, winheight(0))
+ resize +2
+ call assert_equal(10, winheight(0))
+ resize -2
+ call assert_equal(8, winheight(0))
+ resize
+ call assert_equal(&lines - 4, winheight(0))
+ resize 0
+ call assert_equal(1, winheight(0))
+ resize 99999
+ call assert_equal(&lines - 4, winheight(0))
+
+ " :resize with explicit window number.
+ let other_winnr = winnr('j')
+ exe other_winnr .. 'resize 10'
+ call assert_equal(10, winheight(other_winnr))
+ call assert_equal(&lines - 10 - 3, winheight(0))
+ exe other_winnr .. 'resize +1'
+ exe other_winnr .. 'resize +1'
+ call assert_equal(12, winheight(other_winnr))
+ call assert_equal(&lines - 10 - 3 -2, winheight(0))
+ close
+
+ vsplit
+ wincmd l
+ let other_winnr = winnr('h')
+ call assert_notequal(winnr(), other_winnr)
+ exe 'vert ' .. other_winnr .. 'resize -' .. &columns
+ call assert_equal(0, winwidth(other_winnr))
+
+ %bwipe!
+endfunc
+
+" Test for adjusting the window width when a window is closed with some
+" windows using 'winfixwidth'
+func Test_window_width_adjust()
+ only
+ " Three vertical windows. Windows 1 and 2 have 'winfixwidth' set and close
+ " window 2.
+ wincmd v
+ vert resize 10
+ set winfixwidth
+ wincmd v
+ set winfixwidth
+ wincmd c
+ call assert_inrange(10, 12, winwidth(1))
+ " Three vertical windows. Windows 2 and 3 have 'winfixwidth' set and close
+ " window 3.
+ only
+ set winfixwidth
+ wincmd v
+ vert resize 10
+ set winfixwidth
+ wincmd v
+ set nowinfixwidth
+ wincmd b
+ wincmd c
+ call assert_inrange(10, 12, winwidth(2))
+
+ new | only
+endfunc
+
+" Test for jumping to a vertical/horizontal neighbor window based on the
+" current cursor position
+func Test_window_goto_neightbor()
+ %bw!
+
+ " Vertical window movement
+
+ " create the following window layout:
+ " +--+--+
+ " |w1|w3|
+ " +--+ |
+ " |w2| |
+ " +--+--+
+ " |w4 |
+ " +-----+
+ new
+ vsplit
+ split
+ " vertically jump from w4
+ wincmd b
+ call setline(1, repeat(' ', &columns))
+ call cursor(1, 1)
+ wincmd k
+ call assert_equal(2, winnr())
+ wincmd b
+ call cursor(1, &columns)
+ redraw!
+ wincmd k
+ call assert_equal(3, winnr())
+ %bw!
+
+ " create the following window layout:
+ " +--+--+--+
+ " |w1|w2|w3|
+ " +--+--+--+
+ " |w4 |
+ " +--------+
+ new
+ vsplit
+ vsplit
+ wincmd b
+ call setline(1, repeat(' ', &columns))
+ call cursor(1, 1)
+ wincmd k
+ call assert_equal(1, winnr())
+ wincmd b
+ call cursor(1, &columns / 2)
+ redraw!
+ wincmd k
+ call assert_equal(2, winnr())
+ wincmd b
+ call cursor(1, &columns)
+ redraw!
+ wincmd k
+ call assert_equal(3, winnr())
+ %bw!
+
+ " Horizontal window movement
+
+ " create the following window layout:
+ " +--+--+--+
+ " |w1|w2|w4|
+ " +--+--+ |
+ " |w3 | |
+ " +-----+--+
+ vsplit
+ split
+ vsplit
+ 4wincmd l
+ call setline(1, repeat([' '], &lines))
+ call cursor(1, 1)
+ redraw!
+ wincmd h
+ call assert_equal(2, winnr())
+ 4wincmd l
+ call cursor(&lines, 1)
+ redraw!
+ wincmd h
+ call assert_equal(3, winnr())
+ %bw!
+
+ " create the following window layout:
+ " +--+--+
+ " |w1|w4|
+ " +--+ +
+ " |w2| |
+ " +--+ +
+ " |w3| |
+ " +--+--+
+ vsplit
+ split
+ split
+ wincmd l
+ call setline(1, repeat([' '], &lines))
+ call cursor(1, 1)
+ redraw!
+ wincmd h
+ call assert_equal(1, winnr())
+ wincmd l
+ call cursor(&lines / 2, 1)
+ redraw!
+ wincmd h
+ call assert_equal(2, winnr())
+ wincmd l
+ call cursor(&lines, 1)
+ redraw!
+ wincmd h
+ call assert_equal(3, winnr())
+ %bw!
+endfunc
+
+" Test for an autocmd closing the destination window when jumping from one
+" window to another.
+func Test_close_dest_window()
+ split
+ edit Xfile
+
+ " Test for BufLeave
+ augroup T1
+ au!
+ au BufLeave Xfile $wincmd c
+ augroup END
+ wincmd b
+ call assert_equal(1, winnr('$'))
+ call assert_equal('Xfile', @%)
+ augroup T1
+ au!
+ augroup END
+
+ " Test for WinLeave
+ new
+ wincmd p
+ augroup T1
+ au!
+ au WinLeave * 1wincmd c
+ augroup END
+ wincmd t
+ call assert_equal(1, winnr('$'))
+ call assert_equal('Xfile', @%)
+ augroup T1
+ au!
+ augroup END
+ augroup! T1
+ %bw!
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab