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}