aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/api/vim.c6
-rw-r--r--src/nvim/highlight.c38
-rw-r--r--test/functional/api/highlight_spec.lua95
3 files changed, 136 insertions, 3 deletions
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index c363c77afb..e0eebd079f 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -221,6 +221,12 @@ Dictionary nvim__get_hl_defs(Integer ns_id, Error *err)
/// in addition the following keys are also recognized:
/// `default`: don't override existing definition,
/// like `hi default`
+/// `ctermfg`: sets foreground of cterm color
+/// `ctermbg`: sets background of cterm color
+/// `cterm` : cterm attribute map. sets attributed for
+/// cterm colors. similer to `hi cterm`
+/// Note: by default cterm attributes are
+/// same as attributes of gui color
/// @param[out] err Error details, if any
///
/// TODO: ns_id = 0, should modify :highlight namespace
diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c
index 79801262cb..79e474fa2e 100644
--- a/src/nvim/highlight.c
+++ b/src/nvim/highlight.c
@@ -806,8 +806,11 @@ HlAttrs dict2hlattrs(Dictionary dict, bool use_rgb, int *link_id, Error *err)
{
HlAttrs hlattrs = HLATTRS_INIT;
- int32_t fg = -1, bg = -1, sp = -1;
+ int32_t fg = -1, bg = -1, ctermfg = -1, ctermbg = -1, sp = -1;
int16_t mask = 0;
+ int16_t cterm_mask = 0;
+ bool cterm_mask_provided = false;
+
for (size_t i = 0; i < dict.size; i++) {
char *key = dict.items[i].key.data;
Object val = dict.items[i].value;
@@ -837,6 +840,25 @@ HlAttrs dict2hlattrs(Dictionary dict, bool use_rgb, int *link_id, Error *err)
}
}
+ // Handle cterm attrs
+ if (strequal(key, "cterm") && val.type == kObjectTypeDictionary) {
+ cterm_mask_provided = true;
+ Dictionary cterm_dict = val.data.dictionary;
+ for (size_t l = 0; l < cterm_dict.size; l++) {
+ char *cterm_dict_key = cterm_dict.items[l].key.data;
+ Object cterm_dict_val = cterm_dict.items[l].value;
+ for (int m = 0; flags[m].name; m++) {
+ if (strequal(flags[m].name, cterm_dict_key)) {
+ if (api_object_to_bool(cterm_dict_val, cterm_dict_key, false,
+ err)) {
+ cterm_mask |= flags[m].flag;
+ }
+ break;
+ }
+ }
+ }
+ }
+
struct {
const char *name;
const char *shortname;
@@ -844,6 +866,8 @@ HlAttrs dict2hlattrs(Dictionary dict, bool use_rgb, int *link_id, Error *err)
} colors[] = {
{ "foreground", "fg", &fg },
{ "background", "bg", &bg },
+ { "ctermfg", NULL, &ctermfg },
+ { "ctermbg", NULL, &ctermbg },
{ "special", "sp", &sp },
{ NULL, NULL, NULL },
};
@@ -867,7 +891,6 @@ HlAttrs dict2hlattrs(Dictionary dict, bool use_rgb, int *link_id, Error *err)
}
}
-
if (flags[j].name || colors[k].name) {
// handled above
} else if (link_id && strequal(key, "link")) {
@@ -888,13 +911,22 @@ HlAttrs dict2hlattrs(Dictionary dict, bool use_rgb, int *link_id, Error *err)
}
}
+ // apply gui mask as default for cterm mask
+ if (!cterm_mask_provided) {
+ cterm_mask = mask;
+ }
if (use_rgb) {
hlattrs.rgb_ae_attr = mask;
hlattrs.rgb_bg_color = bg;
hlattrs.rgb_fg_color = fg;
hlattrs.rgb_sp_color = sp;
+ hlattrs.cterm_bg_color =
+ ctermbg == -1 ? cterm_normal_bg_color : ctermbg + 1;
+ hlattrs.cterm_fg_color =
+ ctermfg == -1 ? cterm_normal_fg_color : ctermfg + 1;
+ hlattrs.cterm_ae_attr = cterm_mask;
} else {
- hlattrs.cterm_ae_attr = mask;
+ hlattrs.cterm_ae_attr = cterm_mask;
hlattrs.cterm_bg_color = bg == -1 ? cterm_normal_bg_color : bg + 1;
hlattrs.cterm_fg_color = fg == -1 ? cterm_normal_fg_color : fg + 1;
}
diff --git a/test/functional/api/highlight_spec.lua b/test/functional/api/highlight_spec.lua
index 058706718a..21e3094f8e 100644
--- a/test/functional/api/highlight_spec.lua
+++ b/test/functional/api/highlight_spec.lua
@@ -158,3 +158,98 @@ describe('API: highlight',function()
assert_alive()
end)
end)
+
+describe("API: set highlight", function()
+ local highlight_color = {
+ fg = tonumber('0xff0000'),
+ bg = tonumber('0x0032aa'),
+ ctermfg = 8,
+ ctermbg = 15,
+ }
+ local highlight1 = {
+ background = highlight_color.bg,
+ foreground = highlight_color.fg,
+ bold = true,
+ italic = true,
+ }
+ local highlight2_config = {
+ ctermbg = highlight_color.ctermbg,
+ ctermfg = highlight_color.ctermfg,
+ underline = true,
+ reverse = true,
+ }
+ local highlight2_result = {
+ background = highlight_color.ctermbg,
+ foreground = highlight_color.ctermfg,
+ underline = true,
+ reverse = true,
+ }
+ local highlight3_config = {
+ background = highlight_color.bg,
+ foreground = highlight_color.fg,
+ ctermbg = highlight_color.ctermbg,
+ ctermfg = highlight_color.ctermfg,
+ bold = true,
+ italic = true,
+ reverse = true,
+ undercurl = true,
+ underline = true,
+ cterm = {
+ italic = true,
+ reverse = true,
+ undercurl = true,
+ }
+ }
+ local highlight3_result_gui = {
+ background = highlight_color.bg,
+ foreground = highlight_color.fg,
+ bold = true,
+ italic = true,
+ reverse = true,
+ undercurl = true,
+ underline = true,
+ }
+ local highlight3_result_cterm = {
+ background = highlight_color.ctermbg,
+ foreground = highlight_color.ctermfg,
+ italic = true,
+ reverse = true,
+ undercurl = true,
+ }
+
+ local function get_ns()
+ local ns = meths.create_namespace('Test_set_hl')
+ meths._set_hl_ns(ns)
+ return ns
+ end
+
+ before_each(clear)
+
+ it ("can set gui highlight", function()
+ local ns = get_ns()
+ meths.set_hl(ns, 'Test_hl', highlight1)
+ eq(highlight1, meths.get_hl_by_name('Test_hl', true))
+ end)
+
+ it ("can set cterm highlight", function()
+ local ns = get_ns()
+ meths.set_hl(ns, 'Test_hl', highlight2_config)
+ eq(highlight2_result, meths.get_hl_by_name('Test_hl', false))
+ end)
+
+ it ("cterm attr defaults to gui attr", function()
+ local ns = get_ns()
+ meths.set_hl(ns, 'Test_hl', highlight1)
+ eq({
+ bold = true,
+ italic = true,
+ }, meths.get_hl_by_name('Test_hl', false))
+ end)
+
+ it ("can overwrite attr for cterm", function()
+ local ns = get_ns()
+ meths.set_hl(ns, 'Test_hl', highlight3_config)
+ eq(highlight3_result_gui, meths.get_hl_by_name('Test_hl', true))
+ eq(highlight3_result_cterm, meths.get_hl_by_name('Test_hl', false))
+ end)
+end)