Emit unique highlights for each syntax token

Marshall Bowers created

Change summary

crates/theme2/src/themes/andromeda.rs      | 10 ---
crates/theme2/src/themes/ayu.rs            | 34 -------------
crates/theme2/src/themes/dracula.rs        | 18 ++----
crates/theme2/src/themes/gruvbox.rs        | 18 ++----
crates/theme2/src/themes/mod.rs            | 56 +++++++++++++----------
crates/theme2/src/themes/night_owl.rs      | 18 ++----
crates/theme2/src/themes/nord.rs           | 18 ++----
crates/theme2/src/themes/notctis.rs        | 18 ++----
crates/theme2/src/themes/palenight.rs      | 18 ++----
crates/theme2/src/themes/rose_pine.rs      | 18 ++----
crates/theme2/src/themes/solarized.rs      | 18 ++----
crates/theme2/src/themes/synthwave_84.rs   | 18 ++----
crates/theme_importer/src/main.rs          |  2 
crates/theme_importer/src/vscode.rs        | 57 ++++++++++++++---------
crates/theme_importer/src/vscode_syntax.rs | 13 +++--
15 files changed, 141 insertions(+), 193 deletions(-)

Detailed changes

crates/theme2/src/themes/andromeda.rs πŸ”—

@@ -62,10 +62,6 @@ pub fn andromeda() -> UserThemeFamily {
                     syntax: Some(UserSyntaxTheme {
                         highlights: vec![
                             ("comment".into(), rgba(0x9fa0a6cc).into()),
-                            ("something".into(), rgba(0x00e8c6ff).into()),
-                            ("punctuation".into(), rgba(0xf92571ff).into()),
-                            ("something".into(), rgba(0xc64dedff).into()),
-                            ("something".into(), rgba(0xee5d42ff).into()),
                             ("something".into(), rgba(0x95e072ff).into()),
                             ("punctuation".into(), rgba(0x95e072ff).into()),
                         ],
@@ -120,13 +116,9 @@ pub fn andromeda() -> UserThemeFamily {
                     },
                     syntax: Some(UserSyntaxTheme {
                         highlights: vec![
+                            ("punctuation".into(), rgba(0x95e072ff).into()),
                             ("comment".into(), rgba(0x9fa0a6cc).into()),
-                            ("something".into(), rgba(0x00e8c6ff).into()),
-                            ("punctuation".into(), rgba(0xf92571ff).into()),
-                            ("something".into(), rgba(0xc64dedff).into()),
-                            ("something".into(), rgba(0xee5d42ff).into()),
                             ("something".into(), rgba(0x95e072ff).into()),
-                            ("punctuation".into(), rgba(0x95e072ff).into()),
                         ],
                     }),
                 },

crates/theme2/src/themes/ayu.rs πŸ”—

@@ -65,19 +65,9 @@ pub fn ayu() -> UserThemeFamily {
                     },
                     syntax: Some(UserSyntaxTheme {
                         highlights: vec![
-                            ("comment".into(), rgba(0x787b8099).into()),
-                            ("something".into(), rgba(0x86b300ff).into()),
-                            ("something".into(), rgba(0x5c6166ff).into()),
                             ("something".into(), rgba(0xfa8d3eff).into()),
-                            ("punctuation".into(), rgba(0x5c6166b3).into()),
-                            ("punctuation".into(), rgba(0x5c6166ff).into()),
-                            ("punctuation".into(), rgba(0xed9365ff).into()),
-                            ("punctuation".into(), rgba(0xfa8d3eff).into()),
-                            ("punctuation".into(), rgba(0xfa8d3eff).into()),
-                            ("punctuation".into(), rgba(0x55b4d380).into()),
-                            ("punctuation".into(), rgba(0x55b4d380).into()),
-                            ("punctuation".into(), rgba(0x55b4d380).into()),
                             ("punctuation".into(), rgba(0x787b8099).into()),
+                            ("comment".into(), rgba(0x787b8099).into()),
                         ],
                     }),
                 },
@@ -134,18 +124,8 @@ pub fn ayu() -> UserThemeFamily {
                     },
                     syntax: Some(UserSyntaxTheme {
                         highlights: vec![
-                            ("comment".into(), rgba(0xb8cfe680).into()),
-                            ("something".into(), rgba(0xd4fe7fff).into()),
-                            ("something".into(), rgba(0xcccac2ff).into()),
                             ("something".into(), rgba(0xffad65ff).into()),
-                            ("punctuation".into(), rgba(0xcccac2b3).into()),
-                            ("punctuation".into(), rgba(0xcccac2ff).into()),
-                            ("punctuation".into(), rgba(0xf29e74ff).into()),
-                            ("punctuation".into(), rgba(0xffad65ff).into()),
-                            ("punctuation".into(), rgba(0xffad65ff).into()),
-                            ("punctuation".into(), rgba(0x5ccfe680).into()),
-                            ("punctuation".into(), rgba(0x5ccfe680).into()),
-                            ("punctuation".into(), rgba(0x5ccfe680).into()),
+                            ("comment".into(), rgba(0xb8cfe680).into()),
                             ("punctuation".into(), rgba(0xb8cfe680).into()),
                         ],
                     }),
@@ -204,17 +184,7 @@ pub fn ayu() -> UserThemeFamily {
                     syntax: Some(UserSyntaxTheme {
                         highlights: vec![
                             ("comment".into(), rgba(0xabb5be8c).into()),
-                            ("something".into(), rgba(0xa9d94bff).into()),
-                            ("something".into(), rgba(0xbfbdb6ff).into()),
                             ("something".into(), rgba(0xff8f3fff).into()),
-                            ("punctuation".into(), rgba(0xbfbdb6b3).into()),
-                            ("punctuation".into(), rgba(0xbfbdb6ff).into()),
-                            ("punctuation".into(), rgba(0xf29668ff).into()),
-                            ("punctuation".into(), rgba(0xff8f3fff).into()),
-                            ("punctuation".into(), rgba(0xff8f3fff).into()),
-                            ("punctuation".into(), rgba(0x38b9e680).into()),
-                            ("punctuation".into(), rgba(0x38b9e680).into()),
-                            ("punctuation".into(), rgba(0x38b9e680).into()),
                             ("punctuation".into(), rgba(0xabb5be8c).into()),
                         ],
                     }),

crates/theme2/src/themes/dracula.rs πŸ”—

@@ -1,18 +1,77 @@
+// This file was generated by the `theme_importer`.
+// Be careful when modifying it by hand.
 
-            // This file was generated by the `theme_importer`.
-            // Be careful when modifying it by hand.
+use gpui::rgba;
 
-            use gpui::rgba;
+use crate::{
+    Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserTheme, UserThemeFamily,
+    UserThemeStylesRefinement,
+};
 
-            use crate::{
-                Appearance, ThemeColorsRefinement, StatusColorsRefinement, UserTheme, UserThemeFamily, UserThemeStylesRefinement,
-            };
-
-            pub fn dracula() -> UserThemeFamily {
-                UserThemeFamily {
-    name: "Dracula".into(),
-    author: "Zeno Rocha".into(),

crates/theme2/src/themes/gruvbox.rs πŸ”—

@@ -1,18 +1,366 @@
+// This file was generated by the `theme_importer`.
+// Be careful when modifying it by hand.
 
-            // This file was generated by the `theme_importer`.
-            // Be careful when modifying it by hand.
+use gpui::rgba;
 
-            use gpui::rgba;
+use crate::{
+    Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserTheme, UserThemeFamily,
+    UserThemeStylesRefinement,
+};
 
-            use crate::{
-                Appearance, ThemeColorsRefinement, StatusColorsRefinement, UserTheme, UserThemeFamily, UserThemeStylesRefinement,
-            };
-
-            pub fn gruvbox() -> UserThemeFamily {
-                UserThemeFamily {
-    name: "Gruvbox".into(),
-    author: "morhetz".into(),

crates/theme2/src/themes/mod.rs πŸ”—

@@ -1,36 +1,44 @@
+// This file was generated by the `theme_importer`.
+// Be careful when modifying it by hand.
 
-        // This file was generated by the `theme_importer`.
-        // Be careful when modifying it by hand.
-
-        mod rose_pine;
-mod night_owl;
 mod andromeda;
-mod synthwave_84;
-mod palenight;
+mod ayu;
 mod dracula;
-mod solarized;
+mod gruvbox;
+mod night_owl;
 mod nord;
 mod notctis;
-mod ayu;
-mod gruvbox;
+mod palenight;
+mod rose_pine;
+mod solarized;
+mod synthwave_84;
 
-        pub use rose_pine::*;
-pub use night_owl::*;
 pub use andromeda::*;
-pub use synthwave_84::*;
-pub use palenight::*;
+pub use ayu::*;
 pub use dracula::*;
-pub use solarized::*;
+pub use gruvbox::*;
+pub use night_owl::*;
 pub use nord::*;
 pub use notctis::*;
-pub use ayu::*;
-pub use gruvbox::*;
+pub use palenight::*;
+pub use rose_pine::*;
+pub use solarized::*;
+pub use synthwave_84::*;
 
-        
-        use crate::UserThemeFamily;
+use crate::UserThemeFamily;
 
-        pub(crate) fn all_user_themes() -> Vec<UserThemeFamily> {
-            vec![rose_pine(), night_owl(), andromeda(), synthwave_84(), palenight(), dracula(), solarized(), nord(), notctis(), ayu(), gruvbox()]
-        }
-        
-        
+pub(crate) fn all_user_themes() -> Vec<UserThemeFamily> {
+    vec![
+        rose_pine(),
+        night_owl(),
+        andromeda(),
+        synthwave_84(),
+        palenight(),
+        dracula(),
+        solarized(),
+        nord(),
+        notctis(),
+        ayu(),
+        gruvbox(),
+    ]
+}

crates/theme2/src/themes/night_owl.rs πŸ”—

@@ -1,18 +1,137 @@
+// This file was generated by the `theme_importer`.
+// Be careful when modifying it by hand.
 
-            // This file was generated by the `theme_importer`.
-            // Be careful when modifying it by hand.
+use gpui::rgba;
 
-            use gpui::rgba;
+use crate::{
+    Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserTheme, UserThemeFamily,
+    UserThemeStylesRefinement,
+};
 
-            use crate::{
-                Appearance, ThemeColorsRefinement, StatusColorsRefinement, UserTheme, UserThemeFamily, UserThemeStylesRefinement,
-            };
-
-            pub fn night_owl() -> UserThemeFamily {
-                UserThemeFamily {
-    name: "Night Owl".into(),
-    author: "Sarah Drasner (sdras)".into(),

crates/theme2/src/themes/nord.rs πŸ”—

@@ -1,18 +1,77 @@
+// This file was generated by the `theme_importer`.
+// Be careful when modifying it by hand.
 
-            // This file was generated by the `theme_importer`.
-            // Be careful when modifying it by hand.
+use gpui::rgba;
 
-            use gpui::rgba;
+use crate::{
+    Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserTheme, UserThemeFamily,
+    UserThemeStylesRefinement,
+};
 
-            use crate::{
-                Appearance, ThemeColorsRefinement, StatusColorsRefinement, UserTheme, UserThemeFamily, UserThemeStylesRefinement,
-            };
-
-            pub fn nord() -> UserThemeFamily {
-                UserThemeFamily {
-    name: "Nord".into(),
-    author: "Sven Greb (svengreb)".into(),

crates/theme2/src/themes/notctis.rs πŸ”—

@@ -1,18 +1,689 @@
+// This file was generated by the `theme_importer`.
+// Be careful when modifying it by hand.
 
-            // This file was generated by the `theme_importer`.
-            // Be careful when modifying it by hand.
+use gpui::rgba;
 
-            use gpui::rgba;
+use crate::{
+    Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserTheme, UserThemeFamily,
+    UserThemeStylesRefinement,
+};
 
-            use crate::{
-                Appearance, ThemeColorsRefinement, StatusColorsRefinement, UserTheme, UserThemeFamily, UserThemeStylesRefinement,
-            };
-
-            pub fn notctis() -> UserThemeFamily {
-                UserThemeFamily {
-    name: "Notctis".into(),
-    author: "Liviu Schera (liviuschera)".into(),

crates/theme2/src/themes/palenight.rs πŸ”—

@@ -1,18 +1,195 @@
+// This file was generated by the `theme_importer`.
+// Be careful when modifying it by hand.
 
-            // This file was generated by the `theme_importer`.
-            // Be careful when modifying it by hand.
+use gpui::rgba;
 
-            use gpui::rgba;
+use crate::{
+    Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserTheme, UserThemeFamily,
+    UserThemeStylesRefinement,
+};
 
-            use crate::{
-                Appearance, ThemeColorsRefinement, StatusColorsRefinement, UserTheme, UserThemeFamily, UserThemeStylesRefinement,
-            };
-
-            pub fn palenight() -> UserThemeFamily {
-                UserThemeFamily {
-    name: "Palenight".into(),
-    author: "Olaolu Olawuyi (whizkydee)".into(),

crates/theme2/src/themes/rose_pine.rs πŸ”—

@@ -1,18 +1,198 @@
+// This file was generated by the `theme_importer`.
+// Be careful when modifying it by hand.
 
-            // This file was generated by the `theme_importer`.
-            // Be careful when modifying it by hand.
+use gpui::rgba;
 
-            use gpui::rgba;
+use crate::{
+    Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserTheme, UserThemeFamily,
+    UserThemeStylesRefinement,
+};
 
-            use crate::{
-                Appearance, ThemeColorsRefinement, StatusColorsRefinement, UserTheme, UserThemeFamily, UserThemeStylesRefinement,
-            };
-
-            pub fn rose_pine() -> UserThemeFamily {
-                UserThemeFamily {
-    name: "Rose Pine".into(),
-    author: "RosΓ© Pine".into(),

crates/theme2/src/themes/solarized.rs πŸ”—

@@ -1,18 +1,125 @@
+// This file was generated by the `theme_importer`.
+// Be careful when modifying it by hand.
 
-            // This file was generated by the `theme_importer`.
-            // Be careful when modifying it by hand.
+use gpui::rgba;
 
-            use gpui::rgba;
+use crate::{
+    Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserTheme, UserThemeFamily,
+    UserThemeStylesRefinement,
+};
 
-            use crate::{
-                Appearance, ThemeColorsRefinement, StatusColorsRefinement, UserTheme, UserThemeFamily, UserThemeStylesRefinement,
-            };
-
-            pub fn solarized() -> UserThemeFamily {
-                UserThemeFamily {
-    name: "Solarized".into(),
-    author: "Ethan Schoonover (altercation)".into(),

crates/theme2/src/themes/synthwave_84.rs πŸ”—

@@ -1,18 +1,62 @@
+// This file was generated by the `theme_importer`.
+// Be careful when modifying it by hand.
 
-            // This file was generated by the `theme_importer`.
-            // Be careful when modifying it by hand.
+use gpui::rgba;
 
-            use gpui::rgba;
+use crate::{
+    Appearance, StatusColorsRefinement, ThemeColorsRefinement, UserTheme, UserThemeFamily,
+    UserThemeStylesRefinement,
+};
 
-            use crate::{
-                Appearance, ThemeColorsRefinement, StatusColorsRefinement, UserTheme, UserThemeFamily, UserThemeStylesRefinement,
-            };
-
-            pub fn synthwave_84() -> UserThemeFamily {
-                UserThemeFamily {
-    name: "Synthwave 84".into(),
-    author: "Robb Owen (robb0wen)".into(),

crates/theme_importer/src/main.rs πŸ”—

@@ -28,7 +28,7 @@ struct FamilyMetadata {
     pub themes: Vec<ThemeMetadata>,
 }
 
-#[derive(Debug, Deserialize)]
+#[derive(Debug, Clone, Copy, Deserialize)]
 #[serde(rename_all = "snake_case")]
 pub enum ThemeAppearanceJson {
     Light,

crates/theme_importer/src/vscode.rs πŸ”—

@@ -1,3 +1,5 @@
+use std::collections::HashMap;
+
 use anyhow::Result;
 use gpui::{Hsla, Rgba};
 use serde::Deserialize;
@@ -439,9 +441,34 @@ impl VsCodeThemeConverter {
     pub fn convert(self) -> Result<UserTheme> {
         let appearance = self.theme_metadata.appearance.into();
 
+        let status_color_refinements = self.convert_status_colors()?;
+        let theme_colors_refinements = self.convert_theme_colors()?;
+
+        let mut highlight_styles = HashMap::new();
+
+        for token_color in self.theme.token_colors {
+            highlight_styles.extend(token_color.highlight_styles()?);
+        }
+
+        let syntax_theme = UserSyntaxTheme {
+            highlights: highlight_styles.into_iter().collect(),
+        };
+
+        Ok(UserTheme {
+            name: self.theme_metadata.name.into(),
+            appearance,
+            styles: UserThemeStylesRefinement {
+                colors: theme_colors_refinements,
+                status: status_color_refinements,
+                syntax: Some(syntax_theme),
+            },
+        })
+    }
+
+    fn convert_status_colors(&self) -> Result<StatusColorsRefinement> {
         let vscode_colors = &self.theme.colors;
 
-        let status_color_refinements = StatusColorsRefinement {
+        Ok(StatusColorsRefinement {
             // conflict: None,
             // created: None,
             deleted: vscode_colors
@@ -466,9 +493,13 @@ impl VsCodeThemeConverter {
                 .as_ref()
                 .traverse(|color| try_parse_color(&color))?,
             ..Default::default()
-        };
+        })
+    }
+
+    fn convert_theme_colors(&self) -> Result<ThemeColorsRefinement> {
+        let vscode_colors = &self.theme.colors;
 
-        let theme_colors_refinements = ThemeColorsRefinement {
+        Ok(ThemeColorsRefinement {
             border: vscode_colors
                 .panel_border
                 .as_ref()
@@ -622,26 +653,6 @@ impl VsCodeThemeConverter {
                 .as_ref()
                 .traverse(|color| try_parse_color(&color))?,
             ..Default::default()
-        };
-
-        let mut highlight_styles = Vec::new();
-
-        for token_color in self.theme.token_colors {
-            highlight_styles.extend(token_color.highlight_styles()?);
-        }
-
-        let syntax_theme = UserSyntaxTheme {
-            highlights: highlight_styles,
-        };
-
-        Ok(UserTheme {
-            name: self.theme_metadata.name.into(),
-            appearance,
-            styles: UserThemeStylesRefinement {
-                colors: theme_colors_refinements,
-                status: status_color_refinements,
-                syntax: Some(syntax_theme),
-            },
         })
     }
 }

crates/theme_importer/src/vscode_syntax.rs πŸ”—

@@ -2,11 +2,14 @@
 // Map tokenColors style to HighlightStyle (fontStyle, foreground, background)
 // Take in the scopes from the tokenColors and try to match each to our HighlightStyles
 
+use std::collections::HashMap;
+
 use anyhow::Result;
 use serde::Deserialize;
 use theme::UserHighlightStyle;
 
-use crate::{util::Traverse, vscode::try_parse_color};
+use crate::util::Traverse;
+use crate::vscode::try_parse_color;
 
 #[derive(Debug, Deserialize)]
 #[serde(untagged)]
@@ -30,13 +33,13 @@ pub struct VsCodeTokenColorSettings {
 }
 
 impl VsCodeTokenColor {
-    pub fn highlight_styles(&self) -> Result<Vec<(String, UserHighlightStyle)>> {
-        let mut highlight_styles = Vec::new();
+    pub fn highlight_styles(&self) -> Result<HashMap<String, UserHighlightStyle>> {
+        let mut highlight_styles = HashMap::new();
 
         let scope = match self.scope {
             Some(VsCodeTokenScope::One(ref scope)) => vec![scope.clone()],
             Some(VsCodeTokenScope::Many(ref scopes)) => scopes.clone(),
-            None => return Ok(Vec::new()),
+            None => return Ok(HashMap::new()),
         };
 
         for scope in &scope {
@@ -56,7 +59,7 @@ impl VsCodeTokenColor {
                 continue;
             }
 
-            highlight_styles.push((syntax_token, highlight_style));
+            highlight_styles.insert(syntax_token, highlight_style);
         }
 
         Ok(highlight_styles)