diff options
Diffstat (limited to 'helix-view/src/theme.rs')
-rw-r--r-- | helix-view/src/theme.rs | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/helix-view/src/theme.rs b/helix-view/src/theme.rs new file mode 100644 index 00000000..d61457d7 --- /dev/null +++ b/helix-view/src/theme.rs @@ -0,0 +1,179 @@ +use helix_core::hashmap; +use std::collections::HashMap; + +#[cfg(feature = "term")] +pub use tui::style::{Color, Style}; + +// #[derive(Clone, Copy, PartialEq, Eq, Default, Hash)] +// pub struct Color { +// pub r: u8, +// pub g: u8, +// pub b: u8, +// } + +// impl Color { +// pub fn new(r: u8, g: u8, b: u8) -> Self { +// Self { r, g, b } +// } +// } + +// #[cfg(feature = "term")] +// impl Into<tui::style::Color> for Color { +// fn into(self) -> tui::style::Color { +// tui::style::Color::Rgb(self.r, self.g, self.b) +// } +// } + +// impl std::str::FromStr for Color { +// type Err = (); + +// /// Tries to parse a string (`'#FFFFFF'` or `'FFFFFF'`) into RGB. +// fn from_str(input: &str) -> Result<Self, Self::Err> { +// let input = input.trim(); +// let input = match (input.chars().next(), input.len()) { +// (Some('#'), 7) => &input[1..], +// (_, 6) => input, +// _ => return Err(()), +// }; + +// u32::from_str_radix(&input, 16) +// .map(|s| Color { +// r: ((s >> 16) & 0xFF) as u8, +// g: ((s >> 8) & 0xFF) as u8, +// b: (s & 0xFF) as u8, +// }) +// .map_err(|_| ()) +// } +// } + +// #[derive(Clone, Copy, PartialEq, Eq, Default, Hash)] +// pub struct Style { +// pub fg: Option<Color>, +// pub bg: Option<Color>, +// // TODO: modifiers (bold, underline, italic, etc) +// } + +// impl Style { +// pub fn fg(mut self, fg: Color) -> Self { +// self.fg = Some(fg); +// self +// } + +// pub fn bg(mut self, bg: Color) -> Self { +// self.bg = Some(bg); +// self +// } +// } + +// #[cfg(feature = "term")] +// impl Into<tui::style::Style> for Style { +// fn into(self) -> tui::style::Style { +// let style = tui::style::Style::default(); + +// if let Some(fg) = self.fg { +// style.fg(fg.into()); +// } + +// if let Some(bg) = self.bg { +// style.bg(bg.into()); +// } + +// style +// } +// } + +/// Color theme for syntax highlighting. +pub struct Theme { + scopes: Vec<String>, + mapping: HashMap<&'static str, Style>, +} + +// let highlight_names: Vec<String> = [ +// "attribute", +// "constant.builtin", +// "constant", +// "function.builtin", +// "function.macro", +// "function", +// "keyword", +// "operator", +// "property", +// "punctuation", +// "comment", +// "escape", +// "label", +// // "punctuation.bracket", +// "punctuation.delimiter", +// "string", +// "string.special", +// "tag", +// "type", +// "type.builtin", +// "constructor", +// "variable", +// "variable.builtin", +// "variable.parameter", +// "path", +// ]; + +impl Default for Theme { + fn default() -> Self { + let mapping = hashmap! { + "attribute" => Style::default().fg(Color::Rgb(219, 191, 239)), // lilac + "keyword" => Style::default().fg(Color::Rgb(236, 205, 186)), // almond + "punctuation" => Style::default().fg(Color::Rgb(164, 160, 232)), // lavender + "punctuation.delimiter" => Style::default().fg(Color::Rgb(164, 160, 232)), // lavender + "operator" => Style::default().fg(Color::Rgb(219, 191, 239)), // lilac + "property" => Style::default().fg(Color::Rgb(164, 160, 232)), // lavender + "variable.parameter" => Style::default().fg(Color::Rgb(164, 160, 232)), // lavender + // TODO distinguish type from type.builtin? + "type" => Style::default().fg(Color::Rgb(255, 255, 255)), // white + "type.builtin" => Style::default().fg(Color::Rgb(255, 255, 255)), // white + "constructor" => Style::default().fg(Color::Rgb(219, 191, 239)), // lilac + "function" => Style::default().fg(Color::Rgb(255, 255, 255)), // white + "function.macro" => Style::default().fg(Color::Rgb(219, 191, 239)), // lilac + "comment" => Style::default().fg(Color::Rgb(105, 124, 129)), // sirocco + "variable.builtin" => Style::default().fg(Color::Rgb(159, 242, 143)), // mint + "constant" => Style::default().fg(Color::Rgb(255, 255, 255)), // white + "constant.builtin" => Style::default().fg(Color::Rgb(255, 255, 255)), // white + "string" => Style::default().fg(Color::Rgb(204, 204, 204)), // silver + "escape" => Style::default().fg(Color::Rgb(239, 186, 93)), // honey + // used for lifetimes + "label" => Style::default().fg(Color::Rgb(239, 186, 93)), // honey + + // TODO: diferentiate number builtin + // TODO: diferentiate doc comment + // TODO: variable as lilac + // TODO: mod/use statements as white + // TODO: mod stuff as chamoise + // TODO: add "(scoped_identifier) @path" for std::mem:: + // + // concat (ERROR) @syntax-error and "MISSING ;" selectors for errors + + "module" => Style::default().fg(Color::Rgb(255, 0, 0)), // white + "variable" => Style::default().fg(Color::Rgb(255, 0, 0)), // white + "function.builtin" => Style::default().fg(Color::Rgb(255, 0, 0)), // white + + "ui.background" => Style::default().bg(Color::Rgb(59, 34, 76)), // midnight + "ui.linenr" => Style::default().fg(Color::Rgb(90, 89, 119)), // comet + "ui.statusline" => Style::default().bg(Color::Rgb(40, 23, 51)), // revolver + }; + + let scopes = mapping.keys().map(ToString::to_string).collect(); + + Self { mapping, scopes } + } +} + +impl Theme { + pub fn get(&self, scope: &str) -> Style { + self.mapping + .get(scope) + .copied() + .unwrap_or_else(|| Style::default().fg(Color::Rgb(0, 0, 255))) + } + + pub fn scopes(&self) -> &[String] { + &self.scopes + } +} |