Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-view/src/theme.rs')
| -rw-r--r-- | helix-view/src/theme.rs | 67 |
1 files changed, 64 insertions, 3 deletions
diff --git a/helix-view/src/theme.rs b/helix-view/src/theme.rs index 77fa7833..e2e10932 100644 --- a/helix-view/src/theme.rs +++ b/helix-view/src/theme.rs @@ -227,6 +227,7 @@ pub struct Theme { // tree-sitter highlight styles are stored in a Vec to optimize lookups scopes: Vec<String>, highlights: Vec<Style>, + rainbow_length: usize, } impl From<Value> for Theme { @@ -253,12 +254,20 @@ impl<'de> Deserialize<'de> for Theme { } } +#[allow(clippy::type_complexity)] fn build_theme_values( mut values: Map<String, Value>, -) -> (HashMap<String, Style>, Vec<String>, Vec<Style>, Vec<String>) { +) -> ( + HashMap<String, Style>, + Vec<String>, + Vec<Style>, + usize, + Vec<String>, +) { let mut styles = HashMap::new(); let mut scopes = Vec::new(); let mut highlights = Vec::new(); + let mut rainbow_length = 0; let mut warnings = Vec::new(); @@ -277,6 +286,27 @@ fn build_theme_values( styles.reserve(values.len()); scopes.reserve(values.len()); highlights.reserve(values.len()); + + for (i, style) in values + .remove("rainbow") + .and_then(|value| match palette.parse_style_array(value) { + Ok(styles) => Some(styles), + Err(err) => { + warnings.push(err); + None + } + }) + .unwrap_or_else(default_rainbow) + .into_iter() + .enumerate() + { + let name = format!("rainbow.{i}"); + styles.insert(name.clone(), style); + scopes.push(name); + highlights.push(style); + rainbow_length += 1; + } + for (name, style_value) in values { let mut style = Style::default(); if let Err(err) = palette.parse_style(&mut style, style_value) { @@ -289,9 +319,19 @@ fn build_theme_values( highlights.push(style); } - (styles, scopes, highlights, warnings) + (styles, scopes, highlights, rainbow_length, warnings) } +fn default_rainbow() -> Vec<Style> { + vec![ + Style::default().fg(Color::Red), + Style::default().fg(Color::Yellow), + Style::default().fg(Color::Green), + Style::default().fg(Color::Blue), + Style::default().fg(Color::Cyan), + Style::default().fg(Color::Magenta), + ] +} impl Theme { /// To allow `Highlight` to represent arbitrary RGB colors without turning it into an enum, /// we interpret the last 256^3 numbers as RGB. @@ -382,6 +422,10 @@ impl Theme { }) } + pub fn rainbow_length(&self) -> usize { + self.rainbow_length + } + fn from_toml(value: Value) -> (Self, Vec<String>) { if let Value::Table(table) = value { Theme::from_keys(table) @@ -392,12 +436,14 @@ impl Theme { } fn from_keys(toml_keys: Map<String, Value>) -> (Self, Vec<String>) { - let (styles, scopes, highlights, load_errors) = build_theme_values(toml_keys); + let (styles, scopes, highlights, rainbow_length, load_errors) = + build_theme_values(toml_keys); let theme = Self { styles, scopes, highlights, + rainbow_length, ..Default::default() }; (theme, load_errors) @@ -541,6 +587,21 @@ impl ThemePalette { } Ok(()) } + + fn parse_style_array(&self, value: Value) -> Result<Vec<Style>, String> { + let mut styles = Vec::new(); + + for v in value + .as_array() + .ok_or_else(|| format!("Could not parse value as an array: '{value}'"))? + { + let mut style = Style::default(); + self.parse_style(&mut style, v.clone())?; + styles.push(style); + } + + Ok(styles) + } } impl TryFrom<Value> for ThemePalette { |