mirror of
https://github.com/neovim/neovim.git
synced 2024-09-17 20:58:20 -04:00
Merge pull request #10504 from bfredl/hl_def
highlight: expose builtin highlight groups using hl_group_set event
This commit is contained in:
commit
8a3f8589a3
@ -316,6 +316,14 @@ numerical highlight ids to the actual attributes.
|
||||
`info` is an empty array by default, and will be used by the
|
||||
|ui-hlstate| extension explained below.
|
||||
|
||||
["hl_group_set", name, hl_id]
|
||||
The bulitin highlight group `name` was set to use the attributes `hl_id`
|
||||
defined by a previous `hl_attr_define` call. This event is not needed
|
||||
to render the grids which use attribute ids directly, but is useful
|
||||
for an UI who want to render its own elements with consistent
|
||||
highlighting. For instance an UI using |ui-popupmenu| events, might
|
||||
use the |hl-Pmenu| family of builtin highlights.
|
||||
|
||||
*ui-event-grid_line*
|
||||
["grid_line", grid, row, col_start, cells]
|
||||
Redraw a continuous part of a `row` on a `grid`, starting at the column
|
||||
|
@ -123,6 +123,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height,
|
||||
ui->mode_change = remote_ui_mode_change;
|
||||
ui->grid_scroll = remote_ui_grid_scroll;
|
||||
ui->hl_attr_define = remote_ui_hl_attr_define;
|
||||
ui->hl_group_set = remote_ui_hl_group_set;
|
||||
ui->raw_line = remote_ui_raw_line;
|
||||
ui->bell = remote_ui_bell;
|
||||
ui->visual_bell = remote_ui_visual_bell;
|
||||
|
@ -73,6 +73,8 @@ void default_colors_set(Integer rgb_fg, Integer rgb_bg, Integer rgb_sp,
|
||||
void hl_attr_define(Integer id, HlAttrs rgb_attrs, HlAttrs cterm_attrs,
|
||||
Array info)
|
||||
FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL FUNC_API_BRIDGE_IMPL;
|
||||
void hl_group_set(String name, Integer id)
|
||||
FUNC_API_SINCE(6) FUNC_API_BRIDGE_IMPL;
|
||||
void grid_resize(Integer grid, Integer width, Integer height)
|
||||
FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL FUNC_API_COMPOSITOR_IMPL;
|
||||
void grid_clear(Integer grid)
|
||||
|
@ -106,14 +106,19 @@ static int get_attr_entry(HlEntry entry)
|
||||
/// When a UI connects, we need to send it the table of highlights used so far.
|
||||
void ui_send_all_hls(UI *ui)
|
||||
{
|
||||
if (!ui->hl_attr_define) {
|
||||
return;
|
||||
if (ui->hl_attr_define) {
|
||||
for (size_t i = 1; i < kv_size(attr_entries); i++) {
|
||||
Array inspect = hl_inspect((int)i);
|
||||
ui->hl_attr_define(ui, (Integer)i, kv_A(attr_entries, i).attr,
|
||||
kv_A(attr_entries, i).attr, inspect);
|
||||
api_free_array(inspect);
|
||||
}
|
||||
}
|
||||
for (size_t i = 1; i < kv_size(attr_entries); i++) {
|
||||
Array inspect = hl_inspect((int)i);
|
||||
ui->hl_attr_define(ui, (Integer)i, kv_A(attr_entries, i).attr,
|
||||
kv_A(attr_entries, i).attr, inspect);
|
||||
api_free_array(inspect);
|
||||
if (ui->hl_group_set) {
|
||||
for (size_t hlf = 0; hlf < HLF_COUNT; hlf++) {
|
||||
ui->hl_group_set(ui, cstr_as_string((char *)hlf_names[hlf]),
|
||||
highlight_attr[hlf]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -251,6 +256,7 @@ void clear_hl_tables(bool reinit)
|
||||
map_clear(int, int)(combine_attr_entries);
|
||||
map_clear(int, int)(blend_attr_entries);
|
||||
map_clear(int, int)(blendthrough_attr_entries);
|
||||
memset(highlight_attr_last, -1, sizeof(highlight_attr_last));
|
||||
highlight_attr_set_all();
|
||||
highlight_changed();
|
||||
screen_invalidate_highlights();
|
||||
|
@ -150,6 +150,7 @@ EXTERN const char *hlf_names[] INIT(= {
|
||||
|
||||
|
||||
EXTERN int highlight_attr[HLF_COUNT]; // Highl. attr for each context.
|
||||
EXTERN int highlight_attr_last[HLF_COUNT]; // copy for detecting changed groups
|
||||
EXTERN int highlight_user[9]; // User[1-9] attributes
|
||||
EXTERN int highlight_stlnc[9]; // On top of user
|
||||
EXTERN int cterm_normal_fg_color INIT(= 0);
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "nvim/vim.h"
|
||||
#include "nvim/ascii.h"
|
||||
#include "nvim/api/private/helpers.h"
|
||||
#include "nvim/syntax.h"
|
||||
#include "nvim/charset.h"
|
||||
#include "nvim/cursor_shape.h"
|
||||
@ -7504,6 +7505,12 @@ void highlight_changed(void)
|
||||
|
||||
highlight_attr[hlf] = hl_get_ui_attr(hlf, final_id,
|
||||
hlf == (int)HLF_INACTIVE);
|
||||
|
||||
if (highlight_attr[hlf] != highlight_attr_last[hlf]) {
|
||||
ui_call_hl_group_set(cstr_as_string((char *)hlf_names[hlf]),
|
||||
highlight_attr[hlf]);
|
||||
highlight_attr_last[hlf] = highlight_attr[hlf];
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup the user highlights
|
||||
|
@ -311,6 +311,38 @@ describe('highlight defaults', function()
|
||||
[1] = {foreground=Screen.colors.Blue},
|
||||
})
|
||||
end)
|
||||
|
||||
it('are sent to UIs', function()
|
||||
screen:try_resize(53, 4)
|
||||
screen:set_default_attr_ids({
|
||||
[0] = {},
|
||||
[1] = {bold = true, foreground = Screen.colors.Blue1},
|
||||
[2] = {bold = true, reverse = true},
|
||||
[3] = {italic=true}
|
||||
})
|
||||
screen:expect{grid=[[
|
||||
^ |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
|
|
||||
]], hl_groups={EndOfBuffer=1, MsgSeparator=2}}
|
||||
|
||||
command('highlight EndOfBuffer gui=italic')
|
||||
screen:expect{grid=[[
|
||||
^ |
|
||||
{3:~ }|
|
||||
{3:~ }|
|
||||
|
|
||||
]], hl_groups={EndOfBuffer=3, MsgSeparator=2}}
|
||||
|
||||
command('highlight clear EndOfBuffer')
|
||||
screen:expect{grid=[[
|
||||
^ |
|
||||
~ |
|
||||
~ |
|
||||
|
|
||||
]], hl_groups={EndOfBuffer=0, MsgSeparator=2}}
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('highlight', function()
|
||||
|
@ -165,6 +165,7 @@ function Screen.new(width, height)
|
||||
showmode = {},
|
||||
showcmd = {},
|
||||
ruler = {},
|
||||
hl_groups = {},
|
||||
_default_attr_ids = nil,
|
||||
_default_attr_ignore = nil,
|
||||
_mouse_enabled = true,
|
||||
@ -322,7 +323,7 @@ function Screen:expect(expected, attr_ids, attr_ignore)
|
||||
assert(not (attr_ids ~= nil or attr_ignore ~= nil))
|
||||
local is_key = {grid=true, attr_ids=true, attr_ignore=true, condition=true,
|
||||
any=true, mode=true, unchanged=true, intermediate=true,
|
||||
reset=true, timeout=true, request_cb=true}
|
||||
reset=true, timeout=true, request_cb=true, hl_groups=true}
|
||||
for _, v in ipairs(ext_keys) do
|
||||
is_key[v] = true
|
||||
end
|
||||
@ -418,9 +419,10 @@ screen:redraw_debug() to show all intermediate screen states. ]])
|
||||
-- (e.g. no external cmdline visible). Some extensions require
|
||||
-- preprocessing to represent highlights in a reproducible way.
|
||||
local extstate = self:_extstate_repr(attr_state)
|
||||
if expected['mode'] ~= nil then
|
||||
extstate['mode'] = self.mode
|
||||
if expected.mode ~= nil then
|
||||
extstate.mode = self.mode
|
||||
end
|
||||
|
||||
-- Convert assertion errors into invalid screen state descriptions.
|
||||
for _, k in ipairs(concat_tables(ext_keys, {'mode'})) do
|
||||
-- Empty states are considered the default and need not be mentioned.
|
||||
@ -431,6 +433,17 @@ screen:redraw_debug() to show all intermediate screen states. ]])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if expected.hl_groups ~= nil then
|
||||
for name, id in pairs(expected.hl_groups) do
|
||||
local expected_hl = attr_state.ids[id]
|
||||
local actual_hl = self._attr_table[self.hl_groups[name]][(self._options.rgb and 1) or 2]
|
||||
local status, res = pcall(eq, expected_hl, actual_hl, "highlight "..name)
|
||||
if not status then
|
||||
return tostring(res)
|
||||
end
|
||||
end
|
||||
end
|
||||
end, expected)
|
||||
end
|
||||
|
||||
@ -836,6 +849,10 @@ function Screen:_handle_hl_attr_define(id, rgb_attrs, cterm_attrs, info)
|
||||
self._new_attrs = true
|
||||
end
|
||||
|
||||
function Screen:_handle_hl_group_set(name, id)
|
||||
self.hl_groups[name] = id
|
||||
end
|
||||
|
||||
function Screen:get_hl(val)
|
||||
if self._options.ext_newgrid then
|
||||
return self._attr_table[val][1]
|
||||
@ -1411,17 +1428,17 @@ function Screen:_get_attr_id(attr_state, attrs, hl_id)
|
||||
end
|
||||
return "UNEXPECTED "..self:_pprint_attrs(self._attr_table[hl_id][1])
|
||||
else
|
||||
for id, a in pairs(attr_state.ids) do
|
||||
if self:_equal_attrs(a, attrs) then
|
||||
return id
|
||||
end
|
||||
end
|
||||
if self:_equal_attrs(attrs, {}) or
|
||||
attr_state.ignore == true or
|
||||
self:_attr_index(attr_state.ignore, attrs) ~= nil then
|
||||
-- ignore this attrs
|
||||
return nil
|
||||
end
|
||||
for id, a in pairs(attr_state.ids) do
|
||||
if self:_equal_attrs(a, attrs) then
|
||||
return id
|
||||
end
|
||||
end
|
||||
if attr_state.mutable then
|
||||
table.insert(attr_state.ids, attrs)
|
||||
attr_state.modified = true
|
||||
|
Loading…
Reference in New Issue
Block a user