diff options
author | Ville Hakulinen <ville.hakulinen@gmail.com> | 2020-07-11 01:05:06 +0300 |
---|---|---|
committer | Ville Hakulinen <ville.hakulinen@gmail.com> | 2020-07-11 01:05:06 +0300 |
commit | a467850a3fe089e58112328d8cda44b22f98adbc (patch) | |
tree | 68ac356815308b2191451eccd265050a4f80247b | |
parent | 7492a385856b2d2e142d9cbd10a4dcaf0ccc16fa (diff) |
Use hl_group_set API event to get GUI colors
This way we dont need to relay on any autocmds to send us the colors
through viml.
Fix #39
Ref #128
-rw-r--r-- | runtime/plugin/gnvim.vim | 41 | ||||
-rw-r--r-- | src/nvim_bridge/mod.rs | 114 | ||||
-rw-r--r-- | src/nvim_bridge/tests.rs | 97 | ||||
-rw-r--r-- | src/ui/cmdline.rs | 86 | ||||
-rw-r--r-- | src/ui/color.rs | 30 | ||||
-rw-r--r-- | src/ui/popupmenu/popupmenu.rs | 37 | ||||
-rw-r--r-- | src/ui/state.rs | 56 | ||||
-rw-r--r-- | src/ui/tabline.rs | 56 | ||||
-rw-r--r-- | src/ui/ui.rs | 1 | ||||
-rw-r--r-- | src/ui/wildmenu.rs | 56 |
10 files changed, 251 insertions, 323 deletions
diff --git a/runtime/plugin/gnvim.vim b/runtime/plugin/gnvim.vim index a21c079..e39f204 100644 --- a/runtime/plugin/gnvim.vim +++ b/runtime/plugin/gnvim.vim @@ -4,45 +4,4 @@ endif let g:gnvim_runtime_loaded = 1 -function! gnvim#get_hl_term(group, term) - " Store output of group to variable - let output = execute('hi ' . a:group) - - " Find the term we're looking for - return matchstr(output, a:term.'=\zs\S*') -endfunction - -function! gnvim#set_gui_colors() - let colors = { - \ 'pmenu_bg': gnvim#get_hl_term('Pmenu', 'guibg'), - \ 'pmenu_fg': gnvim#get_hl_term('Pmenu', 'guifg'), - \ 'pmenusel_bg': gnvim#get_hl_term('PmenuSel', 'guibg'), - \ 'pmenusel_fg': gnvim#get_hl_term('PmenuSel', 'guifg'), - \ - \ 'tabline_fg': gnvim#get_hl_term('TabLine', 'guifg'), - \ 'tabline_bg': gnvim#get_hl_term('TabLine', 'guibg'), - \ 'tablinesel_fg': gnvim#get_hl_term('TabLineSel', 'guifg'), - \ 'tablinesel_bg': gnvim#get_hl_term('TabLineSel', 'guibg'), - \ 'tablinefill_fg': gnvim#get_hl_term('TabLineFill', 'guifg'), - \ 'tablinefill_bg': gnvim#get_hl_term('TabLineFill', 'guibg'), - \ - \ 'cmdline_fg': gnvim#get_hl_term('Normal', 'guifg'), - \ 'cmdline_bg': gnvim#get_hl_term('Normal', 'guibg'), - \ 'cmdline_border': gnvim#get_hl_term('TabLineSel', 'guibg'), - \ - \ 'wildmenu_bg': gnvim#get_hl_term('Pmenu', 'guibg'), - \ 'wildmenu_fg': gnvim#get_hl_term('Pmenu', 'guifg'), - \ 'wildmenusel_bg': gnvim#get_hl_term('PmenuSel', 'guibg'), - \ 'wildmenusel_fg': gnvim#get_hl_term('PmenuSel', 'guifg'), - \} - - call rpcnotify(g:gnvim_channel_id, 'Gnvim', 'SetGuiColors', colors) -endfunction - -augroup GnvimColors - autocmd! - autocmd ColorScheme * call gnvim#set_gui_colors() - autocmd VimEnter * call gnvim#set_gui_colors() -augroup END - inoremap <expr> <C-s> gnvim#popupmenu#toggle_details() diff --git a/src/nvim_bridge/mod.rs b/src/nvim_bridge/mod.rs index 08d9ead..32a61e1 100644 --- a/src/nvim_bridge/mod.rs +++ b/src/nvim_bridge/mod.rs @@ -67,13 +67,6 @@ macro_rules! try_u64 { }; } -macro_rules! try_map { - ($val:expr, $msg:expr) => { - $val.as_map() - .ok_or(format!("Value is not an map: {}", $msg))? - }; -} - impl Highlight { fn from_map_val(map: &Vec<(Value, Value)>) -> Self { let mut hl = Highlight::default(); @@ -569,6 +562,22 @@ impl From<Value> for HlAttrDefine { } #[derive(Debug, PartialEq)] +pub struct HlGroupSet { + pub name: String, + pub hl_id: u64, +} + +impl From<Value> for HlGroupSet { + fn from(args: Value) -> Self { + let args = unwrap_array!(args); + let name = unwrap_str!(args[0]).to_string(); + let hl_id = unwrap_u64!(args[1]); + + HlGroupSet { name, hl_id } + } +} + +#[derive(Debug, PartialEq)] pub struct ModeInfoSet { pub cursor_shape_enabled: bool, pub mode_info: Vec<ModeInfo>, @@ -748,6 +757,7 @@ pub enum RedrawEvent { DefaultColorsSet(Vec<DefaultColorsSet>), HlAttrDefine(Vec<HlAttrDefine>), + HlGroupSet(Vec<HlGroupSet>), OptionSet(Vec<OptionSet>), ModeInfoSet(Vec<ModeInfoSet>), ModeChange(Vec<ModeChange>), @@ -789,6 +799,7 @@ impl fmt::Display for RedrawEvent { write!(fmt, "DefaultColorsSet") } RedrawEvent::HlAttrDefine(..) => write!(fmt, "HlAttrDefine"), + RedrawEvent::HlGroupSet(..) => write!(fmt, "HlGroupSet"), RedrawEvent::OptionSet(..) => write!(fmt, "OptionSet"), RedrawEvent::ModeInfoSet(..) => write!(fmt, "ModeInfoSet"), RedrawEvent::ModeChange(..) => write!(fmt, "ModeChange"), @@ -824,7 +835,6 @@ impl fmt::Display for RedrawEvent { #[derive(Debug, PartialEq)] pub enum GnvimEvent { - SetGuiColors(SetGuiColors), CompletionMenuToggleInfo, CursorTooltipLoadStyle(String), @@ -839,47 +849,6 @@ pub enum GnvimEvent { Unknown(String), } -#[derive(Debug, Default, Clone, Copy, PartialEq)] -pub struct WildmenuColors { - pub bg: Option<Color>, - pub fg: Option<Color>, - pub sel_bg: Option<Color>, - pub sel_fg: Option<Color>, -} - -#[derive(Debug, Default, Clone, Copy, PartialEq)] -pub struct PmenuColors { - pub bg: Option<Color>, - pub fg: Option<Color>, - pub sel_bg: Option<Color>, - pub sel_fg: Option<Color>, -} - -#[derive(Debug, Default, Clone, Copy, PartialEq)] -pub struct TablineColors { - pub fg: Option<Color>, - pub bg: Option<Color>, - pub fill_fg: Option<Color>, - pub fill_bg: Option<Color>, - pub sel_bg: Option<Color>, - pub sel_fg: Option<Color>, -} - -#[derive(Debug, Default, Clone, Copy, PartialEq)] -pub struct CmdlineColors { - pub fg: Option<Color>, - pub bg: Option<Color>, - pub border: Option<Color>, -} - -#[derive(Debug, Default, PartialEq)] -pub struct SetGuiColors { - pub pmenu: PmenuColors, - pub tabline: TablineColors, - pub cmdline: CmdlineColors, - pub wildmenu: WildmenuColors, -} - pub enum Request { CursorTooltipStyles, } @@ -1042,6 +1011,9 @@ fn parse_single_redraw_event(cmd: &str, args: Vec<Value>) -> RedrawEvent { "hl_attr_define" => RedrawEvent::HlAttrDefine( args.into_iter().map(HlAttrDefine::from).collect(), ), + "hl_group_set" => RedrawEvent::HlGroupSet( + args.into_iter().map(HlGroupSet::from).collect(), + ), "option_set" => RedrawEvent::OptionSet( args.into_iter().map(OptionSet::from).collect(), ), @@ -1109,50 +1081,6 @@ pub(crate) fn parse_gnvim_event( ) -> Result<GnvimEvent, String> { let cmd = try_str!(args.get(0).ok_or("No command given")?, "cmd"); let res = match cmd { - "SetGuiColors" => { - let mut colors = SetGuiColors::default(); - - for e in try_map!( - args.get(1).ok_or("No data for SetGuiColors")?, - "colors" - ) { - let color = Color::from_hex_string(String::from(try_str!( - e.1, - "color hex value" - ))) - .ok(); - match try_str!(e.0, "color name") { - "pmenu_bg" => colors.pmenu.bg = color, - "pmenu_fg" => colors.pmenu.fg = color, - "pmenusel_bg" => colors.pmenu.sel_bg = color, - "pmenusel_fg" => colors.pmenu.sel_fg = color, - - "tabline_fg" => colors.tabline.fg = color, - "tabline_bg" => colors.tabline.bg = color, - "tablinefill_fg" => colors.tabline.fill_fg = color, - "tablinefill_bg" => colors.tabline.fill_bg = color, - "tablinesel_fg" => colors.tabline.sel_fg = color, - "tablinesel_bg" => colors.tabline.sel_bg = color, - - "cmdline_fg" => colors.cmdline.fg = color, - "cmdline_bg" => colors.cmdline.bg = color, - "cmdline_border" => colors.cmdline.border = color, - - "wildmenu_bg" => colors.wildmenu.bg = color, - "wildmenu_fg" => colors.wildmenu.fg = color, - "wildmenusel_bg" => colors.wildmenu.sel_bg = color, - "wildmenusel_fg" => colors.wildmenu.sel_fg = color, - _ => { - error!( - "Unknown SetGuiColor: {}", - try_str!(e.0, "color name") - ); - } - } - } - - GnvimEvent::SetGuiColors(colors) - } "CompletionMenuToggleInfo" => GnvimEvent::CompletionMenuToggleInfo, "CursorTooltipLoadStyle" => { let path = diff --git a/src/nvim_bridge/tests.rs b/src/nvim_bridge/tests.rs index 8a2d60c..b3f6fe5 100644 --- a/src/nvim_bridge/tests.rs +++ b/src/nvim_bridge/tests.rs @@ -688,105 +688,10 @@ mod parse_redraw_event_tests { mod parse_gnvim_event_tests { use crate::nvim_bridge; - use crate::nvim_bridge::{ - CmdlineColors, GnvimEvent, PmenuColors, SetGuiColors, TablineColors, - WildmenuColors, - }; - use crate::ui::color::Color; + use crate::nvim_bridge::GnvimEvent; use rmpv::Value; #[test] - fn set_gui_colors() { - let expected: Result<GnvimEvent, String> = - Ok(GnvimEvent::SetGuiColors(SetGuiColors { - pmenu: PmenuColors { - bg: Some( - Color::from_hex_string("#00ff00".to_owned()).unwrap(), - ), - fg: Some( - Color::from_hex_string("#0000ff".to_owned()).unwrap(), - ), - sel_bg: Some( - Color::from_hex_string("#00ff00".to_owned()).unwrap(), - ), - sel_fg: Some( - Color::from_hex_string("#0000ff".to_owned()).unwrap(), - ), - }, - tabline: TablineColors { - bg: Some( - Color::from_hex_string("#00ff00".to_owned()).unwrap(), - ), - fg: Some( - Color::from_hex_string("#0000ff".to_owned()).unwrap(), - ), - sel_bg: Some( - Color::from_hex_string("#00ff00".to_owned()).unwrap(), - ), - sel_fg: Some( - Color::from_hex_string("#0000ff".to_owned()).unwrap(), - ), - fill_bg: Some( - Color::from_hex_string("#f0ff00".to_owned()).unwrap(), - ), - fill_fg: Some( - Color::from_hex_string("#f000ff".to_owned()).unwrap(), - ), - }, - cmdline: CmdlineColors { - bg: Some( - Color::from_hex_string("#0Aff00".to_owned()).unwrap(), - ), - fg: Some( - Color::from_hex_string("#0A00ff".to_owned()).unwrap(), - ), - border: Some( - Color::from_hex_string("#A0ff00".to_owned()).unwrap(), - ), - }, - wildmenu: WildmenuColors { - bg: Some( - Color::from_hex_string("#00ffe0".to_owned()).unwrap(), - ), - fg: Some( - Color::from_hex_string("#0000ef".to_owned()).unwrap(), - ), - sel_bg: Some( - Color::from_hex_string("#e0ff00".to_owned()).unwrap(), - ), - sel_fg: Some( - Color::from_hex_string("#0e00ff".to_owned()).unwrap(), - ), - }, - })); - - let res = nvim_bridge::parse_gnvim_event(vec![ - "SetGuiColors".into(), - Value::Map(vec![ - ("pmenu_bg".into(), "#00ff00".into()), - ("pmenu_fg".into(), "#0000ff".into()), - ("pmenusel_bg".into(), "#00ff00".into()), - ("pmenusel_fg".into(), "#0000ff".into()), - ("tabline_bg".into(), "#00ff00".into()), - ("tabline_fg".into(), "#0000ff".into()), - ("tablinesel_bg".into(), "#00ff00".into()), - ("tablinesel_fg".into(), "#0000ff".into()), - ("tablinefill_bg".into(), "#f0ff00".into()), - ("tablinefill_fg".into(), "#f000ff".into()), - ("cmdline_bg".into(), "#0Aff00".into()), - ("cmdline_fg".into(), "#0A00ff".into()), - ("cmdline_border".into(), "#A0ff00".into()), - ("wildmenu_bg".into(), "#00ffe0".into()), - ("wildmenu_fg".into(), "#0000ef".into()), - ("wildmenusel_bg".into(), "#e0ff00".into()), - ("wildmenusel_fg".into(), "#0e00ff".into()), - ]), - ]); - - assert_eq!(expected, res); - } - - #[test] fn completion_menu_toggle_info() { let expected: Result<GnvimEvent, String> = Ok(GnvimEvent::CompletionMenuToggleInfo); diff --git a/src/ui/cmdline.rs b/src/ui/cmdline.rs index 7666928..2123266 100644 --- a/src/ui/cmdline.rs +++ b/src/ui/cmdline.rs @@ -3,13 +3,20 @@ use gtk::prelude::*; use crate::nvim_bridge; use crate::nvim_gio::GioNeovim; -use crate::ui::color::HlDefs; +use crate::ui::color::{Color, HlDefs, HlGroup}; use crate::ui::common::calc_line_space; use crate::ui::font::{Font, FontUnit}; use crate::ui::wildmenu::Wildmenu; const MAX_WIDTH: i32 = 650; +#[derive(Default)] +pub struct CmdlineColors { + pub fg: Option<Color>, + pub bg: Option<Color>, + pub border: Option<Color>, +} + struct CmdlineBlock { frame: gtk::Frame, scrolledwindow: gtk::ScrolledWindow, @@ -150,11 +157,7 @@ impl CmdlineBlock { buffer.set_text(""); } - fn set_colors( - &self, - colors: &nvim_bridge::CmdlineColors, - hl_defs: &HlDefs, - ) { + fn set_colors(&self, colors: &CmdlineColors, hl_defs: &HlDefs) { if gtk::get_minor_version() < 20 { self.set_colors_pre20(colors, hl_defs); } else { @@ -162,11 +165,7 @@ impl CmdlineBlock { } } - fn set_colors_pre20( - &self, - colors: &nvim_bridge::CmdlineColors, - hl_defs: &HlDefs, - ) { + fn set_colors_pre20(&self, colors: &CmdlineColors, hl_defs: &HlDefs) { let css = format!( "GtkFrame {{ border: none; @@ -186,11 +185,7 @@ impl CmdlineBlock { .unwrap(); } - fn set_colors_post20( - &self, - colors: &nvim_bridge::CmdlineColors, - hl_defs: &HlDefs, - ) { + fn set_colors_post20(&self, colors: &CmdlineColors, hl_defs: &HlDefs) { let css = format!( "frame {{ padding: 5px; @@ -321,11 +316,7 @@ impl CmdlineInput { iter.backward_char(); } - fn set_colors( - &self, - colors: &nvim_bridge::CmdlineColors, - hl_defs: &HlDefs, - ) { + fn set_colors(&self, colors: &CmdlineColors, hl_defs: &HlDefs) { if gtk::get_minor_version() < 20 { self.set_colors_pre20(colors, hl_defs); } else { @@ -333,11 +324,7 @@ impl CmdlineInput { } } - fn set_colors_pre20( - &self, - colors: &nvim_bridge::CmdlineColors, - hl_defs: &HlDefs, - ) { + fn set_colors_pre20(&self, colors: &CmdlineColors, hl_defs: &HlDefs) { let css = format!( "GtkFrame {{ border: none; @@ -357,11 +344,7 @@ impl CmdlineInput { .unwrap(); } - fn set_colors_post20( - &self, - colors: &nvim_bridge::CmdlineColors, - hl_defs: &HlDefs, - ) { + fn set_colors_post20(&self, colors: &CmdlineColors, hl_defs: &HlDefs) { let css = format!( "frame {{ padding: 5px; @@ -426,7 +409,7 @@ pub struct Cmdline { /// If the wildmenu should be shown or not. show_wildmenu: bool, - colors: nvim_bridge::CmdlineColors, + colors: CmdlineColors, /// Our font. This is inherited to input, block and wildmenu through our /// styles. font: Font, @@ -481,18 +464,31 @@ impl Cmdline { show_block: false, show_wildmenu: false, font: Font::default(), - colors: nvim_bridge::CmdlineColors::default(), + colors: CmdlineColors::default(), } } - pub fn set_colors( - &mut self, - colors: nvim_bridge::CmdlineColors, - hl_defs: &HlDefs, - ) { - self.input.set_colors(&colors, hl_defs); - self.block.set_colors(&colors, hl_defs); - self.colors = colors; + pub fn set_colors(&mut self, hl_defs: &HlDefs) { + self.colors = CmdlineColors { + bg: hl_defs + .get_hl_group(&HlGroup::Cmdline) + .cloned() + .unwrap_or_default() + .background, + fg: hl_defs + .get_hl_group(&HlGroup::Cmdline) + .cloned() + .unwrap_or_default() + .foreground, + border: hl_defs + .get_hl_group(&HlGroup::CmdlineBorder) + .cloned() + .unwrap_or_default() + .background, + }; + + self.input.set_colors(&self.colors, hl_defs); + self.block.set_colors(&self.colors, hl_defs); self.set_styles(hl_defs); } @@ -648,11 +644,7 @@ impl Cmdline { self.wildmenu.select(item_num as i32); } - pub fn wildmenu_set_colors( - &self, - colors: &nvim_bridge::WildmenuColors, - hl_defs: &HlDefs, - ) { - self.wildmenu.set_colors(colors, hl_defs); + pub fn wildmenu_set_colors(&self, hl_defs: &HlDefs) { + self.wildmenu.set_colors(hl_defs); } } diff --git a/src/ui/color.rs b/src/ui/color.rs index f677bc7..1048764 100644 --- a/src/ui/color.rs +++ b/src/ui/color.rs @@ -2,10 +2,28 @@ use std::collections::HashMap; use glib; +#[derive(Hash, PartialEq, Eq)] +pub enum HlGroup { + Pmenu, + PmenuSel, + + Tabline, + TablineSel, + TablineFill, + + Cmdline, + CmdlineBorder, + + Wildmenu, + WildmenuSel, +} + #[derive(Default)] pub struct HlDefs { hl_defs: HashMap<u64, Highlight>, + hl_groups: HashMap<HlGroup, u64>, + pub default_fg: Color, pub default_bg: Color, pub default_sp: Color, @@ -23,6 +41,18 @@ impl HlDefs { pub fn insert(&mut self, id: u64, hl: Highlight) -> Option<Highlight> { self.hl_defs.insert(id, hl) } + + pub fn set_hl_group(&mut self, group: HlGroup, id: u64) -> Option<u64> { + self.hl_groups.insert(group, id) + } + + pub fn get_hl_group(&self, group: &HlGroup) -> Option<&Highlight> { + if let Some(id) = self.hl_groups.get(group) { + return self.hl_defs.get(id); + } + + None + } } #[derive(Debug, Clone, Copy, Default, PartialEq)] diff --git a/src/ui/popupmenu/popupmenu.rs b/src/ui/popupmenu/popupmenu.rs index f015dff..98d1fae 100644 --- a/src/ui/popupmenu/popupmenu.rs +++ b/src/ui/popupmenu/popupmenu.rs @@ -6,9 +6,9 @@ use gtk; use gtk::prelude::*; use pango; -use crate::nvim_bridge::{CompletionItem, PmenuColors}; +use crate::nvim_bridge::CompletionItem; use crate::nvim_gio::GioNeovim; -use crate::ui::color::HlDefs; +use crate::ui::color::{Color, HlDefs, HlGroup}; use crate::ui::common::{ calc_line_space, get_preferred_horizontal_position, get_preferred_vertical_position, spawn_local, @@ -23,6 +23,14 @@ const MAX_HEIGHT: i32 = 500; const DEFAULT_WIDTH_NO_DETAILS: i32 = 430; const DEFAULT_WIDTH_WITH_DETAILS: i32 = 660; +#[derive(Default)] +pub struct PmenuColors { + pub bg: Option<Color>, + pub fg: Option<Color>, + pub sel_bg: Option<Color>, + pub sel_fg: Option<Color>, +} + struct State { selected: i32, @@ -491,8 +499,29 @@ impl Popupmenu { }); } - pub fn set_colors(&mut self, colors: PmenuColors, hl_defs: &HlDefs) { - self.colors = colors; + pub fn set_colors(&mut self, hl_defs: &HlDefs) { + self.colors = PmenuColors { + bg: hl_defs + .get_hl_group(&HlGroup::Pmenu) + .cloned() + .unwrap_or_default() + .background, + fg: hl_defs + .get_hl_group(&HlGroup::Pmenu) + .cloned() + .unwrap_or_default() + .foreground, + sel_bg: hl_defs + .get_hl_group(&HlGroup::PmenuSel) + .cloned() + .unwrap_or_default() + .background, + sel_fg: hl_defs + .get_hl_group(&HlGroup::PmenuSel) + .cloned() + .unwrap_or_default() + .foreground, + }; self.set_styles(hl_defs); } diff --git a/src/ui/state.rs b/src/ui/state.rs index fd24b5f..992ed65 100644 --- a/src/ui/state.rs +++ b/src/ui/state.rs @@ -12,13 +12,13 @@ use nvim_rs::Tabpage; use crate::nvim_bridge::{ CmdlineBlockAppend, CmdlineBlockShow, CmdlinePos, CmdlineShow, CmdlineSpecialChar, DefaultColorsSet, GnvimEvent, GridCursorGoto, - GridLineSegment, GridResize, GridScroll, HlAttrDefine, ModeChange, - ModeInfo, ModeInfoSet, Notify, OptionSet, PopupmenuShow, RedrawEvent, - TablineUpdate, WildmenuShow, + GridLineSegment, GridResize, GridScroll, HlAttrDefine, HlGroupSet, + ModeChange, ModeInfo, ModeInfoSet, Notify, OptionSet, PopupmenuShow, + RedrawEvent, TablineUpdate, WildmenuShow, }; use crate::nvim_gio::GioNeovim; use crate::ui::cmdline::Cmdline; -use crate::ui::color::HlDefs; +use crate::ui::color::{HlDefs, HlGroup}; use crate::ui::common::spawn_local; #[cfg(feature = "libwebkit2gtk")] use crate::ui::cursor_tooltip::{CursorTooltip, Gravity}; @@ -60,6 +60,10 @@ pub(crate) struct UIState { pub resize_source_id: Rc<RefCell<Option<glib::SourceId>>>, /// Resize options that is some if a resize should be send to nvim on flush. pub resize_on_flush: Option<ResizeOptions>, + + /// Flag for flush to update GUI colors on components that depend on + /// hl gruops. + pub hl_groups_changed: bool, } impl UIState { @@ -185,6 +189,31 @@ impl UIState { self.hl_defs.insert(id, hl); } + fn hl_group_set(&mut self, evt: HlGroupSet) { + match evt.name.as_str() { + "Pmenu" => { + self.hl_defs.set_hl_group(HlGroup::Pmenu, evt.hl_id); + self.hl_defs.set_hl_group(HlGroup::Wildmenu, evt.hl_id) + } + "PmenuSel" => { + self.hl_defs.set_hl_group(HlGroup::PmenuSel, evt.hl_id); + self.hl_defs.set_hl_group(HlGroup::WildmenuSel, evt.hl_id) + } + "TabLine" => self.hl_defs.set_hl_group(HlGroup::Tabline, evt.hl_id), + "TabLineSel" => { + self.hl_defs.set_hl_group(HlGroup::TablineSel, evt.hl_id); + self.hl_defs.set_hl_group(HlGroup::CmdlineBorder, evt.hl_id) + } + "TabLineFill" => { + self.hl_defs.set_hl_group(HlGroup::TablineFill, evt.hl_id) + } + "Normal" => self.hl_defs.set_hl_group(HlGroup::Cmdline, evt.hl_id), + _ => None, + }; + + self.hl_groups_changed = true; + } + fn option_set(&mut self, opt: OptionSet) { match opt { OptionSet::GuiFont(font) => { @@ -282,6 +311,15 @@ impl UIState { .set_line_space(opts.line_space, &self.hl_defs); self.tabline.set_line_space(opts.line_space, &self.hl_defs); } + + if self.hl_groups_changed { + self.popupmenu.set_colors(&self.hl_defs); + self.tabline.set_colors(&self.hl_defs); + self.cmdline.set_colors(&self.hl_defs); + self.cmdline.wildmenu_set_colors(&self.hl_defs); + + self.hl_groups_changed = false; + } } fn popupmenu_show(&mut self, popupmenu: PopupmenuShow) { @@ -413,6 +451,9 @@ impl UIState { RedrawEvent::HlAttrDefine(evt) => { evt.into_iter().for_each(|e| self.hl_attr_define(e)) } + RedrawEvent::HlGroupSet(evt) => { + evt.into_iter().for_each(|e| self.hl_group_set(e)) + } RedrawEvent::OptionSet(evt) => { evt.into_iter().for_each(|e| self.option_set(e)); } @@ -467,13 +508,6 @@ impl UIState { fn handle_gnvim_event(&mut self, event: &GnvimEvent, nvim: &GioNeovim) { match event { - GnvimEvent::SetGuiColors(colors) => { - self.popupmenu.set_colors(colors.pmenu, &self.hl_defs); - self.tabline.set_colors(colors.tabline, &self.hl_defs); - self.cmdline.set_colors(colors.cmdline, &self.hl_defs); - self.cmdline - .wildmenu_set_colors(&colors.wildmenu, &self.hl_defs); - } GnvimEvent::CompletionMenuToggleInfo => { self.popupmenu.toggle_show_info() } diff --git a/src/ui/tabline.rs b/src/ui/tabline.rs index 22f33ee..8b51fe9 100644 --- a/src/ui/tabline.rs +++ b/src/ui/tabline.rs @@ -8,12 +8,21 @@ use pango; use nvim_rs::Tabpage; -use crate::nvim_bridge; use crate::nvim_gio::{GioNeovim, GioWriter}; -use crate::ui::color::HlDefs; +use crate::ui::color::{Color, HlDefs, HlGroup}; use crate::ui::common::{calc_line_space, spawn_local}; use crate::ui::font::{Font, FontUnit}; +#[derive(Default)] +pub struct TablineColors { + pub fg: Option<Color>, + pub bg: Option<Color>, + pub fill_fg: Option<Color>, + pub fill_bg: Option<Color>, + pub sel_bg: Option<Color>, + pub sel_fg: Option<Color>, +} + pub struct Tabline { notebook: gtk::Notebook, css_provider: gtk::CssProvider, @@ -22,7 +31,7 @@ pub struct Tabline { tabpage_data: Rc<RefCell<Box<Vec<Tabpage<GioWriter>>>>>, /// Our colors. - colors: nvim_bridge::TablineColors, + colors: TablineColors, /// Our font. font: Font, @@ -60,7 +69,7 @@ impl Tabline { css_provider, switch_tab_signal, tabpage_data, - colors: nvim_bridge::TablineColors::default(), + colors: TablineColors::default(), font: Font::default(), line_space: 0, } @@ -125,12 +134,39 @@ impl Tabline { self.set_styles(hl_defs); } - pub fn set_colors( - &mut self, - colors: nvim_bridge::TablineColors, - hl_defs: &HlDefs, - ) { - self.colors = colors; + pub fn set_colors(&mut self, hl_defs: &HlDefs) { + self.colors = TablineColors { + bg: hl_defs + .get_hl_group(&HlGroup::Tabline) + .cloned() + .unwrap_or_default() + .background, + fg: hl_defs + .get_hl_group(&HlGroup::Tabline) + .cloned() + .unwrap_or_default() + .foreground, + fill_bg: hl_defs + .get_hl_group(&HlGroup::TablineFill) + .cloned() + .unwrap_or_default() + .background, + fill_fg: hl_defs + .get_hl_group(&HlGroup::TablineFill) + .cloned() + .unwrap_or_default() + .foreground, + sel_bg: hl_defs + .get_hl_group(&HlGroup::TablineSel) + .cloned() + .unwrap_or_default() + .background, + sel_fg: hl_defs + .get_hl_group(&HlGroup::TablineSel) + .cloned() + .unwrap_or_default() + .foreground, + }; self.set_styles(hl_defs); } diff --git a/src/ui/ui.rs b/src/ui/ui.rs index 9a9680e..3ea17b9 100644 --- a/src/ui/ui.rs +++ b/src/ui/ui.rs @@ -244,6 +244,7 @@ impl UI { resize_source_id: source_id, hl_defs, resize_on_flush: None, + hl_groups_changed: false, })), nvim, } diff --git a/src/ui/wildmenu.rs b/src/ui/wildmenu.rs index 166b54b..44d31a2 100644 --- a/src/ui/wildmenu.rs +++ b/src/ui/wildmenu.rs @@ -3,9 +3,8 @@ use gtk::prelude::*; use std::cell::RefCell; use std::rc::Rc; -use crate::nvim_bridge; use crate::nvim_gio::GioNeovim; -use crate::ui::color::HlDefs; +use crate::ui::color::{Color, HlDefs, HlGroup}; use crate::ui::common::spawn_local; const MAX_HEIGHT: i32 = 500; @@ -143,22 +142,35 @@ impl Wildmenu { } } - pub fn set_colors( - &self, - colors: &nvim_bridge::WildmenuColors, - hl_defs: &HlDefs, - ) { + pub fn set_colors(&self, hl_defs: &HlDefs) { + let color = hl_defs.get_hl_group(&HlGroup::Wildmenu); + let color_sel = hl_defs.get_hl_group(&HlGroup::WildmenuSel); + let fg = color + .and_then(|hl| hl.foreground) + .unwrap_or(hl_defs.default_fg); + let bg = color + .and_then(|hl| hl.background) + .unwrap_or(hl_defs.default_bg); + let sel_fg = color_sel + .and_then(|hl| hl.foreground) + .unwrap_or(hl_defs.default_fg); + let sel_bg = color_sel + .and_then(|hl| hl.background) + .unwrap_or(hl_defs.default_bg); + if gtk::get_minor_version() < 20 { - self.set_colors_pre20(colors, hl_defs); + self.set_colors_pre20(fg, bg, sel_fg, sel_bg); } else { - self.set_colors_post20(colors, hl_defs); + self.set_colors_post20(fg, bg, sel_fg, sel_bg); } } fn set_colors_pre20( &self, - colors: &nvim_bridge::WildmenuColors, - hl_defs: &HlDefs, + fg: Color, + bg: Color, + sel_fg: Color, + sel_bg: Color, ) { let css = format!( "GtkFrame {{ @@ -176,10 +188,10 @@ impl Wildmenu { color: #{sel_fg}; background: #{sel_bg}; }}", - fg = colors.fg.unwrap_or(hl_defs.default_fg).to_hex(), - bg = colors.bg.unwrap_or(hl_defs.default_bg).to_hex(), - sel_fg = colors.sel_fg.unwrap_or(hl_defs.default_fg).to_hex(), - sel_bg = colors.sel_bg.unwrap_or(hl_defs.default_bg).to_hex(), + fg = fg.to_hex(), + bg = bg.to_hex(), + sel_fg = sel_fg.to_hex(), + sel_bg = sel_bg.to_hex(), ); CssProviderExt::load_from_data(&self.css_provider, css.as_bytes()) .unwrap(); @@ -187,8 +199,10 @@ impl Wildmenu { fn set_colors_post20( &self, - colors: &nvim_bridge::WildmenuColors, - hl_defs: &HlDefs, + fg: Color, + bg: Color, + sel_fg: Color, + sel_bg: Color, ) { let css = format!( "frame > border {{ @@ -206,10 +220,10 @@ impl Wildmenu { color: #{sel_fg}; background: #{sel_bg}; }}", - fg = colors.fg.unwrap_or(hl_defs.default_fg).to_hex(), - bg = colors.bg.unwrap_or(hl_defs.default_bg).to_hex(), - sel_fg = colors.sel_fg.unwrap_or(hl_defs.default_fg).to_hex(), - sel_bg = colors.sel_bg.unwrap_or(hl_defs.default_bg).to_hex(), + fg = fg.to_hex(), + bg = bg.to_hex(), + sel_fg = sel_fg.to_hex(), + sel_bg = sel_bg.to_hex(), ); CssProviderExt::load_from_data(&self.css_provider, css.as_bytes()) .unwrap(); |