mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
test: typing for screen.lua
Very rough buts resolves most diagnostic errors and should provide some useful hovers.
This commit is contained in:
parent
89ffdebd20
commit
0054c18500
@ -352,7 +352,7 @@ function vim.schedule_wrap(fn)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- vim.fn.{func}(...)
|
-- vim.fn.{func}(...)
|
||||||
---@private
|
---@nodoc
|
||||||
vim.fn = setmetatable({}, {
|
vim.fn = setmetatable({}, {
|
||||||
__index = function(t, key)
|
__index = function(t, key)
|
||||||
local _fn
|
local _fn
|
||||||
|
@ -251,9 +251,9 @@ function module.set_method_error(err)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- @param lsession test.Session
|
--- @param lsession test.Session
|
||||||
--- @param request_cb function
|
--- @param request_cb function?
|
||||||
--- @param notification_cb function
|
--- @param notification_cb function?
|
||||||
--- @param setup_cb function
|
--- @param setup_cb function?
|
||||||
--- @param timeout integer
|
--- @param timeout integer
|
||||||
--- @return {[1]: integer, [2]: string}
|
--- @return {[1]: integer, [2]: string}
|
||||||
function module.run_session(lsession, request_cb, notification_cb, setup_cb, timeout)
|
function module.run_session(lsession, request_cb, notification_cb, setup_cb, timeout)
|
||||||
@ -642,6 +642,8 @@ function module.set_shell_powershell(fake)
|
|||||||
return found
|
return found
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param func function
|
||||||
|
---@return table<string,function>
|
||||||
function module.create_callindex(func)
|
function module.create_callindex(func)
|
||||||
return setmetatable({}, {
|
return setmetatable({}, {
|
||||||
--- @param tbl table<any,function>
|
--- @param tbl table<any,function>
|
||||||
|
@ -88,7 +88,28 @@ local function isempty(v)
|
|||||||
return type(v) == 'table' and next(v) == nil
|
return type(v) == 'table' and next(v) == nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @class test.functional.ui.screen.Grid
|
||||||
|
--- @field rows table[][]
|
||||||
|
--- @field width integer
|
||||||
|
--- @field height integer
|
||||||
|
|
||||||
--- @class test.functional.ui.screen
|
--- @class test.functional.ui.screen
|
||||||
|
--- @field colors table<string,integer>
|
||||||
|
--- @field colornames table<integer,string>
|
||||||
|
--- @field uimeths table<string,function>
|
||||||
|
--- @field options? table<string,any>
|
||||||
|
--- @field timeout integer
|
||||||
|
--- @field win_position table<integer,table<string,integer>>
|
||||||
|
--- @field float_pos table<integer,table>
|
||||||
|
--- @field cmdline table<integer,table>
|
||||||
|
--- @field cmdline_block table[]
|
||||||
|
--- @field hl_groups table<string,integer>
|
||||||
|
--- @field messages table<integer,table>
|
||||||
|
--- @field private _cursor {grid:integer,row:integer,col:integer}
|
||||||
|
--- @field private _grids table<integer,test.functional.ui.screen.Grid>
|
||||||
|
--- @field private _grid_win_extmarks table<integer,table>
|
||||||
|
--- @field private _attr_table table<integer,table>
|
||||||
|
--- @field private _hl_info table<integer,table>
|
||||||
local Screen = {}
|
local Screen = {}
|
||||||
Screen.__index = Screen
|
Screen.__index = Screen
|
||||||
|
|
||||||
@ -103,13 +124,14 @@ end
|
|||||||
|
|
||||||
local default_screen_timeout = default_timeout_factor * 3500
|
local default_screen_timeout = default_timeout_factor * 3500
|
||||||
|
|
||||||
function Screen._init_colors(session)
|
local function _init_colors()
|
||||||
|
local session = get_session()
|
||||||
local status, rv = session:request('nvim_get_color_map')
|
local status, rv = session:request('nvim_get_color_map')
|
||||||
if not status then
|
if not status then
|
||||||
error('failed to get color map')
|
error('failed to get color map')
|
||||||
end
|
end
|
||||||
local colors = rv
|
local colors = rv --- @type table<string,integer>
|
||||||
local colornames = {}
|
local colornames = {} --- @type table<integer,string>
|
||||||
for name, rgb in pairs(colors) do
|
for name, rgb in pairs(colors) do
|
||||||
-- we disregard the case that colornames might not be unique, as
|
-- we disregard the case that colornames might not be unique, as
|
||||||
-- this is just a helper to get any canonical name of a color
|
-- this is just a helper to get any canonical name of a color
|
||||||
@ -119,17 +141,14 @@ function Screen._init_colors(session)
|
|||||||
Screen.colornames = colornames
|
Screen.colornames = colornames
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param width? integer
|
||||||
|
--- @param height? integer
|
||||||
|
--- @return test.functional.ui.screen
|
||||||
function Screen.new(width, height)
|
function Screen.new(width, height)
|
||||||
if not Screen.colors then
|
if not Screen.colors then
|
||||||
Screen._init_colors(get_session())
|
_init_colors()
|
||||||
end
|
end
|
||||||
|
|
||||||
if not width then
|
|
||||||
width = 53
|
|
||||||
end
|
|
||||||
if not height then
|
|
||||||
height = 14
|
|
||||||
end
|
|
||||||
local self = setmetatable({
|
local self = setmetatable({
|
||||||
timeout = default_screen_timeout,
|
timeout = default_screen_timeout,
|
||||||
title = '',
|
title = '',
|
||||||
@ -166,8 +185,8 @@ function Screen.new(width, height)
|
|||||||
_attr_table = { [0] = { {}, {} } },
|
_attr_table = { [0] = { {}, {} } },
|
||||||
_clear_attrs = nil,
|
_clear_attrs = nil,
|
||||||
_new_attrs = false,
|
_new_attrs = false,
|
||||||
_width = width,
|
_width = width or 53,
|
||||||
_height = height,
|
_height = height or 14,
|
||||||
_grids = {},
|
_grids = {},
|
||||||
_grid_win_extmarks = {},
|
_grid_win_extmarks = {},
|
||||||
_cursor = {
|
_cursor = {
|
||||||
@ -177,6 +196,7 @@ function Screen.new(width, height)
|
|||||||
},
|
},
|
||||||
_busy = false,
|
_busy = false,
|
||||||
}, Screen)
|
}, Screen)
|
||||||
|
|
||||||
local function ui(method, ...)
|
local function ui(method, ...)
|
||||||
if self.rpc_async then
|
if self.rpc_async then
|
||||||
self._session:notify('nvim_ui_' .. method, ...)
|
self._session:notify('nvim_ui_' .. method, ...)
|
||||||
@ -187,7 +207,9 @@ function Screen.new(width, height)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
self.uimeths = create_callindex(ui)
|
self.uimeths = create_callindex(ui)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -203,16 +225,25 @@ function Screen:set_rgb_cterm(val)
|
|||||||
self._rgb_cterm = val
|
self._rgb_cterm = val
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @class test.functional.ui.screen.Opts
|
||||||
|
--- @field ext_linegrid? boolean
|
||||||
|
--- @field ext_multigrid? boolean
|
||||||
|
--- @field ext_newgrid? boolean
|
||||||
|
--- @field ext_popupmenu? boolean
|
||||||
|
--- @field ext_wildmenu? boolean
|
||||||
|
--- @field rgb? boolean
|
||||||
|
--- @field _debug_float? boolean
|
||||||
|
|
||||||
|
--- @param options test.functional.ui.screen.Opts
|
||||||
|
--- @param session? test.Session
|
||||||
function Screen:attach(options, session)
|
function Screen:attach(options, session)
|
||||||
if session == nil then
|
session = session or get_session()
|
||||||
session = get_session()
|
options = options or {}
|
||||||
end
|
|
||||||
if options == nil then
|
|
||||||
options = {}
|
|
||||||
end
|
|
||||||
if options.ext_linegrid == nil then
|
if options.ext_linegrid == nil then
|
||||||
options.ext_linegrid = true
|
options.ext_linegrid = true
|
||||||
end
|
end
|
||||||
|
|
||||||
self._session = session
|
self._session = session
|
||||||
self._options = options
|
self._options = options
|
||||||
self._clear_attrs = (not options.ext_linegrid) and {} or nil
|
self._clear_attrs = (not options.ext_linegrid) and {} or nil
|
||||||
@ -243,8 +274,11 @@ function Screen:try_resize_grid(grid, columns, rows)
|
|||||||
self.uimeths.try_resize_grid(grid, columns, rows)
|
self.uimeths.try_resize_grid(grid, columns, rows)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param option 'ext_linegrid'|'ext_multigrid'|'ext_popupmenu'|'ext_wildmenu'|'rgb'
|
||||||
|
--- @param value boolean
|
||||||
function Screen:set_option(option, value)
|
function Screen:set_option(option, value)
|
||||||
self.uimeths.set_option(option, value)
|
self.uimeths.set_option(option, value)
|
||||||
|
--- @diagnostic disable-next-line:no-unknown
|
||||||
self._options[option] = value
|
self._options[option] = value
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -264,109 +298,154 @@ local ext_keys = {
|
|||||||
'win_viewport',
|
'win_viewport',
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Asserts that the screen state eventually matches an expected state.
|
local expect_keys = {
|
||||||
--
|
grid = true,
|
||||||
-- Can be called with positional args:
|
attr_ids = true,
|
||||||
-- screen:expect(grid, [attr_ids])
|
condition = true,
|
||||||
-- screen:expect(condition)
|
mouse_enabled = true,
|
||||||
-- or keyword args (supports more options):
|
any = true,
|
||||||
-- screen:expect{grid=[[...]], cmdline={...}, condition=function() ... end}
|
mode = true,
|
||||||
--
|
unchanged = true,
|
||||||
--
|
intermediate = true,
|
||||||
-- grid: Expected screen state (string). Each line represents a screen
|
reset = true,
|
||||||
-- row. Last character of each row (typically "|") is stripped.
|
timeout = true,
|
||||||
-- Common indentation is stripped.
|
request_cb = true,
|
||||||
-- "{MATCH:x}" in a line is matched against Lua pattern `x`.
|
hl_groups = true,
|
||||||
-- "*n" at the end of a line means it repeats `n` times.
|
extmarks = true,
|
||||||
-- attr_ids: Expected text attributes. Screen rows are transformed according
|
}
|
||||||
-- to this table, as follows: each substring S composed of
|
|
||||||
-- characters having the same attributes will be substituted by
|
for _, v in ipairs(ext_keys) do
|
||||||
-- "{K:S}", where K is a key in `attr_ids`. Any unexpected
|
expect_keys[v] = true
|
||||||
-- attributes in the final state are an error.
|
end
|
||||||
-- Use an empty table for a text-only (no attributes) expectation.
|
|
||||||
-- Use screen:set_default_attr_ids() to define attributes for many
|
--- @class test.function.ui.screen.Expect
|
||||||
-- expect() calls.
|
---
|
||||||
-- extmarks: Expected win_extmarks accumulated for the grids. For each grid,
|
--- Expected screen state (string). Each line represents a screen
|
||||||
-- the win_extmark messages are accumulated into an array.
|
--- row. Last character of each row (typically "|") is stripped.
|
||||||
-- condition: Function asserting some arbitrary condition. Return value is
|
--- Common indentation is stripped.
|
||||||
-- ignored, throw an error (use eq() or similar) to signal failure.
|
--- "{MATCH:x}" in a line is matched against Lua pattern `x`.
|
||||||
-- any: Lua pattern string expected to match a screen line. NB: the
|
--- "*n" at the end of a line means it repeats `n` times.
|
||||||
-- following chars are magic characters
|
--- @field grid? string
|
||||||
-- ( ) . % + - * ? [ ^ $
|
---
|
||||||
-- and must be escaped with a preceding % for a literal match.
|
--- Expected text attributes. Screen rows are transformed according
|
||||||
-- mode: Expected mode as signaled by "mode_change" event
|
--- to this table, as follows: each substring S composed of
|
||||||
-- unchanged: Test that the screen state is unchanged since the previous
|
--- characters having the same attributes will be substituted by
|
||||||
-- expect(...). Any flush event resulting in a different state is
|
--- "{K:S}", where K is a key in `attr_ids`. Any unexpected
|
||||||
-- considered an error. Not observing any events until timeout
|
--- attributes in the final state are an error.
|
||||||
-- is acceptable.
|
--- Use an empty table for a text-only (no attributes) expectation.
|
||||||
-- intermediate:Test that the final state is the same as the previous expect,
|
--- Use screen:set_default_attr_ids() to define attributes for many
|
||||||
-- but expect an intermediate state that is different. If possible
|
--- expect() calls.
|
||||||
-- it is better to use an explicit screen:expect(...) for this
|
--- @field attr_ids? table<integer,table<string,any>>
|
||||||
-- intermediate state.
|
---
|
||||||
-- reset: Reset the state internal to the test Screen before starting to
|
--- Expected win_extmarks accumulated for the grids. For each grid,
|
||||||
-- receive updates. This should be used after command("redraw!")
|
--- the win_extmark messages are accumulated into an array.
|
||||||
-- or some other mechanism that will invoke "redraw!", to check
|
--- @field extmarks? table<integer,table>
|
||||||
-- that all screen state is transmitted again. This includes
|
---
|
||||||
-- state related to ext_ features as mentioned below.
|
--- Function asserting some arbitrary condition. Return value is
|
||||||
-- timeout: maximum time that will be waited until the expected state is
|
--- ignored, throw an error (use eq() or similar) to signal failure.
|
||||||
-- seen (or maximum time to observe an incorrect change when
|
--- @field condition? fun()
|
||||||
-- `unchanged` flag is used)
|
---
|
||||||
--
|
--- Lua pattern string expected to match a screen line. NB: the
|
||||||
-- The following keys should be used to expect the state of various ext_
|
--- following chars are magic characters
|
||||||
-- features. Note that an absent key will assert that the item is currently
|
--- ( ) . % + - * ? [ ^ $
|
||||||
-- NOT present on the screen, also when positional form is used.
|
--- and must be escaped with a preceding % for a literal match.
|
||||||
--
|
--- @field any? string
|
||||||
-- popupmenu: Expected ext_popupmenu state,
|
---
|
||||||
-- cmdline: Expected ext_cmdline state, as an array of cmdlines of
|
--- Expected mode as signaled by "mode_change" event
|
||||||
-- different level.
|
--- @field mode? string
|
||||||
-- cmdline_block: Expected ext_cmdline block (for function definitions)
|
---
|
||||||
-- wildmenu_items: Expected items for ext_wildmenu
|
--- Test that the screen state is unchanged since the previous
|
||||||
-- wildmenu_pos: Expected position for ext_wildmenu
|
--- expect(...). Any flush event resulting in a different state is
|
||||||
|
--- considered an error. Not observing any events until timeout
|
||||||
|
--- is acceptable.
|
||||||
|
--- @field unchanged? boolean
|
||||||
|
---
|
||||||
|
--- Test that the final state is the same as the previous expect,
|
||||||
|
--- but expect an intermediate state that is different. If possible
|
||||||
|
--- it is better to use an explicit screen:expect(...) for this
|
||||||
|
--- intermediate state.
|
||||||
|
--- @field intermediate? boolean
|
||||||
|
---
|
||||||
|
--- Reset the state internal to the test Screen before starting to
|
||||||
|
--- receive updates. This should be used after command("redraw!")
|
||||||
|
--- or some other mechanism that will invoke "redraw!", to check
|
||||||
|
--- that all screen state is transmitted again. This includes
|
||||||
|
--- state related to ext_ features as mentioned below.
|
||||||
|
--- @field reset? boolean
|
||||||
|
---
|
||||||
|
--- maximum time that will be waited until the expected state is
|
||||||
|
--- seen (or maximum time to observe an incorrect change when
|
||||||
|
--- `unchanged` flag is used)
|
||||||
|
--- @field timeout? integer
|
||||||
|
---
|
||||||
|
--- @field mouse_enabled? boolean
|
||||||
|
---
|
||||||
|
--- @field win_viewport? table<integer,table<string,integer>>
|
||||||
|
--- @field float_pos? {[1]:integer,[2]:integer}
|
||||||
|
--- @field hl_groups? table<string,integer>
|
||||||
|
---
|
||||||
|
--- The following keys should be used to expect the state of various ext_
|
||||||
|
--- features. Note that an absent key will assert that the item is currently
|
||||||
|
--- NOT present on the screen, also when positional form is used.
|
||||||
|
---
|
||||||
|
--- Expected ext_popupmenu state,
|
||||||
|
--- @field popupmenu? table
|
||||||
|
---
|
||||||
|
--- Expected ext_cmdline state, as an array of cmdlines of
|
||||||
|
--- different level.
|
||||||
|
--- @field cmdline? table
|
||||||
|
---
|
||||||
|
--- Expected ext_cmdline block (for function definitions)
|
||||||
|
--- @field cmdline_block? table
|
||||||
|
---
|
||||||
|
--- items for ext_wildmenu
|
||||||
|
--- @field wildmenu_items? table
|
||||||
|
---
|
||||||
|
--- position for ext_wildmenu
|
||||||
|
--- @field wildmenu_pos? table
|
||||||
|
|
||||||
|
--- Asserts that the screen state eventually matches an expected state.
|
||||||
|
---
|
||||||
|
--- Can be called with positional args:
|
||||||
|
--- screen:expect(grid, [attr_ids])
|
||||||
|
--- screen:expect(condition)
|
||||||
|
--- or keyword args (supports more options):
|
||||||
|
--- screen:expect{grid=[[...]], cmdline={...}, condition=function() ... end}
|
||||||
|
---
|
||||||
|
--- @param expected string|function|test.function.ui.screen.Expect
|
||||||
|
--- @param attr_ids? table<integer,table<string,any>>
|
||||||
function Screen:expect(expected, attr_ids, ...)
|
function Screen:expect(expected, attr_ids, ...)
|
||||||
local grid, condition = nil, nil
|
--- @type string, fun()
|
||||||
local expected_rows = {}
|
local grid, condition
|
||||||
|
|
||||||
assert(next({ ... }) == nil, 'invalid args to expect()')
|
assert(next({ ... }) == nil, 'invalid args to expect()')
|
||||||
|
|
||||||
if type(expected) == 'table' then
|
if type(expected) == 'table' then
|
||||||
assert(not (attr_ids ~= nil))
|
assert(attr_ids == nil)
|
||||||
local is_key = {
|
for k, _ in
|
||||||
grid = true,
|
pairs(expected --[[@as table<string,any>]])
|
||||||
attr_ids = true,
|
do
|
||||||
condition = true,
|
if not expect_keys[k] then
|
||||||
mouse_enabled = true,
|
|
||||||
any = true,
|
|
||||||
mode = true,
|
|
||||||
unchanged = true,
|
|
||||||
intermediate = true,
|
|
||||||
reset = true,
|
|
||||||
timeout = true,
|
|
||||||
request_cb = true,
|
|
||||||
hl_groups = true,
|
|
||||||
extmarks = true,
|
|
||||||
}
|
|
||||||
for _, v in ipairs(ext_keys) do
|
|
||||||
is_key[v] = true
|
|
||||||
end
|
|
||||||
for k, _ in pairs(expected) do
|
|
||||||
if not is_key[k] then
|
|
||||||
error("Screen:expect: Unknown keyword argument '" .. k .. "'")
|
error("Screen:expect: Unknown keyword argument '" .. k .. "'")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
grid = expected.grid
|
grid = expected.grid
|
||||||
attr_ids = expected.attr_ids
|
attr_ids = expected.attr_ids
|
||||||
condition = expected.condition
|
condition = expected.condition
|
||||||
assert(not (expected.any ~= nil and grid ~= nil))
|
assert(expected.any == nil or grid == nil)
|
||||||
elseif type(expected) == 'string' then
|
elseif type(expected) == 'string' then
|
||||||
grid = expected
|
grid = expected
|
||||||
expected = {}
|
expected = {}
|
||||||
elseif type(expected) == 'function' then
|
elseif type(expected) == 'function' then
|
||||||
assert(not (attr_ids ~= nil))
|
assert(attr_ids == nil)
|
||||||
condition = expected
|
condition = expected
|
||||||
expected = {}
|
expected = {}
|
||||||
else
|
else
|
||||||
assert(false)
|
assert(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
if grid ~= nil then
|
local expected_rows = {} --- @type string[]
|
||||||
|
if grid then
|
||||||
-- Remove the last line and dedent. Note that gsub returns more then one
|
-- Remove the last line and dedent. Note that gsub returns more then one
|
||||||
-- value.
|
-- value.
|
||||||
grid = dedent(grid:gsub('\n[ ]+$', ''), 0)
|
grid = dedent(grid:gsub('\n[ ]+$', ''), 0)
|
||||||
@ -374,18 +453,23 @@ function Screen:expect(expected, attr_ids, ...)
|
|||||||
table.insert(expected_rows, row)
|
table.insert(expected_rows, row)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local attr_state = {
|
local attr_state = {
|
||||||
ids = attr_ids or self._default_attr_ids,
|
ids = attr_ids or self._default_attr_ids,
|
||||||
}
|
}
|
||||||
|
|
||||||
if isempty(attr_ids) then
|
if isempty(attr_ids) then
|
||||||
attr_state.ids = nil
|
attr_state.ids = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
if self._options.ext_linegrid then
|
if self._options.ext_linegrid then
|
||||||
attr_state.id_to_index = self:linegrid_check_attrs(attr_state.ids or {})
|
attr_state.id_to_index = self:linegrid_check_attrs(attr_state.ids or {})
|
||||||
end
|
end
|
||||||
|
|
||||||
self._new_attrs = false
|
self._new_attrs = false
|
||||||
self:_wait(function()
|
self:_wait(function()
|
||||||
if condition ~= nil then
|
if condition then
|
||||||
|
--- @type boolean, string
|
||||||
local status, res = pcall(condition)
|
local status, res = pcall(condition)
|
||||||
if not status then
|
if not status then
|
||||||
return tostring(res)
|
return tostring(res)
|
||||||
@ -398,10 +482,10 @@ function Screen:expect(expected, attr_ids, ...)
|
|||||||
|
|
||||||
local actual_rows = self:render(not expected.any, attr_state)
|
local actual_rows = self:render(not expected.any, attr_state)
|
||||||
|
|
||||||
if expected.any ~= nil then
|
if expected.any then
|
||||||
-- Search for `any` anywhere in the screen lines.
|
-- Search for `any` anywhere in the screen lines.
|
||||||
local actual_screen_str = table.concat(actual_rows, '\n')
|
local actual_screen_str = table.concat(actual_rows, '\n')
|
||||||
if nil == string.find(actual_screen_str, expected.any) then
|
if not actual_screen_str:find(expected.any) then
|
||||||
return (
|
return (
|
||||||
'Failed to match any screen lines.\n'
|
'Failed to match any screen lines.\n'
|
||||||
.. 'Expected (anywhere): "'
|
.. 'Expected (anywhere): "'
|
||||||
@ -414,9 +498,9 @@ function Screen:expect(expected, attr_ids, ...)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if grid ~= nil then
|
if grid then
|
||||||
for i, row in ipairs(expected_rows) do
|
for i, row in ipairs(expected_rows) do
|
||||||
local count
|
local count --- @type integer?
|
||||||
row, count = row:match('^(.*%|)%*(%d+)$')
|
row, count = row:match('^(.*%|)%*(%d+)$')
|
||||||
if row then
|
if row then
|
||||||
count = tonumber(count)
|
count = tonumber(count)
|
||||||
@ -438,7 +522,7 @@ function Screen:expect(expected, attr_ids, ...)
|
|||||||
local msg_expected_rows = shallowcopy(expected_rows)
|
local msg_expected_rows = shallowcopy(expected_rows)
|
||||||
local msg_actual_rows = shallowcopy(actual_rows)
|
local msg_actual_rows = shallowcopy(actual_rows)
|
||||||
for i, row in ipairs(expected_rows) do
|
for i, row in ipairs(expected_rows) do
|
||||||
local pat = nil
|
local pat = nil --- @type string?
|
||||||
if actual_rows[i] and row ~= actual_rows[i] then
|
if actual_rows[i] and row ~= actual_rows[i] then
|
||||||
local after = row
|
local after = row
|
||||||
while true do
|
while true do
|
||||||
@ -447,6 +531,7 @@ function Screen:expect(expected, attr_ids, ...)
|
|||||||
pat = pat and (pat .. pesc(after))
|
pat = pat and (pat .. pesc(after))
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
--- @type string
|
||||||
pat = (pat or '') .. pesc(after:sub(1, s - 1)) .. m
|
pat = (pat or '') .. pesc(after:sub(1, s - 1)) .. m
|
||||||
after = after:sub(e + 1)
|
after = after:sub(e + 1)
|
||||||
end
|
end
|
||||||
@ -568,8 +653,12 @@ function Screen:expect_unchanged(intermediate, waittime_ms, ignore_attrs)
|
|||||||
self:expect(kwargs)
|
self:expect(kwargs)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @private
|
||||||
|
--- @param check fun(): string
|
||||||
|
--- @param flags table<string,any>
|
||||||
function Screen:_wait(check, flags)
|
function Screen:_wait(check, flags)
|
||||||
local err, checked = false, false
|
local err --- @type string?
|
||||||
|
local checked = false
|
||||||
local success_seen = false
|
local success_seen = false
|
||||||
local failure_after_success = false
|
local failure_after_success = false
|
||||||
local did_flush = true
|
local did_flush = true
|
||||||
@ -600,7 +689,7 @@ function Screen:_wait(check, flags)
|
|||||||
|
|
||||||
-- For an "unchanged" test, flags.timeout is the time during which the state
|
-- For an "unchanged" test, flags.timeout is the time during which the state
|
||||||
-- must not change, so always wait this full time.
|
-- must not change, so always wait this full time.
|
||||||
if (flags.unchanged or flags.intermediate) and flags.timeout ~= nil then
|
if (flags.unchanged or flags.intermediate) and flags.timeout then
|
||||||
minimal_timeout = timeout
|
minimal_timeout = timeout
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -717,6 +806,8 @@ function Screen:sleep(ms, request_cb)
|
|||||||
run_session(self._session, request_cb, notification_cb, nil, ms)
|
run_session(self._session, request_cb, notification_cb, nil, ms)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @private
|
||||||
|
--- @param updates {[1]:string, [integer]:any[]}[]
|
||||||
function Screen:_redraw(updates)
|
function Screen:_redraw(updates)
|
||||||
local did_flush = false
|
local did_flush = false
|
||||||
for k, update in ipairs(updates) do
|
for k, update in ipairs(updates) do
|
||||||
@ -724,6 +815,7 @@ function Screen:_redraw(updates)
|
|||||||
local method = update[1]
|
local method = update[1]
|
||||||
for i = 2, #update do
|
for i = 2, #update do
|
||||||
local handler_name = '_handle_' .. method
|
local handler_name = '_handle_' .. method
|
||||||
|
--- @type function
|
||||||
local handler = self[handler_name]
|
local handler = self[handler_name]
|
||||||
assert(handler ~= nil, 'missing handler: Screen:' .. handler_name)
|
assert(handler ~= nil, 'missing handler: Screen:' .. handler_name)
|
||||||
local status, res = pcall(handler, self, unpack(update[i]))
|
local status, res = pcall(handler, self, unpack(update[i]))
|
||||||
@ -815,6 +907,8 @@ function Screen:_reset()
|
|||||||
self._grid_win_extmarks = {}
|
self._grid_win_extmarks = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param cursor_style_enabled boolean
|
||||||
|
--- @param mode_info table[]
|
||||||
function Screen:_handle_mode_info_set(cursor_style_enabled, mode_info)
|
function Screen:_handle_mode_info_set(cursor_style_enabled, mode_info)
|
||||||
self._cursor_style_enabled = cursor_style_enabled
|
self._cursor_style_enabled = cursor_style_enabled
|
||||||
for _, item in pairs(mode_info) do
|
for _, item in pairs(mode_info) do
|
||||||
@ -973,11 +1067,19 @@ function Screen:_handle_scroll(count)
|
|||||||
self:_handle_grid_scroll(1, top - 1, bot, left - 1, right, count, 0)
|
self:_handle_grid_scroll(1, top - 1, bot, left - 1, right, count, 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param g any
|
||||||
|
--- @param top integer
|
||||||
|
--- @param bot integer
|
||||||
|
--- @param left integer
|
||||||
|
--- @param right integer
|
||||||
|
--- @param rows integer
|
||||||
|
--- @param cols integer
|
||||||
function Screen:_handle_grid_scroll(g, top, bot, left, right, rows, cols)
|
function Screen:_handle_grid_scroll(g, top, bot, left, right, rows, cols)
|
||||||
top = top + 1
|
top = top + 1
|
||||||
left = left + 1
|
left = left + 1
|
||||||
assert(cols == 0)
|
assert(cols == 0)
|
||||||
local grid = self._grids[g]
|
local grid = self._grids[g]
|
||||||
|
--- @type integer, integer, integer
|
||||||
local start, stop, step
|
local start, stop, step
|
||||||
|
|
||||||
if rows > 0 then
|
if rows > 0 then
|
||||||
@ -1013,6 +1115,8 @@ function Screen:_handle_hl_attr_define(id, rgb_attrs, cterm_attrs, info)
|
|||||||
self._new_attrs = true
|
self._new_attrs = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param name string
|
||||||
|
--- @param id integer
|
||||||
function Screen:_handle_hl_group_set(name, id)
|
function Screen:_handle_hl_group_set(name, id)
|
||||||
self.hl_groups[name] = id
|
self.hl_groups[name] = id
|
||||||
end
|
end
|
||||||
@ -1020,9 +1124,8 @@ end
|
|||||||
function Screen:get_hl(val)
|
function Screen:get_hl(val)
|
||||||
if self._options.ext_newgrid then
|
if self._options.ext_newgrid then
|
||||||
return self._attr_table[val][1]
|
return self._attr_table[val][1]
|
||||||
else
|
|
||||||
return val
|
|
||||||
end
|
end
|
||||||
|
return val
|
||||||
end
|
end
|
||||||
|
|
||||||
function Screen:_handle_highlight_set(attrs)
|
function Screen:_handle_highlight_set(attrs)
|
||||||
@ -1038,6 +1141,10 @@ function Screen:_handle_put(str)
|
|||||||
self._cursor.col = self._cursor.col + 1
|
self._cursor.col = self._cursor.col + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param grid integer
|
||||||
|
--- @param row integer
|
||||||
|
--- @param col integer
|
||||||
|
--- @param items integer[][]
|
||||||
function Screen:_handle_grid_line(grid, row, col, items)
|
function Screen:_handle_grid_line(grid, row, col, items)
|
||||||
assert(self._options.ext_linegrid)
|
assert(self._options.ext_linegrid)
|
||||||
assert(#items > 0)
|
assert(#items > 0)
|
||||||
@ -1045,7 +1152,7 @@ function Screen:_handle_grid_line(grid, row, col, items)
|
|||||||
local colpos = col + 1
|
local colpos = col + 1
|
||||||
local hl_id = 0
|
local hl_id = 0
|
||||||
for _, item in ipairs(items) do
|
for _, item in ipairs(items) do
|
||||||
local text, hl_id_cell, count = unpack(item)
|
local text, hl_id_cell, count = item[1], item[2], item[3]
|
||||||
if hl_id_cell ~= nil then
|
if hl_id_cell ~= nil then
|
||||||
hl_id = hl_id_cell
|
hl_id = hl_id_cell
|
||||||
end
|
end
|
||||||
@ -1379,6 +1486,10 @@ function Screen:redraw_debug(attrs, ignore, timeout)
|
|||||||
run_session(self._session, nil, notification_cb, nil, timeout)
|
run_session(self._session, nil, notification_cb, nil, timeout)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param headers boolean
|
||||||
|
--- @param attr_state any
|
||||||
|
--- @param preview? boolean
|
||||||
|
--- @return string[]
|
||||||
function Screen:render(headers, attr_state, preview)
|
function Screen:render(headers, attr_state, preview)
|
||||||
headers = headers and (self._options.ext_multigrid or self._options._debug_float)
|
headers = headers and (self._options.ext_multigrid or self._options._debug_float)
|
||||||
local rv = {}
|
local rv = {}
|
||||||
|
Loading…
Reference in New Issue
Block a user