mirror of
https://github.com/neovim/neovim.git
synced 2025-09-24 03:58:32 +00:00
feat(api/ui): win_extmarks
This commit is contained in:
@@ -1606,3 +1606,209 @@ describe('Extmarks buffer api with many marks', function()
|
||||
eq({}, get_marks(ns2))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('API/win_extmark', function()
|
||||
local screen
|
||||
local marks, line1, line2
|
||||
local ns
|
||||
|
||||
before_each(function()
|
||||
-- Initialize some namespaces and insert text into a buffer
|
||||
marks = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
|
||||
|
||||
line1 = "non ui-watched line"
|
||||
line2 = "ui-watched line"
|
||||
|
||||
clear()
|
||||
|
||||
insert(line1)
|
||||
feed("o<esc>")
|
||||
insert(line2)
|
||||
ns = request('nvim_create_namespace', "extmark-ui")
|
||||
end)
|
||||
|
||||
it('sends and only sends ui-watched marks to ui', function()
|
||||
screen = Screen.new(20, 4)
|
||||
screen:attach()
|
||||
-- should send this
|
||||
set_extmark(ns, marks[1], 1, 0, { ui_watched = true })
|
||||
-- should not send this
|
||||
set_extmark(ns, marks[2], 0, 0, { ui_watched = false })
|
||||
screen:expect({
|
||||
grid = [[
|
||||
non ui-watched line |
|
||||
ui-watched lin^e |
|
||||
~ |
|
||||
|
|
||||
]],
|
||||
extmarks = {
|
||||
[2] = {
|
||||
-- positioned at the end of the 2nd line
|
||||
{ {id = 1000}, 1, 1, 1, 16 },
|
||||
}
|
||||
},
|
||||
})
|
||||
end)
|
||||
|
||||
it('sends multiple ui-watched marks to ui', function()
|
||||
screen = Screen.new(20, 4)
|
||||
screen:attach()
|
||||
-- should send all of these
|
||||
set_extmark(ns, marks[1], 1, 0, { ui_watched = true, virt_text_pos = "overlay" })
|
||||
set_extmark(ns, marks[2], 1, 2, { ui_watched = true, virt_text_pos = "overlay" })
|
||||
set_extmark(ns, marks[3], 1, 4, { ui_watched = true, virt_text_pos = "overlay" })
|
||||
set_extmark(ns, marks[4], 1, 6, { ui_watched = true, virt_text_pos = "overlay" })
|
||||
set_extmark(ns, marks[5], 1, 8, { ui_watched = true })
|
||||
screen:expect({
|
||||
grid = [[
|
||||
non ui-watched line |
|
||||
ui-watched lin^e |
|
||||
~ |
|
||||
|
|
||||
]],
|
||||
extmarks = {
|
||||
[2] = {
|
||||
-- earlier notifications
|
||||
{ {id = 1000}, 1, 1, 1, 0 },
|
||||
{ {id = 1000}, 1, 1, 1, 0 }, { {id = 1000}, 1, 2, 1, 2 },
|
||||
{ {id = 1000}, 1, 1, 1, 0 }, { {id = 1000}, 1, 2, 1, 2 }, { {id = 1000}, 1, 3, 1, 4 },
|
||||
{ {id = 1000}, 1, 1, 1, 0 }, { {id = 1000}, 1, 2, 1, 2 }, { {id = 1000}, 1, 3, 1, 4 }, { {id = 1000}, 1, 4, 1, 6 },
|
||||
-- final
|
||||
-- overlay
|
||||
{ {id = 1000}, 1, 1, 1, 0 },
|
||||
{ {id = 1000}, 1, 2, 1, 2 },
|
||||
{ {id = 1000}, 1, 3, 1, 4 },
|
||||
{ {id = 1000}, 1, 4, 1, 6 },
|
||||
-- eol
|
||||
{ {id = 1000}, 1, 5, 1, 16 },
|
||||
}
|
||||
},
|
||||
})
|
||||
end)
|
||||
|
||||
it('updates ui-watched marks', function()
|
||||
screen = Screen.new(20, 4)
|
||||
screen:attach()
|
||||
-- should send this
|
||||
set_extmark(ns, marks[1], 1, 0, { ui_watched = true })
|
||||
-- should not send this
|
||||
set_extmark(ns, marks[2], 0, 0, { ui_watched = false })
|
||||
-- make some changes
|
||||
insert(" update")
|
||||
screen:expect({
|
||||
grid = [[
|
||||
non ui-watched line |
|
||||
ui-watched linupdat^e|
|
||||
e |
|
||||
|
|
||||
]],
|
||||
extmarks = {
|
||||
[2] = {
|
||||
-- positioned at the end of the 2nd line
|
||||
{ {id = 1000}, 1, 1, 1, 16 },
|
||||
-- updated and wrapped to 3rd line
|
||||
{ {id = 1000}, 1, 1, 2, 2 },
|
||||
}
|
||||
}
|
||||
})
|
||||
feed("<c-e>")
|
||||
screen:expect({
|
||||
grid = [[
|
||||
ui-watched linupdat^e|
|
||||
e |
|
||||
~ |
|
||||
|
|
||||
]],
|
||||
extmarks = {
|
||||
[2] = {
|
||||
-- positioned at the end of the 2nd line
|
||||
{ {id = 1000}, 1, 1, 1, 16 },
|
||||
-- updated and wrapped to 3rd line
|
||||
{ {id = 1000}, 1, 1, 2, 2 },
|
||||
-- scrolled up one line, should be handled by grid scroll
|
||||
}
|
||||
}
|
||||
})
|
||||
end)
|
||||
|
||||
it('sends ui-watched to splits', function()
|
||||
screen = Screen.new(20, 8)
|
||||
screen:attach({ext_multigrid=true})
|
||||
-- should send this
|
||||
set_extmark(ns, marks[1], 1, 0, { ui_watched = true })
|
||||
-- should not send this
|
||||
set_extmark(ns, marks[2], 0, 0, { ui_watched = false })
|
||||
command('split')
|
||||
screen:expect({
|
||||
grid = [[
|
||||
## grid 1
|
||||
[4:--------------------]|
|
||||
[4:--------------------]|
|
||||
[4:--------------------]|
|
||||
[No Name] [+] |
|
||||
[2:--------------------]|
|
||||
[2:--------------------]|
|
||||
[No Name] [+] |
|
||||
[3:--------------------]|
|
||||
## grid 2
|
||||
non ui-watched line |
|
||||
ui-watched line |
|
||||
## grid 3
|
||||
|
|
||||
## grid 4
|
||||
non ui-watched line |
|
||||
ui-watched lin^e |
|
||||
~ |
|
||||
]],
|
||||
extmarks = {
|
||||
[2] = {
|
||||
-- positioned at the end of the 2nd line
|
||||
{ {id = 1000}, 1, 1, 1, 16 },
|
||||
-- updated after split
|
||||
{ {id = 1000}, 1, 1, 1, 16 },
|
||||
},
|
||||
[4] = {
|
||||
-- only after split
|
||||
{ {id = 1001}, 1, 1, 1, 16 },
|
||||
}
|
||||
}
|
||||
})
|
||||
-- make some changes
|
||||
insert(" update")
|
||||
screen:expect({
|
||||
grid = [[
|
||||
## grid 1
|
||||
[4:--------------------]|
|
||||
[4:--------------------]|
|
||||
[4:--------------------]|
|
||||
[No Name] [+] |
|
||||
[2:--------------------]|
|
||||
[2:--------------------]|
|
||||
[No Name] [+] |
|
||||
[3:--------------------]|
|
||||
## grid 2
|
||||
non ui-watched line |
|
||||
ui-watched linupd@@@|
|
||||
## grid 3
|
||||
|
|
||||
## grid 4
|
||||
non ui-watched line |
|
||||
ui-watched linupdat^e|
|
||||
e |
|
||||
]],
|
||||
extmarks = {
|
||||
[2] = {
|
||||
-- positioned at the end of the 2nd line
|
||||
{ {id = 1000}, 1, 1, 1, 16 },
|
||||
-- updated after split
|
||||
{ {id = 1000}, 1, 1, 1, 16 },
|
||||
},
|
||||
[4] = {
|
||||
{ {id = 1001}, 1, 1, 1, 16 },
|
||||
-- updated
|
||||
{ {id = 1001}, 1, 1, 2, 2 },
|
||||
}
|
||||
}
|
||||
})
|
||||
end)
|
||||
end)
|
||||
|
@@ -179,6 +179,7 @@ function Screen.new(width, height)
|
||||
_width = width,
|
||||
_height = height,
|
||||
_grids = {},
|
||||
_grid_win_extmarks = {},
|
||||
_cursor = {
|
||||
grid = 1, row = 1, col = 1
|
||||
},
|
||||
@@ -278,6 +279,8 @@ local ext_keys = {
|
||||
-- attributes in the final state are an error.
|
||||
-- Use screen:set_default_attr_ids() to define attributes for many
|
||||
-- expect() calls.
|
||||
-- extmarks: Expected win_extmarks accumulated for the grids. For each grid,
|
||||
-- the win_extmark messages are accumulated into an array.
|
||||
-- condition: Function asserting some arbitrary condition. Return value is
|
||||
-- ignored, throw an error (use eq() or similar) to signal failure.
|
||||
-- any: Lua pattern string expected to match a screen line. NB: the
|
||||
@@ -320,7 +323,7 @@ function Screen:expect(expected, attr_ids, ...)
|
||||
assert(not (attr_ids ~= nil))
|
||||
local is_key = {grid=true, attr_ids=true, condition=true, mouse_enabled=true,
|
||||
any=true, mode=true, unchanged=true, intermediate=true,
|
||||
reset=true, timeout=true, request_cb=true, hl_groups=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
|
||||
@@ -459,6 +462,25 @@ screen:redraw_debug() to show all intermediate screen states. ]])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if expected.extmarks ~= nil then
|
||||
for gridid, expected_marks in pairs(expected.extmarks) do
|
||||
local stored_marks = self._grid_win_extmarks[gridid]
|
||||
if stored_marks == nil then
|
||||
return 'no win_extmark for grid '..tostring(gridid)
|
||||
end
|
||||
local status, res = pcall(eq, expected_marks, stored_marks, "extmarks for grid "..tostring(gridid))
|
||||
if not status then
|
||||
return tostring(res)
|
||||
end
|
||||
end
|
||||
for gridid, _ in pairs(self._grid_win_extmarks) do
|
||||
local expected_marks = expected.extmarks[gridid]
|
||||
if expected_marks == nil then
|
||||
return 'unexpected win_extmark for grid '..tostring(gridid)
|
||||
end
|
||||
end
|
||||
end
|
||||
end, expected)
|
||||
end
|
||||
|
||||
@@ -703,6 +725,7 @@ function Screen:_reset()
|
||||
self.cmdline_block = {}
|
||||
self.wildmenu_items = nil
|
||||
self.wildmenu_pos = nil
|
||||
self._grid_win_extmarks = {}
|
||||
end
|
||||
|
||||
function Screen:_handle_mode_info_set(cursor_style_enabled, mode_info)
|
||||
@@ -803,6 +826,13 @@ function Screen:_handle_win_close(grid)
|
||||
self.float_pos[grid] = nil
|
||||
end
|
||||
|
||||
function Screen:_handle_win_extmark(grid, ...)
|
||||
if self._grid_win_extmarks[grid] == nil then
|
||||
self._grid_win_extmarks[grid] = {}
|
||||
end
|
||||
table.insert(self._grid_win_extmarks[grid], {...})
|
||||
end
|
||||
|
||||
function Screen:_handle_busy_start()
|
||||
self._busy = true
|
||||
end
|
||||
|
Reference in New Issue
Block a user