Added theme to language

Isaac Clayton created

Change summary

crates/editor/src/display_map.rs | 18 +++++++++---------
crates/language/src/language.rs  | 26 ++++++++++++++++++--------
crates/zed/src/languages/go.rs   |  2 +-
crates/zed/src/languages/rust.rs |  4 ++--
crates/zed/src/main.rs           |  6 ++++--
test.rs                          |  1 +
6 files changed, 35 insertions(+), 22 deletions(-)

Detailed changes

crates/editor/src/display_map.rs 🔗

@@ -959,10 +959,10 @@ pub mod tests {
             }"#
         .unindent();
 
-        let theme = SyntaxTheme::new(vec![
+        let theme = Arc::new(SyntaxTheme::new(vec![
             ("mod.body".to_string(), Color::red().into()),
             ("fn.name".to_string(), Color::blue().into()),
-        ]);
+        ]));
         let language = Arc::new(
             Language::new(
                 LanguageConfig {
@@ -980,7 +980,7 @@ pub mod tests {
             )
             .unwrap(),
         );
-        language.set_theme(&theme);
+        language.set_theme(theme.clone());
         cx.update(|cx| {
             let mut settings = Settings::test(cx);
             settings.language_settings.tab_size = Some(2.try_into().unwrap());
@@ -1049,10 +1049,10 @@ pub mod tests {
             }"#
         .unindent();
 
-        let theme = SyntaxTheme::new(vec![
+        let theme = Arc::new(SyntaxTheme::new(vec![
             ("mod.body".to_string(), Color::red().into()),
             ("fn.name".to_string(), Color::blue().into()),
-        ]);
+        ]));
         let language = Arc::new(
             Language::new(
                 LanguageConfig {
@@ -1070,7 +1070,7 @@ pub mod tests {
             )
             .unwrap(),
         );
-        language.set_theme(&theme);
+        language.set_theme(theme.clone());
 
         cx.update(|cx| cx.set_global(Settings::test(cx)));
 
@@ -1120,10 +1120,10 @@ pub mod tests {
         cx.foreground().set_block_on_ticks(usize::MAX..=usize::MAX);
 
         cx.update(|cx| cx.set_global(Settings::test(cx)));
-        let theme = SyntaxTheme::new(vec![
+        let theme = Arc::new(SyntaxTheme::new(vec![
             ("operator".to_string(), Color::red().into()),
             ("string".to_string(), Color::green().into()),
-        ]);
+        ]));
         let language = Arc::new(
             Language::new(
                 LanguageConfig {
@@ -1141,7 +1141,7 @@ pub mod tests {
             )
             .unwrap(),
         );
-        language.set_theme(&theme);
+        language.set_theme(theme.clone());
 
         let (text, highlighted_ranges) = marked_text_ranges(r#"const[] [a]: B = "c [d]""#);
 

crates/language/src/language.rs 🔗

@@ -279,6 +279,7 @@ pub struct Language {
     pub(crate) config: LanguageConfig,
     pub(crate) grammar: Option<Arc<Grammar>>,
     pub(crate) adapter: Option<Arc<LspAdapter>>,
+    pub(crate) theme: RwLock<Option<Arc<SyntaxTheme>>>,
 
     #[cfg(any(test, feature = "test-support"))]
     fake_adapter: Option<(
@@ -339,9 +340,8 @@ impl LanguageRegistry {
         Self::new(Task::ready(()))
     }
 
-    pub fn add(&self, language: Arc<Language>, theme: &SyntaxTheme) {
+    pub fn add(&self, language: Arc<Language>) {
         self.languages.write().push(language.clone());
-        language.set_theme(theme);
         *self.subscription.write().0.borrow_mut() = ();
     }
 
@@ -349,9 +349,9 @@ impl LanguageRegistry {
         self.subscription.read().1.clone()
     }
 
-    pub fn set_theme(&self, theme: &SyntaxTheme) {
+    pub fn set_theme(&self, theme: Arc<SyntaxTheme>) {
         for language in self.languages.read().iter() {
-            language.set_theme(theme);
+            language.set_theme(theme.clone());
         }
     }
 
@@ -576,6 +576,7 @@ impl Language {
                 })
             }),
             adapter: None,
+            theme: Default::default(),
 
             #[cfg(any(test, feature = "test-support"))]
             fake_adapter: None,
@@ -712,12 +713,21 @@ impl Language {
         c.is_whitespace() || self.config.autoclose_before.contains(c)
     }
 
-    pub fn set_theme(&self, theme: &SyntaxTheme) {
+    /// Sets the theme to the given theme, and then calls [`highlight`].
+    pub fn set_theme(&self, theme: Arc<SyntaxTheme>) {
+        *self.theme.write() = Some(theme.clone());
+        self.highlight()
+    }
+
+    /// Highlights the grammar according to the current theme,
+    /// if one has been set using [`set_theme`].
+    pub fn highlight(&self) {
         if let Some(grammar) = self.grammar.as_ref() {
             if let Some(highlights_query) = &grammar.highlights_query {
-                *grammar.highlight_map.lock() =
-                    HighlightMap::new(highlights_query.capture_names(), theme);
-                dbg!("highlighting");
+                if let Some(theme) = self.theme.read().as_ref() {
+                    *grammar.highlight_map.lock() =
+                        HighlightMap::new(highlights_query.capture_names(), &theme);
+                }
             }
         }
     }

crates/zed/src/languages/go.rs 🔗

@@ -324,7 +324,7 @@ mod tests {
             ("number".into(), Color::yellow().into()),
             ("property".into(), Color::white().into()),
         ]);
-        language.set_theme(&theme);
+        language.set_theme(theme.into());
 
         let grammar = language.grammar().unwrap();
         let highlight_function = grammar.highlight_id_for_name("function").unwrap();

crates/zed/src/languages/rust.rs 🔗

@@ -315,7 +315,7 @@ mod tests {
             ("property".into(), Color::white().into()),
         ]);
 
-        language.set_theme(&theme);
+        language.set_theme(theme.into());
 
         let highlight_function = grammar.highlight_id_for_name("function").unwrap();
         let highlight_type = grammar.highlight_id_for_name("type").unwrap();
@@ -394,7 +394,7 @@ mod tests {
             ("property".into(), Color::white().into()),
         ]);
 
-        language.set_theme(&theme);
+        language.set_theme(theme.into());
 
         let highlight_function = grammar.highlight_id_for_name("function").unwrap();
         let highlight_type = grammar.highlight_id_for_name("type").unwrap();

crates/zed/src/main.rs 🔗

@@ -217,7 +217,7 @@ fn main() {
         cx.observe_global::<Settings, _>({
             let languages = languages.clone();
             move |cx| {
-                languages.set_theme(&cx.global::<Settings>().theme.editor.syntax);
+                languages.set_theme(cx.global::<Settings>().theme.editor.syntax.clone());
             }
         })
         .detach();
@@ -227,7 +227,9 @@ fn main() {
             |cx| async move {
                 init_languages.await;
                 dbg!("all languages initialized, starting setting highlighting");
-                cx.read(|cx| languages.set_theme(&cx.global::<Settings>().theme.editor.syntax));
+                cx.read(|cx| {
+                    languages.set_theme(cx.global::<Settings>().theme.editor.syntax.clone())
+                });
             }
         })
         .detach();