syntax.rs

  1use gpui::{HighlightStyle, Hsla};
  2
  3use crate::{
  4    blue, cyan, gold, indigo, iris, jade, lime, mint, neutral, orange, plum, purple, red, sky,
  5    tomato, yellow,
  6};
  7
  8#[derive(Clone, Default)]
  9pub struct SyntaxTheme {
 10    pub highlights: Vec<(String, HighlightStyle)>,
 11}
 12
 13impl SyntaxTheme {
 14    pub fn light() -> Self {
 15        Self {
 16            highlights: vec![
 17                ("attribute".into(), cyan().light().step_11().into()),
 18                ("boolean".into(), tomato().light().step_11().into()),
 19                ("comment".into(), neutral().light().step_10().into()),
 20                ("comment.doc".into(), iris().light().step_11().into()),
 21                ("constant".into(), red().light().step_9().into()),
 22                ("constructor".into(), red().light().step_9().into()),
 23                ("embedded".into(), red().light().step_9().into()),
 24                ("emphasis".into(), red().light().step_9().into()),
 25                ("emphasis.strong".into(), red().light().step_9().into()),
 26                ("enum".into(), red().light().step_9().into()),
 27                ("function".into(), red().light().step_9().into()),
 28                ("hint".into(), red().light().step_9().into()),
 29                ("keyword".into(), orange().light().step_9().into()),
 30                ("label".into(), red().light().step_9().into()),
 31                ("link_text".into(), red().light().step_9().into()),
 32                ("link_uri".into(), red().light().step_9().into()),
 33                ("number".into(), purple().light().step_10().into()),
 34                ("operator".into(), red().light().step_9().into()),
 35                ("predictive".into(), red().light().step_9().into()),
 36                ("preproc".into(), red().light().step_9().into()),
 37                ("primary".into(), red().light().step_9().into()),
 38                ("property".into(), red().light().step_9().into()),
 39                ("punctuation".into(), neutral().light().step_11().into()),
 40                (
 41                    "punctuation.bracket".into(),
 42                    neutral().light().step_11().into(),
 43                ),
 44                (
 45                    "punctuation.delimiter".into(),
 46                    neutral().light().step_10().into(),
 47                ),
 48                (
 49                    "punctuation.list_marker".into(),
 50                    blue().light().step_11().into(),
 51                ),
 52                ("punctuation.special".into(), red().light().step_9().into()),
 53                ("string".into(), jade().light().step_9().into()),
 54                ("string.escape".into(), red().light().step_9().into()),
 55                ("string.regex".into(), tomato().light().step_9().into()),
 56                ("string.special".into(), red().light().step_9().into()),
 57                (
 58                    "string.special.symbol".into(),
 59                    red().light().step_9().into(),
 60                ),
 61                ("tag".into(), red().light().step_9().into()),
 62                ("text.literal".into(), red().light().step_9().into()),
 63                ("title".into(), red().light().step_9().into()),
 64                ("type".into(), cyan().light().step_9().into()),
 65                ("variable".into(), red().light().step_9().into()),
 66                ("variable.special".into(), red().light().step_9().into()),
 67                ("variant".into(), red().light().step_9().into()),
 68            ],
 69        }
 70    }
 71
 72    pub fn dark() -> Self {
 73        Self {
 74            highlights: vec![
 75                ("attribute".into(), tomato().dark().step_11().into()),
 76                ("boolean".into(), tomato().dark().step_11().into()),
 77                ("comment".into(), neutral().dark().step_11().into()),
 78                ("comment.doc".into(), iris().dark().step_12().into()),
 79                ("constant".into(), orange().dark().step_11().into()),
 80                ("constructor".into(), gold().dark().step_11().into()),
 81                ("embedded".into(), red().dark().step_11().into()),
 82                ("emphasis".into(), red().dark().step_11().into()),
 83                ("emphasis.strong".into(), red().dark().step_11().into()),
 84                ("enum".into(), yellow().dark().step_11().into()),
 85                ("function".into(), blue().dark().step_11().into()),
 86                ("hint".into(), indigo().dark().step_11().into()),
 87                ("keyword".into(), plum().dark().step_11().into()),
 88                ("label".into(), red().dark().step_11().into()),
 89                ("link_text".into(), red().dark().step_11().into()),
 90                ("link_uri".into(), red().dark().step_11().into()),
 91                ("number".into(), red().dark().step_11().into()),
 92                ("operator".into(), red().dark().step_11().into()),
 93                ("predictive".into(), red().dark().step_11().into()),
 94                ("preproc".into(), red().dark().step_11().into()),
 95                ("primary".into(), red().dark().step_11().into()),
 96                ("property".into(), red().dark().step_11().into()),
 97                ("punctuation".into(), neutral().dark().step_11().into()),
 98                (
 99                    "punctuation.bracket".into(),
100                    neutral().dark().step_11().into(),
101                ),
102                (
103                    "punctuation.delimiter".into(),
104                    neutral().dark().step_11().into(),
105                ),
106                (
107                    "punctuation.list_marker".into(),
108                    blue().dark().step_11().into(),
109                ),
110                ("punctuation.special".into(), red().dark().step_11().into()),
111                ("string".into(), lime().dark().step_11().into()),
112                ("string.escape".into(), orange().dark().step_11().into()),
113                ("string.regex".into(), tomato().dark().step_11().into()),
114                ("string.special".into(), red().dark().step_11().into()),
115                (
116                    "string.special.symbol".into(),
117                    red().dark().step_11().into(),
118                ),
119                ("tag".into(), red().dark().step_11().into()),
120                ("text.literal".into(), purple().dark().step_11().into()),
121                ("title".into(), sky().dark().step_11().into()),
122                ("type".into(), mint().dark().step_11().into()),
123                ("variable".into(), red().dark().step_11().into()),
124                ("variable.special".into(), red().dark().step_11().into()),
125                ("variant".into(), red().dark().step_11().into()),
126            ],
127        }
128    }
129
130    // TODO: Get this working with `#[cfg(test)]`. Why isn't it?
131    pub fn new_test(colors: impl IntoIterator<Item = (&'static str, Hsla)>) -> Self {
132        SyntaxTheme {
133            highlights: colors
134                .into_iter()
135                .map(|(key, color)| {
136                    (
137                        key.to_owned(),
138                        HighlightStyle {
139                            color: Some(color),
140                            ..Default::default()
141                        },
142                    )
143                })
144                .collect(),
145        }
146    }
147
148    pub fn get(&self, name: &str) -> HighlightStyle {
149        self.highlights
150            .iter()
151            .find_map(|entry| if entry.0 == name { Some(entry.1) } else { None })
152            .unwrap_or_default()
153    }
154
155    pub fn color(&self, name: &str) -> Hsla {
156        self.get(name).color.unwrap_or_default()
157    }
158}