mirror of
https://github.com/neovim/neovim
synced 2025-07-15 16:51:49 +00:00
test(messages/cmdline_spec): convert highlight IDs to name and format (#34845)
Problem: Hardcoded highlight IDs for ext_messages/cmdline output need to be adjusted everytime a builtin highlight group is added. Solution: Store a global map of default highlights through nvim_get_hl() and fetch missing (custom) highlight groups through synIDattr(). Use more compact formatting for screen:expect().
This commit is contained in:
@ -749,8 +749,8 @@ This UI extension delegates presentation of the |cmdline| (except 'wildmenu').
|
||||
For command-line 'wildmenu' UI events, activate |ui-popupmenu|.
|
||||
|
||||
["cmdline_show", content, pos, firstc, prompt, indent, level, hl_id] ~
|
||||
content: List of [attrs, string]
|
||||
[[{}, "t"], [attrs, "est"], ...]
|
||||
content: List of [attrs, string, hl_id]
|
||||
[[{}, "t", hl_id], [attrs, "est", hl_id], ...]
|
||||
|
||||
Triggered when the cmdline is displayed or changed.
|
||||
The `content` is the full content that should be displayed in the
|
||||
|
@ -3503,26 +3503,29 @@ static void ui_ext_cmdline_show(CmdlineInfo *line)
|
||||
}
|
||||
char *buf = arena_alloc(&arena, len, false);
|
||||
memset(buf, '*', len);
|
||||
Array item = arena_array(&arena, 2);
|
||||
Array item = arena_array(&arena, 3);
|
||||
ADD_C(item, INTEGER_OBJ(0));
|
||||
ADD_C(item, STRING_OBJ(cbuf_as_string(buf, len)));
|
||||
ADD_C(item, INTEGER_OBJ(0));
|
||||
ADD_C(content, ARRAY_OBJ(item));
|
||||
} else if (kv_size(line->last_colors.colors)) {
|
||||
content = arena_array(&arena, kv_size(line->last_colors.colors));
|
||||
for (size_t i = 0; i < kv_size(line->last_colors.colors); i++) {
|
||||
CmdlineColorChunk chunk = kv_A(line->last_colors.colors, i);
|
||||
Array item = arena_array(&arena, 2);
|
||||
Array item = arena_array(&arena, 3);
|
||||
ADD_C(item, INTEGER_OBJ(chunk.hl_id == 0 ? 0 : syn_id2attr(chunk.hl_id)));
|
||||
|
||||
assert(chunk.end >= chunk.start);
|
||||
ADD_C(item, STRING_OBJ(cbuf_as_string(line->cmdbuff + chunk.start,
|
||||
(size_t)(chunk.end - chunk.start))));
|
||||
ADD_C(item, INTEGER_OBJ(chunk.hl_id));
|
||||
ADD_C(content, ARRAY_OBJ(item));
|
||||
}
|
||||
} else {
|
||||
Array item = arena_array(&arena, 2);
|
||||
Array item = arena_array(&arena, 3);
|
||||
ADD_C(item, INTEGER_OBJ(0));
|
||||
ADD_C(item, CSTR_AS_OBJ(line->cmdbuff));
|
||||
ADD_C(item, INTEGER_OBJ(0));
|
||||
content = arena_array(&arena, 1);
|
||||
ADD_C(content, ARRAY_OBJ(item));
|
||||
}
|
||||
@ -3549,6 +3552,7 @@ void ui_ext_cmdline_block_append(size_t indent, const char *line)
|
||||
Array item = ARRAY_DICT_INIT;
|
||||
ADD(item, INTEGER_OBJ(0));
|
||||
ADD(item, CSTR_AS_OBJ(buf));
|
||||
ADD(item, INTEGER_OBJ(0));
|
||||
Array content = ARRAY_DICT_INIT;
|
||||
ADD(content, ARRAY_OBJ(item));
|
||||
ADD(cmdline_block, ARRAY_OBJ(content));
|
||||
|
@ -191,11 +191,7 @@ describe('vim.ui_attach', function()
|
||||
^1 |
|
||||
{1:~ }|*4
|
||||
]],
|
||||
cmdline = { {
|
||||
content = { { '' } },
|
||||
firstc = ':',
|
||||
pos = 0,
|
||||
} },
|
||||
cmdline = { { content = { { '' } }, firstc = ':', pos = 0 } },
|
||||
})
|
||||
feed('version<CR>')
|
||||
screen:expect({
|
||||
@ -203,7 +199,6 @@ describe('vim.ui_attach', function()
|
||||
^2 |
|
||||
{1:~ }|*4
|
||||
]],
|
||||
cmdline = { { abort = false } },
|
||||
condition = function()
|
||||
eq('list_cmd', screen.messages[1].kind)
|
||||
screen.messages = {} -- Ignore the build dependent :version content
|
||||
@ -216,28 +211,12 @@ describe('vim.ui_attach', function()
|
||||
{1:~ }|*4
|
||||
]],
|
||||
cmdline = {
|
||||
{
|
||||
content = { { '' } },
|
||||
hl_id = 10,
|
||||
pos = 0,
|
||||
prompt = '[Y]es, (N)o, (C)ancel: ',
|
||||
},
|
||||
},
|
||||
messages = {
|
||||
{
|
||||
content = { { '\nSave changes?\n', 6, 10 } },
|
||||
kind = 'confirm',
|
||||
},
|
||||
{ content = { { '' } }, hl = 'MoreMsg', pos = 0, prompt = '[Y]es, (N)o, (C)ancel: ' },
|
||||
},
|
||||
messages = { { content = { { '\nSave changes?\n', 6, 'MoreMsg' } }, kind = 'confirm' } },
|
||||
})
|
||||
feed('n')
|
||||
screen:expect({
|
||||
grid = [[
|
||||
^4 |
|
||||
{1:~ }|*4
|
||||
]],
|
||||
cmdline = { { abort = false } },
|
||||
})
|
||||
screen:expect_unchanged()
|
||||
end)
|
||||
|
||||
it("preserved 'incsearch/command' screen state after :redraw from ext_cmdline", function()
|
||||
@ -257,37 +236,31 @@ describe('vim.ui_attach', function()
|
||||
]])
|
||||
-- Updates a cmdline window
|
||||
feed(':cmdline')
|
||||
screen:expect({
|
||||
grid = [[
|
||||
cmdline |
|
||||
{2:cmdline [+] }|
|
||||
fooba^r |
|
||||
{3:[No Name] [+] }|
|
||||
|
|
||||
]],
|
||||
})
|
||||
screen:expect([[
|
||||
cmdline |
|
||||
{2:cmdline [+] }|
|
||||
fooba^r |
|
||||
{3:[No Name] [+] }|
|
||||
|
|
||||
]])
|
||||
-- Does not clear 'incsearch' highlighting
|
||||
feed('<Esc>/foo')
|
||||
screen:expect({
|
||||
grid = [[
|
||||
foo |
|
||||
{2:cmdline [+] }|
|
||||
{2:foo}ba^r |
|
||||
{3:[No Name] [+] }|
|
||||
|
|
||||
]],
|
||||
})
|
||||
screen:expect([[
|
||||
foo |
|
||||
{2:cmdline [+] }|
|
||||
{2:foo}ba^r |
|
||||
{3:[No Name] [+] }|
|
||||
|
|
||||
]])
|
||||
-- Shows new cmdline state during 'inccommand'
|
||||
feed('<Esc>:%s/bar/baz')
|
||||
screen:expect({
|
||||
grid = [[
|
||||
%s/bar/baz |
|
||||
{2:cmdline [+] }|
|
||||
foo{10:ba^z} |
|
||||
{3:[No Name] [+] }|
|
||||
|
|
||||
]],
|
||||
})
|
||||
screen:expect([[
|
||||
%s/bar/baz |
|
||||
{2:cmdline [+] }|
|
||||
foo{10:ba^z} |
|
||||
{3:[No Name] [+] }|
|
||||
|
|
||||
]])
|
||||
end)
|
||||
|
||||
it('msg_show in fast context', function()
|
||||
@ -314,10 +287,9 @@ describe('vim.ui_attach', function()
|
||||
lled in a fast event context |
|
||||
{1:~ }|
|
||||
]],
|
||||
cmdline = { { abort = false } },
|
||||
messages = {
|
||||
{
|
||||
content = { { 'E122: Function Foo already exists, add ! to replace it', 9, 6 } },
|
||||
content = { { 'E122: Function Foo already exists, add ! to replace it', 9, 'ErrorMsg' } },
|
||||
history = true,
|
||||
kind = 'emsg',
|
||||
},
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -81,7 +81,8 @@ end
|
||||
--- @field cmdline table<integer,table>
|
||||
--- @field cmdline_hide_level integer?
|
||||
--- @field cmdline_block table[]
|
||||
--- @field hl_groups table<string,integer>
|
||||
--- @field hl_groups table<string,integer> Highlight group to attr ID map
|
||||
--- @field hl_names table<integer,string> Highlight ID to group map
|
||||
--- @field messages table<integer,table>
|
||||
--- @field private _cursor {grid:integer,row:integer,col:integer}
|
||||
--- @field private _grids table<integer,test.functional.ui.screen.Grid>
|
||||
@ -154,6 +155,11 @@ local function _init_colors()
|
||||
[29] = { foreground = Screen.colors.SlateBlue, bold = true },
|
||||
[30] = { background = Screen.colors.Red },
|
||||
}
|
||||
|
||||
Screen._global_hl_names = {}
|
||||
for group in pairs(n.api.nvim_get_hl(0, {})) do
|
||||
Screen._global_hl_names[n.api.nvim_get_hl_id_by_name(group)] = group
|
||||
end
|
||||
end
|
||||
|
||||
--- @class test.functional.ui.screen.Opts
|
||||
@ -210,6 +216,7 @@ function Screen.new(width, height, options, session)
|
||||
showcmd = {},
|
||||
ruler = {},
|
||||
hl_groups = {},
|
||||
hl_names = vim.deepcopy(Screen._global_hl_names),
|
||||
_default_attr_ids = nil,
|
||||
mouse_enabled = true,
|
||||
_attrs = {},
|
||||
@ -1343,12 +1350,12 @@ function Screen:_handle_cmdline_show(content, pos, firstc, prompt, indent, level
|
||||
firstc = firstc,
|
||||
prompt = prompt,
|
||||
indent = indent,
|
||||
hl_id = prompt and hl_id,
|
||||
hl = hl_id,
|
||||
}
|
||||
end
|
||||
|
||||
function Screen:_handle_cmdline_hide(level, abort)
|
||||
self.cmdline[level] = { abort = abort }
|
||||
self.cmdline[level] = abort and { abort = abort } or nil
|
||||
self.cmdline_hide_level = level
|
||||
end
|
||||
|
||||
@ -1485,6 +1492,13 @@ function Screen:_row_repr(gridnr, rownr, attr_state, cursor)
|
||||
return table.concat(rv, '') --:gsub('%s+$', '')
|
||||
end
|
||||
|
||||
local function hl_id_to_name(self, id)
|
||||
if id and id > 0 and not self.hl_names[id] then
|
||||
self.hl_names[id] = n.fn.synIDattr(id, 'name')
|
||||
end
|
||||
return id and self.hl_names[id] or nil
|
||||
end
|
||||
|
||||
function Screen:_extstate_repr(attr_state)
|
||||
local cmdline = {}
|
||||
for i, entry in pairs(self.cmdline) do
|
||||
@ -1492,6 +1506,7 @@ function Screen:_extstate_repr(attr_state)
|
||||
if entry.content ~= nil then
|
||||
entry.content = self:_chunks_repr(entry.content, attr_state)
|
||||
end
|
||||
entry.hl = hl_id_to_name(self, entry.hl)
|
||||
cmdline[i] = entry
|
||||
end
|
||||
|
||||
@ -1552,7 +1567,8 @@ function Screen:_chunks_repr(chunks, attr_state)
|
||||
attrs = hl
|
||||
end
|
||||
local attr_id = self:_get_attr_id(attr_state, attrs, hl)
|
||||
repr_chunks[i] = { text, attr_id, attr_id and id or nil }
|
||||
repr_chunks[i] = { text, attr_id }
|
||||
repr_chunks[i][#repr_chunks[i] + 1] = hl_id_to_name(self, id)
|
||||
end
|
||||
return repr_chunks
|
||||
end
|
||||
|
Reference in New Issue
Block a user