accents.rs

 1use std::sync::Arc;
 2
 3use gpui::Hsla;
 4use serde::Deserialize;
 5
 6use crate::{
 7    amber, blue, cyan, gold, grass, indigo, iris, jade, lime, orange, pink, purple, tomato,
 8    try_parse_color,
 9};
10
11/// A collection of colors that are used to color indent aware lines in the editor.
12#[derive(Clone, Debug, Deserialize, PartialEq)]
13pub struct AccentColors(pub Arc<[Hsla]>);
14
15impl Default for AccentColors {
16    /// Don't use this!
17    /// We have to have a default to be `[refineable::Refinable]`.
18    /// TODO "Find a way to not need this for Refinable"
19    fn default() -> Self {
20        Self::dark()
21    }
22}
23
24impl AccentColors {
25    /// Returns the set of dark accent colors.
26    pub fn dark() -> Self {
27        Self(Arc::from(vec![
28            blue().dark().step_9(),
29            orange().dark().step_9(),
30            pink().dark().step_9(),
31            lime().dark().step_9(),
32            purple().dark().step_9(),
33            amber().dark().step_9(),
34            jade().dark().step_9(),
35            tomato().dark().step_9(),
36            cyan().dark().step_9(),
37            gold().dark().step_9(),
38            grass().dark().step_9(),
39            indigo().dark().step_9(),
40            iris().dark().step_9(),
41        ]))
42    }
43
44    /// Returns the set of light accent colors.
45    pub fn light() -> Self {
46        Self(Arc::from(vec![
47            blue().light().step_9(),
48            orange().light().step_9(),
49            pink().light().step_9(),
50            lime().light().step_9(),
51            purple().light().step_9(),
52            amber().light().step_9(),
53            jade().light().step_9(),
54            tomato().light().step_9(),
55            cyan().light().step_9(),
56            gold().light().step_9(),
57            grass().light().step_9(),
58            indigo().light().step_9(),
59            iris().light().step_9(),
60        ]))
61    }
62}
63
64impl AccentColors {
65    /// Returns the color for the given index.
66    pub fn color_for_index(&self, index: u32) -> Hsla {
67        self.0[index as usize % self.0.len()]
68    }
69
70    /// Merges the given accent colors into this [`AccentColors`] instance.
71    pub fn merge(&mut self, accent_colors: &[settings::AccentContent]) {
72        if accent_colors.is_empty() {
73            return;
74        }
75
76        let colors = accent_colors
77            .iter()
78            .filter_map(|accent_color| {
79                accent_color
80                    .0
81                    .as_ref()
82                    .and_then(|color| try_parse_color(color).ok())
83            })
84            .collect::<Vec<_>>();
85
86        if !colors.is_empty() {
87            self.0 = Arc::from(colors);
88        }
89    }
90}