diff options
Diffstat (limited to 'src/nvim/highlight.c')
| -rw-r--r-- | src/nvim/highlight.c | 110 |
1 files changed, 79 insertions, 31 deletions
diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c index 3ba02be32d..f11880cb2b 100644 --- a/src/nvim/highlight.c +++ b/src/nvim/highlight.c @@ -7,6 +7,7 @@ #include "nvim/highlight.h" #include "nvim/highlight_defs.h" #include "nvim/map.h" +#include "nvim/popupmnu.h" #include "nvim/screen.h" #include "nvim/syntax.h" #include "nvim/ui.h" @@ -105,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]); + } } } @@ -140,11 +146,23 @@ int hl_get_ui_attr(int idx, int final_id, bool optional) HlAttrs attrs = HLATTRS_INIT; bool available = false; - int syn_attr = syn_id2attr(final_id); - if (syn_attr != 0) { - attrs = syn_attr2entry(syn_attr); - available = true; + if (final_id > 0) { + int syn_attr = syn_id2attr(final_id); + if (syn_attr != 0) { + attrs = syn_attr2entry(syn_attr); + available = true; + } + } + + if (HLF_PNI <= idx && idx <= HLF_PST) { + if (attrs.hl_blend == -1 && p_pb > 0) { + attrs.hl_blend = (int)p_pb; + } + if (pum_drawn()) { + must_redraw_pum = true; + } } + if (optional && !available) { return 0; } @@ -159,28 +177,42 @@ void update_window_hl(win_T *wp, bool invalid) } wp->w_hl_needs_update = false; + // If a floating window is blending it always have a named + // wp->w_hl_attr_normal group. HL_ATTR(HLF_NFLOAT) is always named. + bool has_blend = wp->w_floating && wp->w_p_winbl != 0; + // determine window specific background set in 'winhighlight' bool float_win = wp->w_floating && !wp->w_float_config.external; - if (wp != curwin && wp->w_hl_ids[HLF_INACTIVE] > 0) { + if (wp != curwin && wp->w_hl_ids[HLF_INACTIVE] != 0) { wp->w_hl_attr_normal = hl_get_ui_attr(HLF_INACTIVE, - wp->w_hl_ids[HLF_INACTIVE], true); - } else if (float_win && wp->w_hl_ids[HLF_NFLOAT] > 0) { + wp->w_hl_ids[HLF_INACTIVE], + !has_blend); + } else if (float_win && wp->w_hl_ids[HLF_NFLOAT] != 0) { wp->w_hl_attr_normal = hl_get_ui_attr(HLF_NFLOAT, - wp->w_hl_ids[HLF_NFLOAT], true); - } else if (wp->w_hl_id_normal > 0) { - wp->w_hl_attr_normal = hl_get_ui_attr(-1, wp->w_hl_id_normal, true); + wp->w_hl_ids[HLF_NFLOAT], !has_blend); + } else if (wp->w_hl_id_normal != 0) { + wp->w_hl_attr_normal = hl_get_ui_attr(-1, wp->w_hl_id_normal, !has_blend); } else { wp->w_hl_attr_normal = float_win ? HL_ATTR(HLF_NFLOAT) : 0; } - if (wp != curwin) { + // if blend= attribute is not set, 'winblend' value overrides it. + if (wp->w_floating && wp->w_p_winbl > 0) { + HlEntry entry = kv_A(attr_entries, wp->w_hl_attr_normal); + if (entry.attr.hl_blend == -1) { + entry.attr.hl_blend = (int)wp->w_p_winbl; + wp->w_hl_attr_normal = get_attr_entry(entry); + } + } + + if (wp != curwin && wp->w_hl_ids[HLF_INACTIVE] == 0) { wp->w_hl_attr_normal = hl_combine_attr(HL_ATTR(HLF_INACTIVE), wp->w_hl_attr_normal); } for (int hlf = 0; hlf < (int)HLF_COUNT; hlf++) { int attr; - if (wp->w_hl_ids[hlf] > 0) { + if (wp->w_hl_ids[hlf] != 0) { attr = hl_get_ui_attr(hlf, wp->w_hl_ids[hlf], false); } else { attr = HL_ATTR(hlf); @@ -224,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(); @@ -240,6 +273,8 @@ void hl_invalidate_blends(void) { map_clear(int, int)(blend_attr_entries); map_clear(int, int)(blendthrough_attr_entries); + highlight_changed(); + update_window_hl(curwin, true); } // Combine special attributes (e.g., for spelling) with other attributes @@ -292,6 +327,10 @@ int hl_combine_attr(int char_attr, int prim_attr) new_en.rgb_sp_color = spell_aep.rgb_sp_color; } + if (spell_aep.hl_blend >= 0) { + new_en.hl_blend = spell_aep.hl_blend; + } + id = get_attr_entry((HlEntry){ .attr = new_en, .kind = kHlCombine, .id1 = char_attr, .id2 = prim_attr }); if (id > 0) { @@ -336,50 +375,59 @@ static HlAttrs get_colors_force(int attr) /// This is called per-cell, so cache the result. /// /// @return the resulting attributes. -int hl_blend_attrs(int back_attr, int front_attr, bool through) +int hl_blend_attrs(int back_attr, int front_attr, bool *through) { + HlAttrs fattrs = get_colors_force(front_attr); + int ratio = fattrs.hl_blend; + if (ratio <= 0) { + *through = false; + return front_attr; + } + int combine_tag = (back_attr << 16) + front_attr; - Map(int, int) *map = through ? blendthrough_attr_entries : blend_attr_entries; + Map(int, int) *map = (*through + ? blendthrough_attr_entries + : blend_attr_entries); int id = map_get(int, int)(map, combine_tag); if (id > 0) { return id; } HlAttrs battrs = get_colors_force(back_attr); - HlAttrs fattrs = get_colors_force(front_attr); HlAttrs cattrs; - if (through) { + + if (*through) { cattrs = battrs; - cattrs.rgb_fg_color = rgb_blend((int)p_pb, battrs.rgb_fg_color, + cattrs.rgb_fg_color = rgb_blend(ratio, battrs.rgb_fg_color, fattrs.rgb_bg_color); if (cattrs.rgb_ae_attr & (HL_UNDERLINE|HL_UNDERCURL)) { - cattrs.rgb_sp_color = rgb_blend((int)p_pb, battrs.rgb_sp_color, + cattrs.rgb_sp_color = rgb_blend(ratio, battrs.rgb_sp_color, fattrs.rgb_bg_color); } else { cattrs.rgb_sp_color = -1; } cattrs.cterm_bg_color = fattrs.cterm_bg_color; - cattrs.cterm_fg_color = cterm_blend((int)p_pb, battrs.cterm_fg_color, + cattrs.cterm_fg_color = cterm_blend(ratio, battrs.cterm_fg_color, fattrs.cterm_bg_color); } else { cattrs = fattrs; - if (p_pb >= 50) { + if (ratio >= 50) { cattrs.rgb_ae_attr |= battrs.rgb_ae_attr; } - cattrs.rgb_fg_color = rgb_blend((int)p_pb/2, battrs.rgb_fg_color, + cattrs.rgb_fg_color = rgb_blend(ratio/2, battrs.rgb_fg_color, fattrs.rgb_fg_color); if (cattrs.rgb_ae_attr & (HL_UNDERLINE|HL_UNDERCURL)) { - cattrs.rgb_sp_color = rgb_blend((int)p_pb/2, battrs.rgb_bg_color, + cattrs.rgb_sp_color = rgb_blend(ratio/2, battrs.rgb_bg_color, fattrs.rgb_sp_color); } else { cattrs.rgb_sp_color = -1; } } - cattrs.rgb_bg_color = rgb_blend((int)p_pb, battrs.rgb_bg_color, + cattrs.rgb_bg_color = rgb_blend(ratio, battrs.rgb_bg_color, fattrs.rgb_bg_color); - HlKind kind = through ? kHlBlendThrough : kHlBlend; + HlKind kind = *through ? kHlBlendThrough : kHlBlend; id = get_attr_entry((HlEntry){ .attr = cattrs, .kind = kind, .id1 = back_attr, .id2 = front_attr }); if (id > 0) { |
