Retrive theme color as async task
This will prevent lock of ui in case of neovim slowdown and in case of errors. Also speedup starting.
This commit is contained in:
parent
ddc2d36b17
commit
d8d33edb19
63
src/color.rs
63
src/color.rs
@ -1,5 +1,7 @@
|
|||||||
use std;
|
use std;
|
||||||
|
|
||||||
use gdk;
|
use gdk;
|
||||||
|
|
||||||
use ui_model::Cell;
|
use ui_model::Cell;
|
||||||
use theme::Theme;
|
use theme::Theme;
|
||||||
|
|
||||||
@ -10,12 +12,12 @@ pub const COLOR_BLACK: Color = Color(0.0, 0.0, 0.0);
|
|||||||
pub const COLOR_WHITE: Color = Color(1.0, 1.0, 1.0);
|
pub const COLOR_WHITE: Color = Color(1.0, 1.0, 1.0);
|
||||||
pub const COLOR_RED: Color = Color(1.0, 0.0, 0.0);
|
pub const COLOR_RED: Color = Color(1.0, 0.0, 0.0);
|
||||||
|
|
||||||
impl<'a> Into<gdk::RGBA> for &'a Color {
|
impl From<Color> for gdk::RGBA {
|
||||||
fn into(self) -> gdk::RGBA {
|
fn from(color: Color) -> Self {
|
||||||
gdk::RGBA {
|
gdk::RGBA {
|
||||||
red: self.0,
|
red: color.0,
|
||||||
green: self.1,
|
green: color.1,
|
||||||
blue: self.2,
|
blue: color.2,
|
||||||
alpha: 1.0,
|
alpha: 1.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,39 +103,36 @@ impl ColorModel {
|
|||||||
cell.attrs.special.as_ref().unwrap_or(&self.sp_color)
|
cell.attrs.special.as_ref().unwrap_or(&self.sp_color)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pmenu_bg(&self) -> &Color {
|
pub fn pmenu_bg<'a>(&'a self) -> Color {
|
||||||
if let Some(ref pmenu) = self.theme.pmenu {
|
self.theme
|
||||||
pmenu.bg.as_ref().unwrap_or(&self.bg_color)
|
.pmenu()
|
||||||
} else {
|
.bg
|
||||||
&self.bg_color
|
.clone()
|
||||||
}
|
.unwrap_or_else(|| self.bg_color.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn pmenu_fg(&self) -> Color {
|
||||||
pub fn pmenu_fg(&self) -> &Color {
|
self.theme
|
||||||
if let Some(ref pmenu) = self.theme.pmenu {
|
.pmenu()
|
||||||
pmenu.fg.as_ref().unwrap_or(&self.fg_color)
|
.fg
|
||||||
} else {
|
.clone()
|
||||||
&self.fg_color
|
.unwrap_or_else(|| self.fg_color.clone())
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn pmenu_bg_sel(&self) -> Color {
|
||||||
pub fn pmenu_bg_sel(&self) -> &Color {
|
self.theme
|
||||||
if let Some(ref pmenu) = self.theme.pmenu {
|
.pmenu()
|
||||||
pmenu.bg_sel.as_ref().unwrap_or(&self.bg_color)
|
.bg_sel
|
||||||
} else {
|
.clone()
|
||||||
&self.bg_color
|
.unwrap_or_else(|| self.bg_color.clone())
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn pmenu_fg_sel(&self) -> Color {
|
||||||
pub fn pmenu_fg_sel(&self) -> &Color {
|
self.theme
|
||||||
if let Some(ref pmenu) = self.theme.pmenu {
|
.pmenu()
|
||||||
pmenu.fg_sel.as_ref().unwrap_or(&self.fg_color)
|
.fg_sel
|
||||||
} else {
|
.clone()
|
||||||
&self.fg_color
|
.unwrap_or_else(|| self.fg_color.clone())
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1181,7 +1181,7 @@ impl State {
|
|||||||
|
|
||||||
if let Some(mut nvim) = self.nvim.nvim() {
|
if let Some(mut nvim) = self.nvim.nvim() {
|
||||||
let mut render_state = self.render_state.borrow_mut();
|
let mut render_state = self.render_state.borrow_mut();
|
||||||
render_state.color_model.theme.update(&mut *nvim);
|
render_state.color_model.theme.queue_update(&mut *nvim);
|
||||||
}
|
}
|
||||||
RepaintMode::Nothing
|
RepaintMode::Nothing
|
||||||
}
|
}
|
||||||
|
111
src/theme.rs
111
src/theme.rs
@ -1,22 +1,72 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::cell::Ref;
|
||||||
|
|
||||||
use neovim_lib::{Value, Neovim, NeovimApi};
|
use glib;
|
||||||
|
|
||||||
|
use neovim_lib::{CallError, Neovim, NeovimApiAsync, Value};
|
||||||
|
|
||||||
|
use ui::UiMutex;
|
||||||
use nvim::ErrorReport;
|
use nvim::ErrorReport;
|
||||||
use color::Color;
|
use color::Color;
|
||||||
use value::ValueMapExt;
|
use value::ValueMapExt;
|
||||||
|
|
||||||
|
struct State {
|
||||||
|
pmenu: Pmenu,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl State {
|
||||||
|
fn new() -> Self {
|
||||||
|
State {
|
||||||
|
pmenu: Pmenu::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Theme {
|
pub struct Theme {
|
||||||
pub pmenu: Option<Pmenu>,
|
state: Arc<UiMutex<State>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Theme {
|
impl Theme {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Theme { pmenu: None }
|
Theme {
|
||||||
|
state: Arc::new(UiMutex::new(State::new())),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, nvim: &mut Neovim) {
|
pub fn pmenu(&self) -> Ref<Pmenu> {
|
||||||
self.pmenu = Some(Pmenu::new(nvim));
|
Ref::map(self.state.borrow(), |s| &s.pmenu)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn queue_update(&self, nvim: &mut Neovim) {
|
||||||
|
self.get_hl(nvim, "Pmenu", |state, bg, fg| {
|
||||||
|
state.pmenu.bg = bg;
|
||||||
|
state.pmenu.fg = fg;
|
||||||
|
});
|
||||||
|
|
||||||
|
self.get_hl(nvim, "PmenuSel", |state, bg_sel, fg_sel| {
|
||||||
|
state.pmenu.bg_sel = bg_sel;
|
||||||
|
state.pmenu.fg_sel = fg_sel;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_hl<CB>(&self, nvim: &mut Neovim, hl_name: &str, mut cb: CB)
|
||||||
|
where
|
||||||
|
CB: FnMut(&mut State, Option<Color>, Option<Color>) + Send + 'static,
|
||||||
|
{
|
||||||
|
let state = self.state.clone();
|
||||||
|
|
||||||
|
nvim.get_hl_by_name_async(hl_name, true)
|
||||||
|
.cb(move |v| {
|
||||||
|
let mut hl = Some(hl_colors(v));
|
||||||
|
glib::idle_add(move || {
|
||||||
|
let (bg, fg) = hl.take().unwrap();
|
||||||
|
let mut state = state.borrow_mut();
|
||||||
|
cb(&mut *state, bg, fg);
|
||||||
|
glib::Continue(false)
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.call();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,45 +78,38 @@ pub struct Pmenu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Pmenu {
|
impl Pmenu {
|
||||||
pub fn new(nvim: &mut Neovim) -> Self {
|
pub fn new() -> Self {
|
||||||
let (bg, fg) = get_hl_colors(nvim, "Pmenu");
|
|
||||||
let (bg_sel, fg_sel) = get_hl_colors(nvim, "PmenuSel");
|
|
||||||
|
|
||||||
Pmenu {
|
Pmenu {
|
||||||
bg,
|
bg: None,
|
||||||
fg,
|
fg: None,
|
||||||
bg_sel,
|
bg_sel: None,
|
||||||
fg_sel,
|
fg_sel: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_hl_color(map: &HashMap<&str, &Value>, color_name: &str) -> Option<Color> {
|
fn get_hl_color(map: &HashMap<&str, &Value>, color_name: &str) -> Option<Color> {
|
||||||
if let Some(col) = map.get(color_name) {
|
map.get(color_name)
|
||||||
if let Some(col) = col.as_u64() {
|
.and_then(|col| col.as_u64())
|
||||||
Some(Color::from_indexed_color(col))
|
.map(Color::from_indexed_color)
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_hl_colors(nvim: &mut Neovim, hl: &str) -> (Option<Color>, Option<Color>) {
|
fn hl_colors(hl: Result<Vec<(Value, Value)>, CallError>) -> (Option<Color>, Option<Color>) {
|
||||||
nvim.get_hl_by_name(hl, true)
|
hl.ok_and_report()
|
||||||
.ok_and_report()
|
.and_then(|m| {
|
||||||
.and_then(|m| if let Some(m) = m.to_attrs_map_report() {
|
if let Some(m) = m.to_attrs_map_report() {
|
||||||
let reverse = m.get("reverse").and_then(|v| v.as_bool()).unwrap_or(false);
|
let reverse = m.get("reverse").and_then(|v| v.as_bool()).unwrap_or(false);
|
||||||
let bg = get_hl_color(&m, "background");
|
let bg = get_hl_color(&m, "background");
|
||||||
let fg = get_hl_color(&m, "foreground");
|
let fg = get_hl_color(&m, "foreground");
|
||||||
if reverse {
|
if reverse {
|
||||||
Some((fg, bg))
|
Some((fg, bg))
|
||||||
|
} else {
|
||||||
|
Some((bg, fg))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Some((bg, fg))
|
None
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
None
|
|
||||||
})
|
})
|
||||||
.unwrap_or((None, None))
|
.unwrap_or((None, None))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user