Use Pmenu colors for backgournd/foreground

This commit is contained in:
daa84 2017-11-14 18:38:24 +03:00
parent de55aecff0
commit 3b9de543ae
8 changed files with 136 additions and 19 deletions

View File

@ -1,6 +1,7 @@
use std;
use gdk;
use ui_model::Cell;
use theme::Theme;
#[derive(Clone, PartialEq, Debug)]
pub struct Color(pub f64, pub f64, pub f64);
@ -41,6 +42,7 @@ pub struct ColorModel {
pub bg_color: Color,
pub fg_color: Color,
pub sp_color: Color,
pub theme: Theme,
}
impl ColorModel {
@ -49,6 +51,7 @@ impl ColorModel {
bg_color: COLOR_BLACK,
fg_color: COLOR_WHITE,
sp_color: COLOR_RED,
theme: Theme::new(),
}
}
@ -102,4 +105,39 @@ impl ColorModel {
pub fn actual_cell_sp<'a>(&'a self, cell: &'a Cell) -> &'a Color {
cell.attrs.special.as_ref().unwrap_or(&self.sp_color)
}
pub fn pmenu_bg(&self) -> &Color {
if let Some(ref pmenu) = self.theme.pmenu {
pmenu.bg.as_ref().unwrap_or(&self.bg_color)
} else {
&self.bg_color
}
}
pub fn pmenu_fg(&self) -> &Color {
if let Some(ref pmenu) = self.theme.pmenu {
pmenu.fg.as_ref().unwrap_or(&self.fg_color)
} else {
&self.fg_color
}
}
pub fn pmenu_bg_sel(&self) -> &Color {
if let Some(ref pmenu) = self.theme.pmenu {
pmenu.bg_sel.as_ref().unwrap_or(&self.bg_color)
} else {
&self.bg_color
}
}
pub fn pmenu_fg_sel(&self) -> &Color {
if let Some(ref pmenu) = self.theme.pmenu {
pmenu.fg_sel.as_ref().unwrap_or(&self.fg_color)
} else {
&self.fg_color
}
}
}

View File

@ -28,6 +28,7 @@ mod sys;
mod nvim_config;
mod dirs;
mod theme;
mod color;
mod value;
mod mode;

View File

@ -159,7 +159,7 @@ pub fn post_start_init(
pub trait ErrorReport<T> {
fn report_err(&self, nvim: &mut NeovimApi);
fn ok_and_report(&self, nvim: &mut NeovimApi) -> Option<&T>;
fn ok_and_report(self, nvim: &mut NeovimApi) -> Option<T>;
}
impl<T> ErrorReport<T> for result::Result<T, CallError> {
@ -170,9 +170,9 @@ impl<T> ErrorReport<T> for result::Result<T, CallError> {
}
}
fn ok_and_report(&self, nvim: &mut NeovimApi) -> Option<&T> {
fn ok_and_report(self, nvim: &mut NeovimApi) -> Option<T> {
self.report_err(nvim);
self.as_ref().ok()
self.ok()
}
}

View File

@ -201,7 +201,7 @@ pub fn call(
);
let tab_attr = tab_attrs
.get("tab")
.map(|tab_id| Tabpage::new(tab_id.clone()))
.map(|&tab_id| Tabpage::new(tab_id.clone()))
.unwrap();
(tab_attr, name_attr)

View File

@ -50,11 +50,13 @@ impl State {
self.renderer.set_property_font(
Some(&shell.get_font_desc().to_string()),
);
let color_model = &shell.color_model;
self.renderer.set_property_foreground_rgba(
Some(&shell.get_foreground().into()),
Some(&color_model.pmenu_fg().into()),
);
self.renderer.set_property_background_rgba(
Some(&shell.get_background().into()),
Some(&color_model.pmenu_bg().into()),
);
let col_count = menu[0].len();

View File

@ -57,7 +57,7 @@ enum ResizeState {
pub struct State {
pub model: UiModel,
color_model: ColorModel,
pub color_model: ColorModel,
cur_attrs: Option<Attrs>,
mouse_enabled: bool,
nvim: Rc<NeovimClient>,
@ -117,14 +117,6 @@ impl State {
}
}
pub fn get_foreground(&self) -> &Color {
&self.color_model.fg_color
}
pub fn get_background(&self) -> &Color {
&self.color_model.bg_color
}
pub fn nvim(&self) -> Option<NeovimRef> {
self.nvim.nvim()
}
@ -939,6 +931,10 @@ impl RedrawEvents for State {
}
}
}
if let Some(mut nvim) = self.nvim.nvim() {
self.color_model.theme.update(&mut *nvim);
}
RepaintMode::Nothing
}

68
src/theme.rs Normal file
View File

@ -0,0 +1,68 @@
use std::collections::HashMap;
use neovim_lib::{Value, Neovim, NeovimApi};
use nvim::ErrorReport;
use color::Color;
use value::ValueMapExt;
pub struct Theme {
pub pmenu: Option<Pmenu>,
}
impl Theme {
pub fn new() -> Self {
Theme { pmenu: None }
}
pub fn update(&mut self, nvim: &mut Neovim) {
self.pmenu = Some(Pmenu::new(nvim));
}
}
pub struct Pmenu {
pub bg: Option<Color>,
pub fg: Option<Color>,
pub bg_sel: Option<Color>,
pub fg_sel: Option<Color>,
}
impl Pmenu {
pub fn new(nvim: &mut Neovim) -> Self {
let (bg, fg) = get_hl_colors(nvim, "Pmenu");
let (bg_sel, fg_sel) = get_hl_colors(nvim, "PmenuSel");
Pmenu {
bg,
fg,
bg_sel,
fg_sel,
}
}
}
fn get_hl_color(map: &HashMap<&str, &Value>, color_name: &str) -> Option<Color> {
if let Some(col) = map.get(color_name) {
if let Some(col) = col.as_u64() {
Some(Color::from_indexed_color(col))
} else {
None
}
} else {
None
}
}
fn get_hl_colors(nvim: &mut Neovim, hl: &str) -> (Option<Color>, Option<Color>) {
nvim.get_hl_by_name(hl, true)
.ok_and_report(nvim)
.and_then(|m| if let Some(m) = m.to_attrs_map_report() {
Some((
get_hl_color(&m, "background"),
get_hl_color(&m, "foreground"),
))
} else {
None
})
.unwrap_or((None, None))
}

View File

@ -2,19 +2,31 @@ use std::collections::HashMap;
use neovim_lib::Value;
pub trait ValueMapExt {
fn to_attrs_map(&self) -> Result<HashMap<&str, Value>, String>;
fn to_attrs_map(&self) -> Result<HashMap<&str, &Value>, String>;
fn to_attrs_map_report(&self) -> Option<HashMap<&str, &Value>>;
}
impl ValueMapExt for Vec<(Value, Value)> {
fn to_attrs_map(&self) -> Result<HashMap<&str, Value>, String> {
fn to_attrs_map(&self) -> Result<HashMap<&str, &Value>, String> {
self.iter()
.map(|p| {
p.0
.as_str()
.ok_or_else(|| "Can't convert map key to string".to_owned())
.map(|key| (key, p.1.clone()))
.map(|key| (key, &p.1))
})
.collect::<Result<HashMap<&str, Value>, String>>()
.collect::<Result<HashMap<&str, &Value>, String>>()
}
fn to_attrs_map_report(&self) -> Option<HashMap<&str, &Value>> {
match self.to_attrs_map() {
Err(e) => {
error!("{}", e);
None
}
Ok(m) => Some(m),
}
}
}