Load themes from settings and rework `Settings` trait

Marshall Bowers created

Change summary

Cargo.lock                                |  3 +
crates/client2/src/client2.rs             |  5 +-
crates/client2/src/telemetry.rs           |  5 +-
crates/language2/src/language_settings.rs |  7 ++-
crates/project2/src/project2.rs           | 14 +++---
crates/project2/src/project_settings.rs   |  4 +-
crates/project2/src/terminals.rs          |  3 +
crates/settings2/src/settings2.rs         |  2 
crates/settings2/src/settings_file.rs     | 26 +-----------
crates/settings2/src/settings_store.rs    | 48 ++++++++++++++++++++----
crates/storybook2/Cargo.toml              |  2 
crates/storybook2/src/storybook2.rs       | 20 +++++++---
crates/terminal2/src/terminal2.rs         |  5 +-
crates/terminal2/src/terminal_settings.rs |  2 
crates/theme2/src/settings.rs             | 19 +++++----
crates/theme2/src/theme2.rs               | 23 +++++------
crates/ui2/src/theme.rs                   |  2 
crates/zed2/Cargo.toml                    |  2 
crates/zed2/src/main.rs                   |  8 ++-
19 files changed, 114 insertions(+), 86 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -8089,7 +8089,7 @@ dependencies = [
  "log",
  "rust-embed",
  "serde",
- "settings",
+ "settings2",
  "simplelog",
  "smallvec",
  "strum",
@@ -10753,6 +10753,7 @@ dependencies = [
  "sum_tree",
  "tempdir",
  "text",
+ "theme2",
  "thiserror",
  "tiny_http",
  "toml 0.5.11",

crates/client2/src/client2.rs 🔗

@@ -24,6 +24,7 @@ use rand::prelude::*;
 use rpc::proto::{AnyTypedEnvelope, EntityMessage, EnvelopedMessage, PeerId, RequestMessage};
 use schemars::JsonSchema;
 use serde::{Deserialize, Serialize};
+use settings2::Settings;
 use std::{
     any::TypeId,
     collections::HashMap,
@@ -78,7 +79,7 @@ pub struct SignOut;
 pub struct Reconnect;
 
 pub fn init_settings(cx: &mut AppContext) {
-    settings2::register::<TelemetrySettings>(cx);
+    TelemetrySettings::register(cx);
 }
 
 pub fn init(client: &Arc<Client>, cx: &mut AppContext) {
@@ -371,7 +372,7 @@ pub struct TelemetrySettingsContent {
     pub metrics: Option<bool>,
 }
 
-impl settings2::Setting for TelemetrySettings {
+impl settings2::Settings for TelemetrySettings {
     const KEY: Option<&'static str> = Some("telemetry");
 
     type FileContent = TelemetrySettingsContent;

crates/client2/src/telemetry.rs 🔗

@@ -3,6 +3,7 @@ use gpui2::{serde_json, AppContext, AppMetadata, Executor, Task};
 use lazy_static::lazy_static;
 use parking_lot::Mutex;
 use serde::Serialize;
+use settings2::Settings;
 use std::{env, io::Write, mem, path::PathBuf, sync::Arc, time::Duration};
 use sysinfo::{Pid, PidExt, ProcessExt, System, SystemExt};
 use tempfile::NamedTempFile;
@@ -191,7 +192,7 @@ impl Telemetry {
                 };
 
                 let telemetry_settings = if let Ok(telemetry_settings) =
-                    cx.update(|cx| *settings2::get::<TelemetrySettings>(cx))
+                    cx.update(|cx| *TelemetrySettings::get_global(cx))
                 {
                     telemetry_settings
                 } else {
@@ -211,7 +212,7 @@ impl Telemetry {
         is_staff: bool,
         cx: &AppContext,
     ) {
-        if !settings2::get::<TelemetrySettings>(cx).metrics {
+        if !TelemetrySettings::get_global(cx).metrics {
             return;
         }
 

crates/language2/src/language_settings.rs 🔗

@@ -8,10 +8,11 @@ use schemars::{
     JsonSchema,
 };
 use serde::{Deserialize, Serialize};
+use settings2::Settings;
 use std::{num::NonZeroU32, path::Path, sync::Arc};
 
 pub fn init(cx: &mut AppContext) {
-    settings2::register::<AllLanguageSettings>(cx);
+    AllLanguageSettings::register(cx);
 }
 
 pub fn language_settings<'a>(
@@ -28,7 +29,7 @@ pub fn all_language_settings<'a>(
     cx: &'a AppContext,
 ) -> &'a AllLanguageSettings {
     let location = file.map(|f| (f.worktree_id(), f.path().as_ref()));
-    settings2::get_local(location, cx)
+    AllLanguageSettings::get(location, cx)
 }
 
 #[derive(Debug, Clone)]
@@ -254,7 +255,7 @@ impl InlayHintKind {
     }
 }
 
-impl settings2::Setting for AllLanguageSettings {
+impl settings2::Settings for AllLanguageSettings {
     const KEY: Option<&'static str> = None;
 
     type FileContent = AllLanguageSettingsContent;

crates/project2/src/project2.rs 🔗

@@ -58,7 +58,7 @@ use project_settings::{LspSettings, ProjectSettings};
 use rand::prelude::*;
 use search::SearchQuery;
 use serde::Serialize;
-use settings2::SettingsStore;
+use settings2::{SettingsStore, Settings};
 use sha2::{Digest, Sha256};
 use similar::{ChangeTag, TextDiff};
 use smol::channel::{Receiver, Sender};
@@ -562,7 +562,7 @@ impl SearchMatchCandidate {
 
 impl Project {
     pub fn init_settings(cx: &mut AppContext) {
-        settings2::register::<ProjectSettings>(cx);
+        ProjectSettings::register(cx);
     }
 
     pub fn init(client: &Arc<Client>, cx: &mut AppContext) {
@@ -674,7 +674,7 @@ impl Project {
                 },
                 copilot_lsp_subscription,
                 copilot_log_subscription: None,
-                current_lsp_settings: settings2::get::<ProjectSettings>(cx).lsp.clone(),
+                current_lsp_settings: ProjectSettings::get_global(cx).lsp.clone(),
                 node: Some(node),
                 prettier_instances: HashMap::default(),
             }
@@ -775,7 +775,7 @@ impl Project {
                 },
                 copilot_lsp_subscription,
                 copilot_log_subscription: None,
-                current_lsp_settings: settings2::get::<ProjectSettings>(cx).lsp.clone(),
+                current_lsp_settings: ProjectSettings::get_global(cx).lsp.clone(),
                 node: None,
                 prettier_instances: HashMap::default(),
             };
@@ -914,7 +914,7 @@ impl Project {
         let mut language_servers_to_restart = Vec::new();
         let languages = self.languages.to_vec();
 
-        let new_lsp_settings = settings2::get::<ProjectSettings>(cx).lsp.clone();
+        let new_lsp_settings = ProjectSettings::get_global(cx).lsp.clone();
         let current_lsp_settings = &self.current_lsp_settings;
         for (worktree_id, started_lsp_name) in self.language_server_ids.keys() {
             let language = languages.iter().find_map(|l| {
@@ -2493,7 +2493,7 @@ impl Project {
         self.buffers_needing_diff.insert(buffer.downgrade());
         let first_insertion = self.buffers_needing_diff.len() == 1;
 
-        let settings = settings2::get::<ProjectSettings>(cx);
+        let settings = ProjectSettings::get_global(cx);
         let delay = if let Some(delay) = settings.git.gutter_debounce {
             delay
         } else {
@@ -2789,7 +2789,7 @@ impl Project {
             None => return,
         };
 
-        let project_settings = settings2::get::<ProjectSettings>(cx);
+        let project_settings = ProjectSettings::get_global(cx);
         let lsp = project_settings.lsp.get(&adapter.name.0);
         let override_options = lsp.map(|s| s.initialization_options.clone()).flatten();
 

crates/project2/src/project_settings.rs 🔗

@@ -2,7 +2,7 @@ use collections::HashMap;
 use gpui2::AppContext;
 use schemars::JsonSchema;
 use serde::{Deserialize, Serialize};
-use settings2::Setting;
+use settings2::Settings;
 use std::sync::Arc;
 
 #[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
@@ -33,7 +33,7 @@ pub struct LspSettings {
     pub initialization_options: Option<serde_json::Value>,
 }
 
-impl Setting for ProjectSettings {
+impl Settings for ProjectSettings {
     const KEY: Option<&'static str> = None;
 
     type FileContent = Self;

crates/project2/src/terminals.rs 🔗

@@ -1,5 +1,6 @@
 use crate::Project;
 use gpui2::{AnyWindowHandle, Context, Handle, ModelContext, WeakHandle};
+use settings2::Settings;
 use std::path::{Path, PathBuf};
 use terminal2::{
     terminal_settings::{self, TerminalSettings, VenvSettingsContent},
@@ -25,7 +26,7 @@ impl Project {
                 "creating terminals as a guest is not supported yet"
             ));
         } else {
-            let settings = settings2::get::<TerminalSettings>(cx);
+            let settings = TerminalSettings::get_global(cx);
             let python_settings = settings.detect_venv.clone();
             let shell = settings.shell.clone();
 

crates/settings2/src/settings2.rs 🔗

@@ -8,7 +8,7 @@ use util::asset_str;
 
 pub use keymap_file::KeymapFile;
 pub use settings_file::*;
-pub use settings_store::{Setting, SettingsJsonSchemaParams, SettingsStore};
+pub use settings_store::{Settings, SettingsJsonSchemaParams, SettingsStore};
 
 #[derive(RustEmbed)]
 #[folder = "../../assets"]

crates/settings2/src/settings_file.rs 🔗

@@ -1,31 +1,11 @@
-use crate::{settings_store::SettingsStore, Setting};
+use crate::{settings_store::SettingsStore, Settings};
 use anyhow::Result;
 use fs::Fs;
 use futures::{channel::mpsc, StreamExt};
 use gpui2::{AppContext, Executor};
-use std::{
-    io::ErrorKind,
-    path::{Path, PathBuf},
-    str,
-    sync::Arc,
-    time::Duration,
-};
+use std::{io::ErrorKind, path::PathBuf, str, sync::Arc, time::Duration};
 use util::{paths, ResultExt};
 
-pub fn register<T: Setting>(cx: &mut AppContext) {
-    cx.update_global(|store: &mut SettingsStore, cx| {
-        store.register_setting::<T>(cx);
-    });
-}
-
-pub fn get<'a, T: Setting>(cx: &'a AppContext) -> &'a T {
-    cx.global::<SettingsStore>().get(None)
-}
-
-pub fn get_local<'a, T: Setting>(location: Option<(usize, &Path)>, cx: &'a AppContext) -> &'a T {
-    cx.global::<SettingsStore>().get(location)
-}
-
 pub const EMPTY_THEME_NAME: &'static str = "empty-theme";
 
 #[cfg(any(test, feature = "test-support"))]
@@ -119,7 +99,7 @@ async fn load_settings(fs: &Arc<dyn Fs>) -> Result<String> {
     }
 }
 
-pub fn update_settings_file<T: Setting>(
+pub fn update_settings_file<T: Settings>(
     fs: Arc<dyn Fs>,
     cx: &mut AppContext,
     update: impl 'static + Send + FnOnce(&mut T::FileContent),

crates/settings2/src/settings_store.rs 🔗

@@ -18,7 +18,7 @@ use util::{merge_non_null_json_value_into, RangeExt, ResultExt as _};
 /// A value that can be defined as a user setting.
 ///
 /// Settings can be loaded from a combination of multiple JSON files.
-pub trait Setting: 'static + Send + Sync {
+pub trait Settings: 'static + Send + Sync {
     /// The name of a key within the JSON file from which this setting should
     /// be deserialized. If this is `None`, then the setting will be deserialized
     /// from the root object.
@@ -76,6 +76,36 @@ pub trait Setting: 'static + Send + Sync {
     fn missing_default() -> anyhow::Error {
         anyhow::anyhow!("missing default")
     }
+
+    fn register(cx: &mut AppContext)
+    where
+        Self: Sized,
+    {
+        cx.update_global(|store: &mut SettingsStore, cx| {
+            store.register_setting::<Self>(cx);
+        });
+    }
+
+    fn get<'a>(path: Option<(usize, &Path)>, cx: &'a AppContext) -> &'a Self
+    where
+        Self: Sized,
+    {
+        cx.global::<SettingsStore>().get(path)
+    }
+
+    fn get_global<'a>(cx: &'a AppContext) -> &'a Self
+    where
+        Self: Sized,
+    {
+        cx.global::<SettingsStore>().get(None)
+    }
+
+    fn override_global<'a>(settings: Self, cx: &'a mut AppContext)
+    where
+        Self: Sized,
+    {
+        cx.global_mut::<SettingsStore>().override_global(settings)
+    }
 }
 
 pub struct SettingsJsonSchemaParams<'a> {
@@ -138,7 +168,7 @@ struct DeserializedSetting(Box<dyn Any>);
 
 impl SettingsStore {
     /// Add a new type of setting to the store.
-    pub fn register_setting<T: Setting>(&mut self, cx: &mut AppContext) {
+    pub fn register_setting<T: Settings>(&mut self, cx: &mut AppContext) {
         let setting_type_id = TypeId::of::<T>();
         let entry = self.setting_values.entry(setting_type_id);
         if matches!(entry, hash_map::Entry::Occupied(_)) {
@@ -177,7 +207,7 @@ impl SettingsStore {
     ///
     /// Panics if the given setting type has not been registered, or if there is no
     /// value for this setting.
-    pub fn get<T: Setting>(&self, path: Option<(usize, &Path)>) -> &T {
+    pub fn get<T: Settings>(&self, path: Option<(usize, &Path)>) -> &T {
         self.setting_values
             .get(&TypeId::of::<T>())
             .unwrap_or_else(|| panic!("unregistered setting type {}", type_name::<T>()))
@@ -189,7 +219,7 @@ impl SettingsStore {
     /// Override the global value for a setting.
     ///
     /// The given value will be overwritten if the user settings file changes.
-    pub fn override_global<T: Setting>(&mut self, value: T) {
+    pub fn override_global<T: Settings>(&mut self, value: T) {
         self.setting_values
             .get_mut(&TypeId::of::<T>())
             .unwrap_or_else(|| panic!("unregistered setting type {}", type_name::<T>()))
@@ -218,7 +248,7 @@ impl SettingsStore {
     /// This is only for tests. Normally, settings are only loaded from
     /// JSON files.
     #[cfg(any(test, feature = "test-support"))]
-    pub fn update_user_settings<T: Setting>(
+    pub fn update_user_settings<T: Settings>(
         &mut self,
         cx: &mut AppContext,
         update: impl FnOnce(&mut T::FileContent),
@@ -230,7 +260,7 @@ impl SettingsStore {
 
     /// Update the value of a setting in a JSON file, returning the new text
     /// for that JSON file.
-    pub fn new_text_for_update<T: Setting>(
+    pub fn new_text_for_update<T: Settings>(
         &self,
         old_text: String,
         update: impl FnOnce(&mut T::FileContent),
@@ -245,7 +275,7 @@ impl SettingsStore {
 
     /// Update the value of a setting in a JSON file, returning a list
     /// of edits to apply to the JSON file.
-    pub fn edits_for_update<T: Setting>(
+    pub fn edits_for_update<T: Settings>(
         &self,
         text: &str,
         update: impl FnOnce(&mut T::FileContent),
@@ -287,7 +317,7 @@ impl SettingsStore {
     }
 
     /// Configure the tab sized when updating JSON files.
-    pub fn set_json_tab_size_callback<T: Setting>(
+    pub fn set_json_tab_size_callback<T: Settings>(
         &mut self,
         get_tab_size: fn(&T) -> Option<usize>,
     ) {
@@ -544,7 +574,7 @@ impl Debug for SettingsStore {
     }
 }
 
-impl<T: Setting> AnySettingValue for SettingValue<T> {
+impl<T: Settings> AnySettingValue for SettingValue<T> {
     fn key(&self) -> Option<&'static str> {
         T::KEY
     }

crates/storybook2/Cargo.toml 🔗

@@ -19,7 +19,7 @@ itertools = "0.11.0"
 log.workspace = true
 rust-embed.workspace = true
 serde.workspace = true
-settings = { path = "../settings" }
+settings2 = { path = "../settings2" }
 simplelog = "0.9"
 smallvec.workspace = true
 strum = { version = "0.25.0", features = ["derive"] }

crates/storybook2/src/storybook2.rs 🔗

@@ -14,11 +14,11 @@ use gpui2::{
     WindowOptions,
 };
 use log::LevelFilter;
+use settings2::{default_settings, Settings, SettingsStore};
 use simplelog::SimpleLogger;
 use story_selector::ComponentStory;
-use theme2::ThemeRegistry;
+use theme2::{ThemeRegistry, ThemeSettings};
 use ui::{prelude::*, themed};
-use util::ResultExt;
 
 use crate::assets::Assets;
 use crate::story_selector::StorySelector;
@@ -56,14 +56,22 @@ fn main() {
     gpui2::App::production(asset_source).run(move |cx| {
         load_embedded_fonts(cx).unwrap();
 
+        let mut store = SettingsStore::default();
+        store
+            .set_default_settings(default_settings().as_ref(), cx)
+            .unwrap();
+        cx.set_global(store);
+
+        theme2::init(cx);
+
         let selector =
             story_selector.unwrap_or(StorySelector::Component(ComponentStory::Workspace));
 
-        let theme_registry = cx.default_global::<ThemeRegistry>();
+        let theme_registry = cx.global::<ThemeRegistry>();
 
-        if let Some(new_theme) = theme_registry.get(&theme_name).log_err() {
-            cx.set_global(new_theme);
-        }
+        let mut theme_settings = ThemeSettings::get_global(cx).clone();
+        theme_settings.active_theme = theme_registry.get(&theme_name).unwrap();
+        ThemeSettings::override_global(theme_settings, cx);
 
         cx.set_global(theme.clone());
         ui::settings::init(cx);

crates/terminal2/src/terminal2.rs 🔗

@@ -33,6 +33,7 @@ use mappings::mouse::{
 
 use procinfo::LocalProcessInfo;
 use serde::{Deserialize, Serialize};
+use settings2::Settings;
 use terminal_settings::{AlternateScroll, Shell, TerminalBlink, TerminalSettings};
 use util::truncate_and_trailoff;
 
@@ -126,7 +127,7 @@ impl EventListener for ZedListener {
 }
 
 pub fn init(cx: &mut AppContext) {
-    settings2::register::<TerminalSettings>(cx);
+    TerminalSettings::register(cx);
 }
 
 #[derive(Clone, Copy, Debug, Serialize, Deserialize)]
@@ -1190,7 +1191,7 @@ impl Terminal {
         origin: Point<Pixels>,
         cx: &mut MainThread<ModelContext<Self>>,
     ) {
-        let setting = settings2::get::<TerminalSettings>(cx);
+        let setting = TerminalSettings::get_global(cx);
 
         let position = e.position - origin;
         if self.mouse_mode(e.modifiers.shift) {

crates/terminal2/src/terminal_settings.rs 🔗

@@ -98,7 +98,7 @@ impl TerminalSettings {
     // }
 }
 
-impl settings2::Setting for TerminalSettings {
+impl settings2::Settings for TerminalSettings {
     const KEY: Option<&'static str> = Some("terminal");
 
     type FileContent = TerminalSettingsContent;

crates/theme2/src/settings.rs 🔗

@@ -8,7 +8,7 @@ use schemars::{
 };
 use serde::{Deserialize, Serialize};
 use serde_json::Value;
-use settings2::SettingsJsonSchemaParams;
+use settings2::{Settings, SettingsJsonSchemaParams};
 use std::sync::Arc;
 use util::ResultExt as _;
 
@@ -20,7 +20,7 @@ pub struct ThemeSettings {
     pub buffer_font: Font,
     pub buffer_font_size: Pixels,
     pub buffer_line_height: BufferLineHeight,
-    pub theme: Arc<Theme>,
+    pub active_theme: Arc<Theme>,
 }
 
 #[derive(Default)]
@@ -75,7 +75,7 @@ impl ThemeSettings {
 
 pub fn adjusted_font_size(size: Pixels, cx: &mut AppContext) -> Pixels {
     if let Some(adjusted_size) = cx.default_global::<AdjustedBufferFontSize>().0 {
-        let buffer_font_size = settings2::get::<ThemeSettings>(cx).buffer_font_size;
+        let buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size;
         let delta = adjusted_size - buffer_font_size;
         size + delta
     } else {
@@ -85,7 +85,7 @@ pub fn adjusted_font_size(size: Pixels, cx: &mut AppContext) -> Pixels {
 }
 
 pub fn adjust_font_size(cx: &mut AppContext, f: fn(&mut Pixels)) {
-    let buffer_font_size = settings2::get::<ThemeSettings>(cx).buffer_font_size;
+    let buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size;
     let adjusted_size = cx
         .default_global::<AdjustedBufferFontSize>()
         .0
@@ -102,7 +102,7 @@ pub fn reset_font_size(cx: &mut AppContext) {
     }
 }
 
-impl settings2::Setting for ThemeSettings {
+impl settings2::Settings for ThemeSettings {
     const KEY: Option<&'static str> = None;
 
     type FileContent = ThemeSettingsContent;
@@ -123,7 +123,7 @@ impl settings2::Setting for ThemeSettings {
             },
             buffer_font_size: defaults.buffer_font_size.unwrap().into(),
             buffer_line_height: defaults.buffer_line_height.unwrap(),
-            theme: themes.get(defaults.theme.as_ref().unwrap()).unwrap(),
+            active_theme: themes.get(defaults.theme.as_ref().unwrap()).unwrap(),
         };
 
         for value in user_values.into_iter().copied().cloned() {
@@ -136,11 +136,14 @@ impl settings2::Setting for ThemeSettings {
 
             if let Some(value) = &value.theme {
                 if let Some(theme) = themes.get(value).log_err() {
-                    this.theme = theme;
+                    this.active_theme = theme;
                 }
             }
 
-            merge(&mut this.buffer_font_size, value.buffer_font_size.map(Into::into));
+            merge(
+                &mut this.buffer_font_size,
+                value.buffer_font_size.map(Into::into),
+            );
             merge(&mut this.buffer_line_height, value.buffer_line_height);
         }
 

crates/theme2/src/theme2.rs 🔗

@@ -5,9 +5,19 @@ mod themes;
 pub use registry::*;
 pub use settings::*;
 
-use gpui2::{HighlightStyle, Hsla, SharedString};
+use gpui2::{AppContext, HighlightStyle, Hsla, SharedString};
+use settings2::Settings;
 use std::sync::Arc;
 
+pub fn init(cx: &mut AppContext) {
+    cx.set_global(ThemeRegistry::default());
+    ThemeSettings::register(cx);
+}
+
+pub fn active_theme<'a>(cx: &'a AppContext) -> &'a Arc<Theme> {
+    &ThemeSettings::get_global(cx).active_theme
+}
+
 pub struct Theme {
     pub metadata: ThemeMetadata,
 
@@ -102,14 +112,3 @@ pub struct ThemeMetadata {
 pub struct Editor {
     pub syntax: Arc<SyntaxTheme>,
 }
-
-// #[derive(Default)]
-// pub struct SyntaxTheme {
-//     pub highlights: Vec<(String, HighlightStyle)>,
-// }
-
-// impl SyntaxTheme {
-//     pub fn new(highlights: Vec<(String, HighlightStyle)>) -> Self {
-//         Self { highlights }
-//     }
-// }

crates/ui2/src/theme.rs 🔗

@@ -219,5 +219,5 @@ pub fn old_theme(cx: &WindowContext) -> Arc<Theme> {
 }
 
 pub fn theme(cx: &WindowContext) -> Arc<theme2::Theme> {
-    cx.global::<Arc<theme2::Theme>>().clone()
+    theme2::active_theme(cx).clone()
 }

crates/zed2/Cargo.toml 🔗

@@ -64,7 +64,7 @@ sum_tree = { path = "../sum_tree" }
 shellexpand = "2.1.0"
 text = { path = "../text" }
 # terminal_view = { path = "../terminal_view" }
-# theme = { path = "../theme" }
+theme2 = { path = "../theme2" }
 # theme_selector = { path = "../theme_selector" }
 util = { path = "../util" }
 # semantic_index = { path = "../semantic_index" }

crates/zed2/src/main.rs 🔗

@@ -19,7 +19,9 @@ use log::LevelFilter;
 use node_runtime::RealNodeRuntime;
 use parking_lot::Mutex;
 use serde::{Deserialize, Serialize};
-use settings2::{default_settings, handle_settings_file_changes, watch_config_file, SettingsStore};
+use settings2::{
+    default_settings, handle_settings_file_changes, watch_config_file, Settings, SettingsStore,
+};
 use simplelog::ConfigBuilder;
 use smol::process::Command;
 use std::{
@@ -123,7 +125,7 @@ fn main() {
 
         // cx.set_global(client.clone());
 
-        // theme::init(Assets, cx);
+        theme2::init(cx);
         // context_menu::init(cx);
         // project::Project::init(&client, cx);
         // client::init(&client, cx);
@@ -506,7 +508,7 @@ fn init_panic_hook(app: &App, installation_id: Option<String>, session_id: Strin
 }
 
 fn upload_previous_panics(http: Arc<dyn HttpClient>, cx: &mut AppContext) {
-    let telemetry_settings = *settings2::get::<client2::TelemetrySettings>(cx);
+    let telemetry_settings = *client2::TelemetrySettings::get_global(cx);
 
     cx.executor()
         .spawn(async move {