Sorted themes correctly

Mikayla Maki created

Change summary

crates/theme/src/theme.rs                   |  8 +++++
crates/theme/src/theme_registry.rs          |  8 +++---
crates/theme_selector/src/theme_selector.rs | 29 +++++++++++-----------
crates/zed/src/zed.rs                       |  8 +++---
styles/src/styleTree/app.ts                 |  4 +++
5 files changed, 34 insertions(+), 23 deletions(-)

Detailed changes

crates/theme/src/theme.rs 🔗

@@ -15,7 +15,7 @@ pub use theme_registry::*;
 #[derive(Deserialize, Default)]
 pub struct Theme {
     #[serde(default)]
-    pub name: String,
+    pub meta: ThemeMeta,
     pub workspace: Workspace,
     pub context_menu: ContextMenu,
     pub chat_panel: ChatPanel,
@@ -34,6 +34,12 @@ pub struct Theme {
     pub terminal: TerminalStyle,
 }
 
+#[derive(Deserialize, Default, Clone)]
+pub struct ThemeMeta {
+    pub name: String,
+    pub is_light: bool,
+}
+
 #[derive(Deserialize, Default)]
 pub struct Workspace {
     pub background: Color,

crates/theme/src/theme_registry.rs 🔗

@@ -1,4 +1,4 @@
-use crate::Theme;
+use crate::{Theme, ThemeMeta};
 use anyhow::{Context, Result};
 use gpui::{fonts, AssetSource, FontCache};
 use parking_lot::Mutex;
@@ -22,11 +22,11 @@ impl ThemeRegistry {
         })
     }
 
-    pub fn list(&self) -> impl Iterator<Item = String> {
+    pub fn list(&self) -> impl Iterator<Item = ThemeMeta> + '_ {
         self.assets.list("themes/").into_iter().filter_map(|path| {
             let filename = path.strip_prefix("themes/")?;
             let theme_name = filename.strip_suffix(".json")?;
-            Some(theme_name.to_string())
+            self.get(theme_name).ok().map(|theme| theme.meta.clone())
         })
     }
 
@@ -50,7 +50,7 @@ impl ThemeRegistry {
             serde_path_to_error::deserialize(&mut serde_json::Deserializer::from_slice(&theme_json))
         })?;
 
-        theme.name = name.into();
+        theme.meta.name = name.into();
         let theme = Arc::new(theme);
         self.themes.lock().insert(name.to_string(), theme.clone());
         Ok(theme)

crates/theme_selector/src/theme_selector.rs 🔗

@@ -6,12 +6,12 @@ use gpui::{
 use picker::{Picker, PickerDelegate};
 use settings::Settings;
 use std::sync::Arc;
-use theme::{Theme, ThemeRegistry};
+use theme::{Theme, ThemeMeta, ThemeRegistry};
 use workspace::{AppState, Workspace};
 
 pub struct ThemeSelector {
     registry: Arc<ThemeRegistry>,
-    theme_names: Vec<String>,
+    theme_data: Vec<ThemeMeta>,
     matches: Vec<StringMatch>,
     original_theme: Arc<Theme>,
     picker: ViewHandle<Picker<Self>>,
@@ -42,29 +42,30 @@ impl ThemeSelector {
         let original_theme = cx.global::<Settings>().theme.clone();
         let mut theme_names = registry.list().collect::<Vec<_>>();
         theme_names.sort_unstable_by(|a, b| {
-            a.ends_with("dark")
-                .cmp(&b.ends_with("dark"))
-                .then_with(|| a.cmp(b))
+            a.is_light.cmp(&b.is_light).reverse()
+            // a.ends_with("dark")
+            //     .cmp(&b.ends_with("dark"))
+            //     .then_with(|| a.cmp(b))
         });
         let matches = theme_names
             .iter()
-            .map(|name| StringMatch {
+            .map(|meta| StringMatch {
                 candidate_id: 0,
                 score: 0.0,
                 positions: Default::default(),
-                string: name.clone(),
+                string: meta.name.clone(),
             })
             .collect();
         let mut this = Self {
             registry,
-            theme_names,
+            theme_data: theme_names,
             matches,
             picker,
             original_theme: original_theme.clone(),
             selected_index: 0,
             selection_completed: false,
         };
-        this.select_if_matching(&original_theme.name);
+        this.select_if_matching(&original_theme.meta.name);
         this
     }
 
@@ -82,7 +83,7 @@ impl ThemeSelector {
 
     #[cfg(debug_assertions)]
     pub fn reload(themes: Arc<ThemeRegistry>, cx: &mut MutableAppContext) {
-        let current_theme_name = cx.global::<Settings>().theme.name.clone();
+        let current_theme_name = cx.global::<Settings>().theme.meta.name.clone();
         themes.clear();
         match themes.get(&current_theme_name) {
             Ok(theme) => {
@@ -165,13 +166,13 @@ impl PickerDelegate for ThemeSelector {
     fn update_matches(&mut self, query: String, cx: &mut ViewContext<Self>) -> gpui::Task<()> {
         let background = cx.background().clone();
         let candidates = self
-            .theme_names
+            .theme_data
             .iter()
             .enumerate()
-            .map(|(id, name)| StringMatchCandidate {
+            .map(|(id, meta)| StringMatchCandidate {
                 id,
-                char_bag: name.as_str().into(),
-                string: name.clone(),
+                char_bag: meta.name.as_str().into(),
+                string: meta.name.clone(),
             })
             .collect::<Vec<_>>();
 

crates/zed/src/zed.rs 🔗

@@ -244,7 +244,7 @@ pub fn initialize_workspace(
 
     cx.emit(workspace::Event::PaneAdded(workspace.active_pane().clone()));
 
-    let theme_names = app_state.themes.list().collect();
+    let theme_names = app_state.themes.list().map(|meta| meta.name).collect();
     let language_names = &languages::LANGUAGE_NAMES;
 
     workspace.project().update(cx, |project, cx| {
@@ -1668,12 +1668,12 @@ mod tests {
         let settings = Settings::defaults(Assets, cx.font_cache(), &themes);
 
         let mut has_default_theme = false;
-        for theme_name in themes.list() {
+        for theme_name in themes.list().map(|meta| meta.name) {
             let theme = themes.get(&theme_name).unwrap();
-            if theme.name == settings.theme.name {
+            if theme.meta.name == settings.theme.meta.name {
                 has_default_theme = true;
             }
-            assert_eq!(theme.name, theme_name);
+            assert_eq!(theme.meta.name, theme_name);
         }
         assert!(has_default_theme);
     }

styles/src/styleTree/app.ts 🔗

@@ -22,6 +22,10 @@ export const panel = {
 
 export default function app(theme: Theme): Object {
   return {
+    meta: {
+      name: theme.name,
+      isLight: theme.isLight
+    },
     picker: picker(theme),
     workspace: workspace(theme),
     contextMenu: contextMenu(theme),