123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544 |
- local helpers = require('test.functional.helpers')(after_each)
- local Screen = require('test.functional.ui.screen')
- local clear, nvim, curbuf, curbuf_contents, window, curwin, eq, neq,
- ok, feed, insert, eval, tabpage = helpers.clear, helpers.nvim, helpers.curbuf,
- helpers.curbuf_contents, helpers.window, helpers.curwin, helpers.eq,
- helpers.neq, helpers.ok, helpers.feed, helpers.insert, helpers.eval,
- helpers.tabpage
- local poke_eventloop = helpers.poke_eventloop
- local curwinmeths = helpers.curwinmeths
- local exec = helpers.exec
- local funcs = helpers.funcs
- local request = helpers.request
- local NIL = helpers.NIL
- local meths = helpers.meths
- local command = helpers.command
- local pcall_err = helpers.pcall_err
- local assert_alive = helpers.assert_alive
- -- check if str is visible at the beginning of some line
- local function is_visible(str)
- local slen = string.len(str)
- local nlines = eval("&lines")
- for i = 1,nlines do
- local iseq = true
- for j = 1,slen do
- if string.byte(str,j) ~= eval("screenchar("..i..","..j..")") then
- iseq = false
- break
- end
- end
- if iseq then
- return true
- end
- end
- return false
- end
- describe('API/win', function()
- before_each(clear)
- describe('get_buf', function()
- it('works', function()
- eq(curbuf(), window('get_buf', nvim('list_wins')[1]))
- nvim('command', 'new')
- nvim('set_current_win', nvim('list_wins')[2])
- eq(curbuf(), window('get_buf', nvim('list_wins')[2]))
- neq(window('get_buf', nvim('list_wins')[1]),
- window('get_buf', nvim('list_wins')[2]))
- end)
- end)
- describe('set_buf', function()
- it('works', function()
- nvim('command', 'new')
- local windows = nvim('list_wins')
- neq(window('get_buf', windows[2]), window('get_buf', windows[1]))
- window('set_buf', windows[2], window('get_buf', windows[1]))
- eq(window('get_buf', windows[2]), window('get_buf', windows[1]))
- end)
- it('validates args', function()
- eq('Invalid buffer id: 23', pcall_err(window, 'set_buf', nvim('get_current_win'), 23))
- eq('Invalid window id: 23', pcall_err(window, 'set_buf', 23, nvim('get_current_buf')))
- end)
- end)
- describe('{get,set}_cursor', function()
- it('works', function()
- eq({1, 0}, curwin('get_cursor'))
- nvim('command', 'normal ityping\027o some text')
- eq('typing\n some text', curbuf_contents())
- eq({2, 10}, curwin('get_cursor'))
- curwin('set_cursor', {2, 6})
- nvim('command', 'normal i dumb')
- eq('typing\n some dumb text', curbuf_contents())
- end)
- it('does not leak memory when using invalid window ID with invalid pos', function()
- eq('Invalid window id: 1', pcall_err(meths.win_set_cursor, 1, {"b\na"}))
- end)
- it('updates the screen, and also when the window is unfocused', function()
- insert("prologue")
- feed('100o<esc>')
- insert("epilogue")
- local win = curwin()
- feed('gg')
- poke_eventloop() -- let nvim process the 'gg' command
- -- cursor position is at beginning
- eq({1, 0}, window('get_cursor', win))
- eq(true, is_visible("prologue"))
- eq(false, is_visible("epilogue"))
- -- move cursor to end
- window('set_cursor', win, {101, 0})
- eq(false, is_visible("prologue"))
- eq(true, is_visible("epilogue"))
- -- move cursor to the beginning again
- window('set_cursor', win, {1, 0})
- eq(true, is_visible("prologue"))
- eq(false, is_visible("epilogue"))
- -- move focus to new window
- nvim('command',"new")
- neq(win, curwin())
- -- sanity check, cursor position is kept
- eq({1, 0}, window('get_cursor', win))
- eq(true, is_visible("prologue"))
- eq(false, is_visible("epilogue"))
- -- move cursor to end
- window('set_cursor', win, {101, 0})
- eq(false, is_visible("prologue"))
- eq(true, is_visible("epilogue"))
- -- move cursor to the beginning again
- window('set_cursor', win, {1, 0})
- eq(true, is_visible("prologue"))
- eq(false, is_visible("epilogue"))
- -- curwin didn't change back
- neq(win, curwin())
- end)
- it('remembers what column it wants to be in', function()
- insert("first line")
- feed('o<esc>')
- insert("second line")
- feed('gg')
- poke_eventloop() -- let nvim process the 'gg' command
- -- cursor position is at beginning
- local win = curwin()
- eq({1, 0}, window('get_cursor', win))
- -- move cursor to column 5
- window('set_cursor', win, {1, 5})
- -- move down a line
- feed('j')
- poke_eventloop() -- let nvim process the 'j' command
- -- cursor is still in column 5
- eq({2, 5}, window('get_cursor', win))
- end)
- it('updates cursorline and statusline ruler in non-current window', function()
- local screen = Screen.new(60, 8)
- screen:set_default_attr_ids({
- [1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
- [2] = {background = Screen.colors.Grey90}, -- CursorLine
- [3] = {bold = true, reverse = true}, -- StatusLine
- [4] = {reverse = true}, -- StatusLineNC
- })
- screen:attach()
- command('set ruler')
- command('set cursorline')
- insert([[
- aaa
- bbb
- ccc
- ddd]])
- local oldwin = curwin()
- command('vsplit')
- screen:expect([[
- aaa │aaa |
- bbb │bbb |
- ccc │ccc |
- {2:dd^d }│{2:ddd }|
- {1:~ }│{1:~ }|
- {1:~ }│{1:~ }|
- {3:[No Name] [+] 4,3 All }{4:[No Name] [+] 4,3 All}|
- |
- ]])
- window('set_cursor', oldwin, {1, 0})
- screen:expect([[
- aaa │{2:aaa }|
- bbb │bbb |
- ccc │ccc |
- {2:dd^d }│ddd |
- {1:~ }│{1:~ }|
- {1:~ }│{1:~ }|
- {3:[No Name] [+] 4,3 All }{4:[No Name] [+] 1,1 All}|
- |
- ]])
- end)
- end)
- describe('{get,set}_height', function()
- it('works', function()
- nvim('command', 'vsplit')
- eq(window('get_height', nvim('list_wins')[2]),
- window('get_height', nvim('list_wins')[1]))
- nvim('set_current_win', nvim('list_wins')[2])
- nvim('command', 'split')
- eq(window('get_height', nvim('list_wins')[2]),
- math.floor(window('get_height', nvim('list_wins')[1]) / 2))
- window('set_height', nvim('list_wins')[2], 2)
- eq(2, window('get_height', nvim('list_wins')[2]))
- end)
- it('do not cause ml_get errors with foldmethod=expr #19989', function()
- insert([[
- aaaaa
- bbbbb
- ccccc]])
- command('set foldmethod=expr')
- exec([[
- new
- let w = nvim_get_current_win()
- wincmd w
- call nvim_win_set_height(w, 5)
- ]])
- feed('l')
- eq('', meths.get_vvar('errmsg'))
- end)
- end)
- describe('{get,set}_width', function()
- it('works', function()
- nvim('command', 'split')
- eq(window('get_width', nvim('list_wins')[2]),
- window('get_width', nvim('list_wins')[1]))
- nvim('set_current_win', nvim('list_wins')[2])
- nvim('command', 'vsplit')
- eq(window('get_width', nvim('list_wins')[2]),
- math.floor(window('get_width', nvim('list_wins')[1]) / 2))
- window('set_width', nvim('list_wins')[2], 2)
- eq(2, window('get_width', nvim('list_wins')[2]))
- end)
- it('do not cause ml_get errors with foldmethod=expr #19989', function()
- insert([[
- aaaaa
- bbbbb
- ccccc]])
- command('set foldmethod=expr')
- exec([[
- vnew
- let w = nvim_get_current_win()
- wincmd w
- call nvim_win_set_width(w, 5)
- ]])
- feed('l')
- eq('', meths.get_vvar('errmsg'))
- end)
- end)
- describe('{get,set,del}_var', function()
- it('works', function()
- curwin('set_var', 'lua', {1, 2, {['3'] = 1}})
- eq({1, 2, {['3'] = 1}}, curwin('get_var', 'lua'))
- eq({1, 2, {['3'] = 1}}, nvim('eval', 'w:lua'))
- eq(1, funcs.exists('w:lua'))
- curwinmeths.del_var('lua')
- eq(0, funcs.exists('w:lua'))
- eq('Key not found: lua', pcall_err(curwinmeths.del_var, 'lua'))
- curwinmeths.set_var('lua', 1)
- command('lockvar w:lua')
- eq('Key is locked: lua', pcall_err(curwinmeths.del_var, 'lua'))
- eq('Key is locked: lua', pcall_err(curwinmeths.set_var, 'lua', 1))
- end)
- it('window_set_var returns the old value', function()
- local val1 = {1, 2, {['3'] = 1}}
- local val2 = {4, 7}
- eq(NIL, request('window_set_var', 0, 'lua', val1))
- eq(val1, request('window_set_var', 0, 'lua', val2))
- end)
- it('window_del_var returns the old value', function()
- local val1 = {1, 2, {['3'] = 1}}
- local val2 = {4, 7}
- eq(NIL, request('window_set_var', 0, 'lua', val1))
- eq(val1, request('window_set_var', 0, 'lua', val2))
- eq(val2, request('window_del_var', 0, 'lua'))
- end)
- end)
- describe('nvim_win_get_option, nvim_win_set_option', function()
- it('works', function()
- curwin('set_option', 'colorcolumn', '4,3')
- eq('4,3', curwin('get_option', 'colorcolumn'))
- command("set modified hidden")
- command("enew") -- edit new buffer, window option is preserved
- eq('4,3', curwin('get_option', 'colorcolumn'))
- -- global-local option
- curwin('set_option', 'statusline', 'window-status')
- eq('window-status', curwin('get_option', 'statusline'))
- eq('', nvim('get_option', 'statusline'))
- command("set modified")
- command("enew") -- global-local: not preserved in new buffer
- -- confirm local value was not copied
- eq('', curwin('get_option', 'statusline'))
- eq('', eval('&l:statusline'))
- end)
- it('after switching windows #15390', function()
- nvim('command', 'tabnew')
- local tab1 = unpack(nvim('list_tabpages'))
- local win1 = unpack(tabpage('list_wins', tab1))
- window('set_option', win1, 'statusline', 'window-status')
- nvim('command', 'split')
- nvim('command', 'wincmd J')
- nvim('command', 'wincmd j')
- eq('window-status', window('get_option', win1, 'statusline'))
- assert_alive()
- end)
- it('returns values for unset local options', function()
- eq(-1, curwin('get_option', 'scrolloff'))
- end)
- end)
- describe('get_position', function()
- it('works', function()
- local height = window('get_height', nvim('list_wins')[1])
- local width = window('get_width', nvim('list_wins')[1])
- nvim('command', 'split')
- nvim('command', 'vsplit')
- eq({0, 0}, window('get_position', nvim('list_wins')[1]))
- local vsplit_pos = math.floor(width / 2)
- local split_pos = math.floor(height / 2)
- local win2row, win2col =
- unpack(window('get_position', nvim('list_wins')[2]))
- local win3row, win3col =
- unpack(window('get_position', nvim('list_wins')[3]))
- eq(0, win2row)
- eq(0, win3col)
- ok(vsplit_pos - 1 <= win2col and win2col <= vsplit_pos + 1)
- ok(split_pos - 1 <= win3row and win3row <= split_pos + 1)
- end)
- end)
- describe('get_position', function()
- it('works', function()
- nvim('command', 'tabnew')
- nvim('command', 'vsplit')
- eq(window('get_tabpage',
- nvim('list_wins')[1]), nvim('list_tabpages')[1])
- eq(window('get_tabpage',
- nvim('list_wins')[2]), nvim('list_tabpages')[2])
- eq(window('get_tabpage',
- nvim('list_wins')[3]), nvim('list_tabpages')[2])
- end)
- end)
- describe('get_number', function()
- it('works', function()
- local wins = nvim('list_wins')
- eq(1, window('get_number', wins[1]))
- nvim('command', 'split')
- local win1, win2 = unpack(nvim('list_wins'))
- eq(1, window('get_number', win1))
- eq(2, window('get_number', win2))
- nvim('command', 'wincmd J')
- eq(2, window('get_number', win1))
- eq(1, window('get_number', win2))
- nvim('command', 'tabnew')
- local win3 = nvim('list_wins')[3]
- -- First tab page
- eq(2, window('get_number', win1))
- eq(1, window('get_number', win2))
- -- Second tab page
- eq(1, window('get_number', win3))
- end)
- end)
- describe('is_valid', function()
- it('works', function()
- nvim('command', 'split')
- local win = nvim('list_wins')[2]
- nvim('set_current_win', win)
- ok(window('is_valid', win))
- nvim('command', 'close')
- ok(not window('is_valid', win))
- end)
- end)
- describe('close', function()
- it('can close current window', function()
- local oldwin = meths.get_current_win()
- command('split')
- local newwin = meths.get_current_win()
- meths.win_close(newwin,false)
- eq({oldwin}, meths.list_wins())
- end)
- it('can close noncurrent window', function()
- local oldwin = meths.get_current_win()
- command('split')
- local newwin = meths.get_current_win()
- meths.win_close(oldwin,false)
- eq({newwin}, meths.list_wins())
- end)
- it("handles changed buffer when 'hidden' is unset", function()
- command('set nohidden')
- local oldwin = meths.get_current_win()
- insert('text')
- command('new')
- local newwin = meths.get_current_win()
- eq("Vim:E37: No write since last change (add ! to override)",
- pcall_err(meths.win_close, oldwin,false))
- eq({newwin,oldwin}, meths.list_wins())
- end)
- it('handles changed buffer with force', function()
- local oldwin = meths.get_current_win()
- insert('text')
- command('new')
- local newwin = meths.get_current_win()
- meths.win_close(oldwin,true)
- eq({newwin}, meths.list_wins())
- end)
- it('in cmdline-window #9767', function()
- command('split')
- eq(2, #meths.list_wins())
- local oldwin = meths.get_current_win()
- -- Open cmdline-window.
- feed('q:')
- eq(3, #meths.list_wins())
- eq(':', funcs.getcmdwintype())
- -- Vim: not allowed to close other windows from cmdline-window.
- eq('E11: Invalid in command-line window; <CR> executes, CTRL-C quits',
- pcall_err(meths.win_close, oldwin, true))
- -- Close cmdline-window.
- meths.win_close(0,true)
- eq(2, #meths.list_wins())
- eq('', funcs.getcmdwintype())
- end)
- it('closing current (float) window of another tabpage #15313', function()
- command('tabedit')
- eq(2, eval('tabpagenr()'))
- local win = meths.open_win(0, true, {
- relative='editor', row=10, col=10, width=50, height=10
- })
- local tab = eval('tabpagenr()')
- command('tabprevious')
- eq(1, eval('tabpagenr()'))
- meths.win_close(win, false)
- eq(1001, meths.tabpage_get_win(tab).id)
- assert_alive()
- end)
- end)
- describe('hide', function()
- it('can hide current window', function()
- local oldwin = meths.get_current_win()
- command('split')
- local newwin = meths.get_current_win()
- meths.win_hide(newwin)
- eq({oldwin}, meths.list_wins())
- end)
- it('can hide noncurrent window', function()
- local oldwin = meths.get_current_win()
- command('split')
- local newwin = meths.get_current_win()
- meths.win_hide(oldwin)
- eq({newwin}, meths.list_wins())
- end)
- it('does not close the buffer', function()
- local oldwin = meths.get_current_win()
- local oldbuf = meths.get_current_buf()
- local buf = meths.create_buf(true, false)
- local newwin = meths.open_win(buf, true, {
- relative='win', row=3, col=3, width=12, height=3
- })
- meths.win_hide(newwin)
- eq({oldwin}, meths.list_wins())
- eq({oldbuf, buf}, meths.list_bufs())
- end)
- it('deletes the buffer when bufhidden=wipe', function()
- local oldwin = meths.get_current_win()
- local oldbuf = meths.get_current_buf()
- local buf = meths.create_buf(true, false)
- local newwin = meths.open_win(buf, true, {
- relative='win', row=3, col=3, width=12, height=3
- })
- meths.buf_set_option(buf, 'bufhidden', 'wipe')
- meths.win_hide(newwin)
- eq({oldwin}, meths.list_wins())
- eq({oldbuf}, meths.list_bufs())
- end)
- end)
- describe('open_win', function()
- it('noautocmd option works', function()
- command('autocmd BufEnter,BufLeave,BufWinEnter * let g:fired = 1')
- meths.open_win(meths.create_buf(true, true), true, {
- relative='win', row=3, col=3, width=12, height=3, noautocmd=true
- })
- eq(0, funcs.exists('g:fired'))
- meths.open_win(meths.create_buf(true, true), true, {
- relative='win', row=3, col=3, width=12, height=3
- })
- eq(1, funcs.exists('g:fired'))
- end)
- end)
- describe('get_config', function()
- it('includes border', function()
- local b = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' }
- local win = meths.open_win(0, true, {
- relative='win', row=3, col=3, width=12, height=3,
- border = b,
- })
- local cfg = meths.win_get_config(win)
- eq(b, cfg.border)
- end)
- it('includes border with highlight group', function()
- local b = {
- {'a', 'Normal'},
- {'b', 'Special'},
- {'c', 'String'},
- {'d', 'Comment'},
- {'e', 'Visual'},
- {'f', 'Error'},
- {'g', 'Constant'},
- {'h', 'PreProc'},
- }
- local win = meths.open_win(0, true, {
- relative='win', row=3, col=3, width=12, height=3,
- border = b,
- })
- local cfg = meths.win_get_config(win)
- eq(b, cfg.border)
- end)
- end)
- end)
|