@@ -78,8 +78,11 @@ impl Loader {
7878
7979#[derive(Clone, Debug)]
8080pub struct Theme {
81− scopes: Vec<String>,
81+ // UI styles are stored in a HashMap
8282 styles: HashMap<String, Style>,
83+ // tree-sitter highlight styles are stored in a Vec to optimize lookups
84+ scopes: Vec<String>,
85+ highlights: Vec<Style>,
8386}
8487
8588impl<'de> Deserialize<'de> for Theme {
@@ -88,6 +91,8 @@ impl<'de> Deserialize<'de> for Theme {
8891 D: Deserializer<'de>,
8992 {
9093 let mut styles = HashMap::new();
94+ let mut scopes = Vec::new();
95+ let mut highlights = Vec::new();
9196
9297 if let Ok(mut colors) = HashMap::<String, Value>::deserialize(deserializer) {
9398 // TODO: alert user of parsing failures in editor
@@ -102,21 +107,35 @@ impl<'de> Deserialize<'de> for Theme {
102107 .unwrap_or_default();
103108
104109 styles.reserve(colors.len());
110+ scopes.reserve(colors.len());
111+ highlights.reserve(colors.len());
112+
105113 for (name, style_value) in colors {
106114 let mut style = Style::default();
107115 if let Err(err) = palette.parse_style(&mut style, style_value) {
108116 warn!("{}", err);
109117 }
110− styles.insert(name, style);
118+
119+ // these are used both as UI and as highlights
120+ styles.insert(name.clone(), style);
121+ scopes.push(name);
122+ highlights.push(style);
111123 }
112124 }
113125
114− let scopes = styles.keys().map(ToString::to_string).collect();
115− Ok(Self { scopes, styles })
126+ Ok(Self {
127+ scopes,
128+ styles,
129+ highlights,
130+ })
116131 }
117132}
118133
119134impl Theme {
135+ pub fn highlight(&self, index: usize) -> Style {
136+ self.highlights[index]
137+ }
138+
120139 pub fn get(&self, scope: &str) -> Style {
121140 self.try_get(scope)
122141 .unwrap_or_else(|| Style::default().fg(Color::Rgb(0, 0, 255)))