mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06: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
|
`info` is an empty array by default, and will be used by the
|
||||||
|ui-hlstate| extension explained below.
|
|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*
|
*ui-event-grid_line*
|
||||||
["grid_line", grid, row, col_start, cells]
|
["grid_line", grid, row, col_start, cells]
|
||||||
Redraw a continuous part of a `row` on a `grid`, starting at the column
|
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->mode_change = remote_ui_mode_change;
|
||||||
ui->grid_scroll = remote_ui_grid_scroll;
|
ui->grid_scroll = remote_ui_grid_scroll;
|
||||||
ui->hl_attr_define = remote_ui_hl_attr_define;
|
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->raw_line = remote_ui_raw_line;
|
||||||
ui->bell = remote_ui_bell;
|
ui->bell = remote_ui_bell;
|
||||||
ui->visual_bell = remote_ui_visual_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,
|
void hl_attr_define(Integer id, HlAttrs rgb_attrs, HlAttrs cterm_attrs,
|
||||||
Array info)
|
Array info)
|
||||||
FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL FUNC_API_BRIDGE_IMPL;
|
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)
|
void grid_resize(Integer grid, Integer width, Integer height)
|
||||||
FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL FUNC_API_COMPOSITOR_IMPL;
|
FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL FUNC_API_COMPOSITOR_IMPL;
|
||||||
void grid_clear(Integer grid)
|
void grid_clear(Integer grid)
|
||||||
|
@ -106,15 +106,20 @@ static int get_attr_entry(HlEntry entry)
|
|||||||
/// When a UI connects, we need to send it the table of highlights used so far.
|
/// When a UI connects, we need to send it the table of highlights used so far.
|
||||||
void ui_send_all_hls(UI *ui)
|
void ui_send_all_hls(UI *ui)
|
||||||
{
|
{
|
||||||
if (!ui->hl_attr_define) {
|
if (ui->hl_attr_define) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (size_t i = 1; i < kv_size(attr_entries); i++) {
|
for (size_t i = 1; i < kv_size(attr_entries); i++) {
|
||||||
Array inspect = hl_inspect((int)i);
|
Array inspect = hl_inspect((int)i);
|
||||||
ui->hl_attr_define(ui, (Integer)i, kv_A(attr_entries, i).attr,
|
ui->hl_attr_define(ui, (Integer)i, kv_A(attr_entries, i).attr,
|
||||||
kv_A(attr_entries, i).attr, inspect);
|
kv_A(attr_entries, i).attr, inspect);
|
||||||
api_free_array(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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get attribute code for a syntax group.
|
/// Get attribute code for a syntax group.
|
||||||
@ -251,6 +256,7 @@ void clear_hl_tables(bool reinit)
|
|||||||
map_clear(int, int)(combine_attr_entries);
|
map_clear(int, int)(combine_attr_entries);
|
||||||
map_clear(int, int)(blend_attr_entries);
|
map_clear(int, int)(blend_attr_entries);
|
||||||
map_clear(int, int)(blendthrough_attr_entries);
|
map_clear(int, int)(blendthrough_attr_entries);
|
||||||
|
memset(highlight_attr_last, -1, sizeof(highlight_attr_last));
|
||||||
highlight_attr_set_all();
|
highlight_attr_set_all();
|
||||||
highlight_changed();
|
highlight_changed();
|
||||||
screen_invalidate_highlights();
|
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[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_user[9]; // User[1-9] attributes
|
||||||
EXTERN int highlight_stlnc[9]; // On top of user
|
EXTERN int highlight_stlnc[9]; // On top of user
|
||||||
EXTERN int cterm_normal_fg_color INIT(= 0);
|
EXTERN int cterm_normal_fg_color INIT(= 0);
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include "nvim/vim.h"
|
#include "nvim/vim.h"
|
||||||
#include "nvim/ascii.h"
|
#include "nvim/ascii.h"
|
||||||
|
#include "nvim/api/private/helpers.h"
|
||||||
#include "nvim/syntax.h"
|
#include "nvim/syntax.h"
|
||||||
#include "nvim/charset.h"
|
#include "nvim/charset.h"
|
||||||
#include "nvim/cursor_shape.h"
|
#include "nvim/cursor_shape.h"
|
||||||
@ -7504,6 +7505,12 @@ void highlight_changed(void)
|
|||||||
|
|
||||||
highlight_attr[hlf] = hl_get_ui_attr(hlf, final_id,
|
highlight_attr[hlf] = hl_get_ui_attr(hlf, final_id,
|
||||||
hlf == (int)HLF_INACTIVE);
|
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
|
/* Setup the user highlights
|
||||||
|
@ -311,6 +311,38 @@ describe('highlight defaults', function()
|
|||||||
[1] = {foreground=Screen.colors.Blue},
|
[1] = {foreground=Screen.colors.Blue},
|
||||||
})
|
})
|
||||||
end)
|
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)
|
end)
|
||||||
|
|
||||||
describe('highlight', function()
|
describe('highlight', function()
|
||||||
|
@ -165,6 +165,7 @@ function Screen.new(width, height)
|
|||||||
showmode = {},
|
showmode = {},
|
||||||
showcmd = {},
|
showcmd = {},
|
||||||
ruler = {},
|
ruler = {},
|
||||||
|
hl_groups = {},
|
||||||
_default_attr_ids = nil,
|
_default_attr_ids = nil,
|
||||||
_default_attr_ignore = nil,
|
_default_attr_ignore = nil,
|
||||||
_mouse_enabled = true,
|
_mouse_enabled = true,
|
||||||
@ -322,7 +323,7 @@ function Screen:expect(expected, attr_ids, attr_ignore)
|
|||||||
assert(not (attr_ids ~= nil or attr_ignore ~= nil))
|
assert(not (attr_ids ~= nil or attr_ignore ~= nil))
|
||||||
local is_key = {grid=true, attr_ids=true, attr_ignore=true, condition=true,
|
local is_key = {grid=true, attr_ids=true, attr_ignore=true, condition=true,
|
||||||
any=true, mode=true, unchanged=true, intermediate=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
|
for _, v in ipairs(ext_keys) do
|
||||||
is_key[v] = true
|
is_key[v] = true
|
||||||
end
|
end
|
||||||
@ -418,9 +419,10 @@ screen:redraw_debug() to show all intermediate screen states. ]])
|
|||||||
-- (e.g. no external cmdline visible). Some extensions require
|
-- (e.g. no external cmdline visible). Some extensions require
|
||||||
-- preprocessing to represent highlights in a reproducible way.
|
-- preprocessing to represent highlights in a reproducible way.
|
||||||
local extstate = self:_extstate_repr(attr_state)
|
local extstate = self:_extstate_repr(attr_state)
|
||||||
if expected['mode'] ~= nil then
|
if expected.mode ~= nil then
|
||||||
extstate['mode'] = self.mode
|
extstate.mode = self.mode
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Convert assertion errors into invalid screen state descriptions.
|
-- Convert assertion errors into invalid screen state descriptions.
|
||||||
for _, k in ipairs(concat_tables(ext_keys, {'mode'})) do
|
for _, k in ipairs(concat_tables(ext_keys, {'mode'})) do
|
||||||
-- Empty states are considered the default and need not be mentioned.
|
-- 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
|
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, expected)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -836,6 +849,10 @@ function Screen:_handle_hl_attr_define(id, rgb_attrs, cterm_attrs, info)
|
|||||||
self._new_attrs = true
|
self._new_attrs = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Screen:_handle_hl_group_set(name, id)
|
||||||
|
self.hl_groups[name] = id
|
||||||
|
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]
|
||||||
@ -1411,17 +1428,17 @@ function Screen:_get_attr_id(attr_state, attrs, hl_id)
|
|||||||
end
|
end
|
||||||
return "UNEXPECTED "..self:_pprint_attrs(self._attr_table[hl_id][1])
|
return "UNEXPECTED "..self:_pprint_attrs(self._attr_table[hl_id][1])
|
||||||
else
|
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
|
if self:_equal_attrs(attrs, {}) or
|
||||||
attr_state.ignore == true or
|
attr_state.ignore == true or
|
||||||
self:_attr_index(attr_state.ignore, attrs) ~= nil then
|
self:_attr_index(attr_state.ignore, attrs) ~= nil then
|
||||||
-- ignore this attrs
|
-- ignore this attrs
|
||||||
return nil
|
return nil
|
||||||
end
|
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
|
if attr_state.mutable then
|
||||||
table.insert(attr_state.ids, attrs)
|
table.insert(attr_state.ids, attrs)
|
||||||
attr_state.modified = true
|
attr_state.modified = true
|
||||||
|
Loading…
Reference in New Issue
Block a user