diff options
Diffstat (limited to 'test/functional/ui/float_spec.lua')
-rw-r--r-- | test/functional/ui/float_spec.lua | 310 |
1 files changed, 284 insertions, 26 deletions
diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua index cdb3b79963..248220e28b 100644 --- a/test/functional/ui/float_spec.lua +++ b/test/functional/ui/float_spec.lua @@ -1,24 +1,26 @@ -local helpers = require('test.functional.helpers')(after_each) +local t = require('test.testutil') +local n = require('test.functional.testnvim')() local Screen = require('test.functional.ui.screen') local os = require('os') -local clear, feed = helpers.clear, helpers.feed -local assert_alive = helpers.assert_alive -local command, feed_command = helpers.command, helpers.feed_command -local eval = helpers.eval -local eq = helpers.eq -local neq = helpers.neq -local expect = helpers.expect -local exec = helpers.exec -local exec_lua = helpers.exec_lua -local insert = helpers.insert -local api = helpers.api -local fn = helpers.fn -local run = helpers.run -local pcall_err = helpers.pcall_err + +local clear, feed = n.clear, n.feed +local assert_alive = n.assert_alive +local command, feed_command = n.command, n.feed_command +local eval = n.eval +local eq = t.eq +local neq = t.neq +local expect = n.expect +local exec = n.exec +local exec_lua = n.exec_lua +local insert = n.insert +local api = n.api +local fn = n.fn +local run = n.run +local pcall_err = t.pcall_err local tbl_contains = vim.tbl_contains -local curbuf = helpers.api.nvim_get_current_buf -local curwin = helpers.api.nvim_get_current_win -local curtab = helpers.api.nvim_get_current_tabpage +local curbuf = n.api.nvim_get_current_buf +local curwin = n.api.nvim_get_current_win +local curtab = n.api.nvim_get_current_tabpage local NIL = vim.NIL describe('float window', function() @@ -325,6 +327,27 @@ describe('float window', function() eq(12, pos[2]) end) + it('error message when reconfig missing relative field', function() + local bufnr = api.nvim_create_buf(false, true) + local opts = { + width = 10, + height = 10, + col = 5, + row = 5, + relative = 'editor', + style = 'minimal', + } + local win_id = api.nvim_open_win(bufnr, true, opts) + eq( + "Missing 'relative' field when reconfiguring floating window 1001", + pcall_err(api.nvim_win_set_config, win_id, { + width = 3, + height = 3, + row = 10, + col = 10, + })) + end) + it('is not operated on by windo when non-focusable #15374', function() command([[ let winids = [] @@ -413,6 +436,25 @@ describe('float window', function() eq(winid, eval('win_getid()')) end) + it('is not active after closing window when non-focusable #28454', function() + command('copen') + local winid = exec_lua([[ + local bufnr = vim.api.nvim_create_buf(false, true) + local opts = { + relative = 'editor', + focusable = false, + height = 5, + width = 5, + col = 5, + row = 5, + } + return vim.api.nvim_open_win(bufnr, false, opts) + ]]) + command('wincmd t') + command('wincmd q') + neq(winid, curwin()) + end) + it('supports windo with focusable and non-focusable floats', function() local winids = exec_lua([[ local result = {vim.api.nvim_get_current_win()} @@ -490,7 +532,10 @@ describe('float window', function() local closed_win = api.nvim_get_current_win() command('close') local buf = api.nvim_create_buf(false,false) - api.nvim_open_win(buf, true, {relative='win', win=closed_win, width=1, height=1, bufpos={0,0}}) + eq( + 'Invalid window id: ' .. closed_win, + pcall_err(api.nvim_open_win, buf, true, {relative='win', win=closed_win, width=1, height=1, bufpos={0,0}}) + ) assert_alive() end) @@ -550,6 +595,43 @@ describe('float window', function() eq({ w0 }, api.nvim_list_wins()) end) + it('win_splitmove() can move float into a split', function() + command('split') + eq({'col', {{'leaf', 1001}, {'leaf', 1000}}}, fn.winlayout()) + + local win1 = api.nvim_open_win(0, true, {relative = 'editor', row = 1, col = 1, width = 5, height = 5}) + fn.win_splitmove(win1, 1001, {vertical = true}) + eq({'col', {{'row', {{'leaf', win1}, {'leaf', 1001}}}, {'leaf', 1000}}}, fn.winlayout()) + eq('', api.nvim_win_get_config(win1).relative) + + -- Should be unable to create a split relative to a float, though. + local win2 = api.nvim_open_win(0, true, {relative = 'editor', row = 1, col = 1, width = 5, height = 5}) + eq('Vim:E957: Invalid window number', pcall_err(fn.win_splitmove, win1, win2, {vertical = true})) + end) + + it('tp_curwin updated if external window is moved into split', function() + local screen = Screen.new(20, 7) + screen:attach { ext_multigrid = true } + + command('tabnew') + local external_win = api.nvim_open_win(0, true, {external = true, width = 5, height = 5}) + eq(external_win, api.nvim_get_current_win()) + eq(2, fn.tabpagenr()) + command('tabfirst') + api.nvim_set_current_win(external_win) + eq(external_win, api.nvim_get_current_win()) + eq(1, fn.tabpagenr()) + + command('wincmd J') + eq(external_win, api.nvim_get_current_win()) + eq(false, api.nvim_win_get_config(external_win).external) + command('tabnext') + eq(2, fn.tabpagenr()) + neq(external_win, api.nvim_get_current_win()) + + screen:detach() + end) + describe('with only one tabpage,', function() local float_opts = {relative = 'editor', row = 1, col = 1, width = 1, height = 1} local old_buf, old_win @@ -836,6 +918,57 @@ describe('float window', function() end) end) + describe(':close on non-float with floating windows', function() + -- XXX: it isn't really clear whether this should quit Nvim, as if the autocommand + -- here is BufUnload then it does quit Nvim. + -- But with BufWinLeave, this doesn't quit Nvim if there are no floating windows, + -- so it shouldn't quit Nvim if there are floating windows. + it('does not quit Nvim if BufWinLeave makes it the only non-float', function() + exec([[ + let g:buf = bufnr() + new + let s:midwin = win_getid() + new + setlocal bufhidden=wipe + call nvim_win_set_config(s:midwin, + \ #{relative: 'editor', row: 5, col: 5, width: 5, height: 5}) + autocmd BufWinLeave * ++once exe g:buf .. 'bwipe!' + ]]) + eq('Vim(close):E855: Autocommands caused command to abort', pcall_err(command, 'close')) + assert_alive() + end) + + pending('does not crash if BufUnload makes it the only non-float in tabpage', function() + exec([[ + tabnew + let g:buf = bufnr() + new + let s:midwin = win_getid() + new + setlocal bufhidden=wipe + call nvim_win_set_config(s:midwin, + \ #{relative: 'editor', row: 5, col: 5, width: 5, height: 5}) + autocmd BufUnload * ++once exe g:buf .. 'bwipe!' + ]]) + command('close') + assert_alive() + end) + + it('does not crash if WinClosed from floating window closes it', function() + exec([[ + tabnew + new + let s:win = win_getid() + call nvim_win_set_config(s:win, + \ #{relative: 'editor', row: 5, col: 5, width: 5, height: 5}) + wincmd t + exe $"autocmd WinClosed {s:win} 1close" + ]]) + command('close') + assert_alive() + end) + end) + local function with_ext_multigrid(multigrid) local screen, attrs before_each(function() @@ -1448,7 +1581,12 @@ describe('float window', function() }, win_viewport={ [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; - }} + }, + win_viewport_margins={ + [2] = {win = 1000, top = 0, bottom = 0, left = 0, right = 0}; + [4] = {win = 1001, top = 1, bottom = 1, left = 1, right = 1}; + } + } else screen:expect{grid=[[ ^ | @@ -1648,7 +1786,12 @@ describe('float window', function() }, win_viewport={ [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; - }} + }, + win_viewport_margins={ + [2] = {win = 1000, top = 0, bottom = 0, left = 0, right = 0}; + [4] = {win = 1001, top = 0, bottom = 0, left = 1, right = 1}; + } + } else screen:expect{grid=[[ ^ | @@ -1681,6 +1824,10 @@ describe('float window', function() }, win_viewport={ [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + }, + win_viewport_margins={ + [2] = {win = 1000, top = 0, bottom = 0, left = 0, right = 0}; + [4] = {win = 1001, top = 1, bottom = 1, left = 0, right = 0}; }} else screen:expect{grid=[[ @@ -1726,6 +1873,10 @@ describe('float window', function() }, win_viewport={ [2] = {win = 1000, topline = 0, botline = 6, curline = 5, curcol = 0, linecount = 6, sum_scroll_delta = 0}; [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + }, + win_viewport_margins={ + [2] = {win = 1000, top = 0, bottom = 0, left = 0, right = 0}; + [4] = {win = 1001, top = 0, bottom = 1, left = 0, right = 1}; }} else screen:expect{grid=[[ @@ -2256,6 +2407,7 @@ describe('float window', function() command('hi B0 guibg=Red guifg=Black') command('hi B1 guifg=White') + api.nvim_win_set_config(win, { title = {{"🦄"}, {"BB", {"B0", "B1"}}}, title_pos = "right", footer= {{"🦄"}, {"BB", {"B0", "B1"}}}, footer_pos = "right", @@ -2292,6 +2444,47 @@ describe('float window', function() | ]]} end + eq({{"🦄"}, {"BB", {"B0", "B1"}}}, api.nvim_win_get_config(win).title) + eq({{"🦄"}, {"BB", {"B0", "B1"}}}, api.nvim_win_get_config(win).footer) + + api.nvim_win_set_config(win, { + title = {{"🦄", ""}, {"BB", {"B0", "B1", ""}}}, title_pos = "left", + footer= {{"🦄", ""}, {"BB", {"B0", "B1", ""}}}, footer_pos = "left", + }) + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [2:----------------------------------------]|*6 + [3:----------------------------------------]| + ## grid 2 + ^ | + {0:~ }|*5 + ## grid 3 + | + ## grid 4 + {5:╔}🦄{7:BB}{5:═════╗}| + {5:║}{1: halloj! }{5:║}| + {5:║}{1: BORDAA }{5:║}| + {5:╚}🦄{7:BB}{5:═════╝}| + ]], float_pos={ + [4] = { 1001, "NW", 1, 2, 5, true } + }, win_viewport={ + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + }} + else + screen:expect{grid=[[ + ^ | + {0:~ }| + {0:~ }{5:╔}🦄{7:BB}{5:═════╗}{0: }| + {0:~ }{5:║}{1: halloj! }{5:║}{0: }| + {0:~ }{5:║}{1: BORDAA }{5:║}{0: }| + {0:~ }{5:╚}🦄{7:BB}{5:═════╝}{0: }| + | + ]]} + end + eq({{"🦄", ""}, {"BB", {"B0", "B1", ""}}}, api.nvim_win_get_config(win).title) + eq({{"🦄", ""}, {"BB", {"B0", "B1", ""}}}, api.nvim_win_get_config(win).footer) end) it('terminates border on edge of viewport when window extends past viewport', function() @@ -3974,7 +4167,7 @@ describe('float window', function() if multigrid then pending("supports second UI without multigrid", function() - local session2 = helpers.connect(eval('v:servername')) + local session2 = n.connect(eval('v:servername')) print(session2:request("nvim_eval", "2+2")) local screen2 = Screen.new(40,7) screen2:attach(nil, session2) @@ -6169,7 +6362,7 @@ describe('float window', function() run(on_request, nil, on_setup) os.remove('Xtest_written') os.remove('Xtest_written2') - eq(exited, true) + eq(true, exited) end) it(':quit two floats in a row', function() @@ -7872,7 +8065,7 @@ describe('float window', function() end) it("correctly redraws when overlaid windows are resized #13991", function() - helpers.source([[ + n.source([[ let popup_config = {"relative" : "editor", \ "width" : 7, \ "height" : 3, @@ -7936,7 +8129,7 @@ describe('float window', function() ]]) end - helpers.source([[ + n.source([[ let new_popup_config = {"width" : 1, "height" : 3} let new_border_config = {"width" : 3, "height" : 5} @@ -7951,7 +8144,7 @@ describe('float window', function() nnoremap zz <cmd>call Resize()<cr> ]]) - helpers.feed("zz") + n.feed("zz") if multigrid then screen:expect{grid=[[ ## grid 1 @@ -8273,6 +8466,10 @@ describe('float window', function() }, win_viewport={ [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + }, + win_viewport_margins={ + [2] = {win = 1000, top = 0, bottom = 0, left = 0, right = 0}; + [4] = {win = 1001, top = 2, bottom = 1, left = 1, right = 1}; }} else screen:expect{grid=[[ @@ -9101,6 +9298,67 @@ describe('float window', function() ]]} end end) + + it('attempt to turn into split with no room', function() + eq('Vim(split):E36: Not enough room', pcall_err(command, 'execute "split |"->repeat(&lines)')) + command('vsplit | wincmd | | wincmd p') + api.nvim_open_win(0, true, {relative = "editor", row = 0, col = 0, width = 5, height = 5}) + local config = api.nvim_win_get_config(0) + eq('editor', config.relative) + + local layout = fn.winlayout() + local restcmd = fn.winrestcmd() + eq('Vim(wincmd):E36: Not enough room', pcall_err(command, 'wincmd K')) + eq('Vim(wincmd):E36: Not enough room', pcall_err(command, 'wincmd J')) + eq(layout, fn.winlayout()) + eq(restcmd, fn.winrestcmd()) + eq(config, api.nvim_win_get_config(0)) + end) + + it("error when relative to itself", function() + local buf = api.nvim_create_buf(false, true) + local config = { relative='win', width=5, height=2, row=3, col=3 } + local winid = api.nvim_open_win(buf, false, config) + api.nvim_set_current_win(winid) + eq("floating window cannot be relative to itself", pcall_err(api.nvim_win_set_config, winid, config)) + end) + + it("bufpos out of range", function() + local buf = api.nvim_create_buf(false, true) + api.nvim_buf_set_lines(0, 0, -1, false, {}) + local config = { relative='win', width=5, height=2, row=0, col=0, bufpos = { 3, 3 } } + api.nvim_open_win(buf, false, config) + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:----------------------------------------]|*6 + [3:----------------------------------------]| + ## grid 2 + ^ | + {0:~ }|*5 + ## grid 3 + | + ## grid 4 + {1: }| + {2:~ }| + ]], float_pos={ + [4] = {1001, "NW", 2, 0, 0, true, 50}; + }, win_viewport={ + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + }}) + else + screen:expect({ + grid = [[ + {1:^ } | + {2:~ }{0: }| + {0:~ }|*4 + | + ]] + }) + end + end) end describe('with ext_multigrid', function() |