Merge pull request #10504 from bfredl/hl_def

highlight: expose builtin highlight groups using hl_group_set event
This commit is contained in:
Björn Linse 2019-07-16 10:17:29 +02:00 committed by GitHub
commit 8a3f8589a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 89 additions and 15 deletions

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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();

View File

@ -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);

View File

@ -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

View File

@ -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()

View File

@ -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