Onboarding

Conrad Irwin created

Change summary

crates/agent_settings/src/agent_settings.rs                               |   6 
crates/agent_ui/src/acp/thread_view.rs                                    |   4 
crates/agent_ui/src/agent_configuration/add_llm_provider_modal.rs         |  29 
crates/agent_ui/src/agent_configuration/configure_context_server_modal.rs |  21 
crates/agent_ui/src/agent_panel.rs                                        |   9 
crates/agent_ui/src/context_server_configuration.rs                       |   3 
crates/onboarding/Cargo.toml                                              |   3 
crates/onboarding/src/ai_setup_page.rs                                    |   4 
crates/onboarding/src/base_keymap_picker.rs                               |   4 
crates/onboarding/src/basics_page.rs                                      |  24 
crates/onboarding/src/editing_page.rs                                     |  56 
crates/project/src/project_settings.rs                                    |  12 
crates/settings/src/base_keymap_setting.rs                                |  14 
crates/settings/src/settings_content/agent.rs                             |  15 
crates/theme/src/settings.rs                                              | 144 
15 files changed, 188 insertions(+), 160 deletions(-)

Detailed changes

crates/agent_settings/src/agent_settings.rs 🔗

@@ -8,8 +8,8 @@ use language_model::LanguageModel;
 use schemars::JsonSchema;
 use serde::{Deserialize, Serialize};
 use settings::{
-    AgentDockPosition, DefaultAgentView, LanguageModelParameters, LanguageModelSelection,
-    NotifyWhenAgentWaiting, Settings, SettingsContent,
+    DefaultAgentView, LanguageModelParameters, LanguageModelSelection, NotifyWhenAgentWaiting,
+    Settings, SettingsContent,
 };
 use util::MergeFrom;
 
@@ -28,7 +28,7 @@ pub fn init(cx: &mut App) {
 pub struct AgentSettings {
     pub enabled: bool,
     pub button: bool,
-    pub dock: AgentDockPosition,
+    pub dock: DockPosition,
     pub default_width: Pixels,
     pub default_height: Pixels,
     pub default_model: Option<LanguageModelSelection>,

crates/agent_ui/src/acp/thread_view.rs 🔗

@@ -7,7 +7,7 @@ use acp_thread::{AgentConnection, Plan};
 use action_log::ActionLog;
 use agent_client_protocol::{self as acp, PromptCapabilities};
 use agent_servers::{AgentServer, AgentServerDelegate};
-use agent_settings::{AgentProfileId, AgentSettings, CompletionMode, NotifyWhenAgentWaiting};
+use agent_settings::{AgentProfileId, AgentSettings, CompletionMode};
 use agent2::{DbThreadMetadata, HistoryEntry, HistoryEntryId, HistoryStore, NativeAgentServer};
 use anyhow::{Context as _, Result, anyhow, bail};
 use arrayvec::ArrayVec;
@@ -35,7 +35,7 @@ use markdown::{HeadingLevelStyles, Markdown, MarkdownElement, MarkdownStyle};
 use project::{Project, ProjectEntryId};
 use prompt_store::{PromptId, PromptStore};
 use rope::Point;
-use settings::{Settings as _, SettingsStore};
+use settings::{NotifyWhenAgentWaiting, Settings as _, SettingsStore};
 use std::cell::RefCell;
 use std::path::Path;
 use std::sync::Arc;

crates/agent_ui/src/agent_configuration/add_llm_provider_modal.rs 🔗

@@ -5,11 +5,8 @@ use collections::HashSet;
 use fs::Fs;
 use gpui::{DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, Render, Task};
 use language_model::LanguageModelRegistry;
-use language_models::{
-    AllLanguageModelSettings, OpenAiCompatibleSettingsContent,
-    provider::open_ai_compatible::{AvailableModel, ModelCapabilities},
-};
-use settings::update_settings_file;
+use language_models::provider::open_ai_compatible::{AvailableModel, ModelCapabilities};
+use settings::{OpenAiCompatibleSettingsContent, update_settings_file};
 use ui::{
     Banner, Checkbox, KeyBinding, Modal, ModalFooter, ModalHeader, Section, ToggleState, prelude::*,
 };
@@ -238,15 +235,19 @@ fn save_provider_to_settings(
         task.await
             .map_err(|_| "Failed to write API key to keychain")?;
         cx.update(|cx| {
-            update_settings_file::<AllLanguageModelSettings>(fs, cx, |settings, _cx| {
-                settings.language_models.getO
-                settings.openai_compatible.get_or_insert_default().insert(
-                    provider_name,
-                    OpenAiCompatibleSettingsContent {
-                        api_url,
-                        available_models: models,
-                    },
-                );
+            update_settings_file(fs, cx, |settings, _cx| {
+                settings
+                    .language_models
+                    .get_or_insert_default()
+                    .openai_compatible
+                    .get_or_insert_default()
+                    .insert(
+                        provider_name,
+                        OpenAiCompatibleSettingsContent {
+                            api_url,
+                            available_models: models,
+                        },
+                    );
             });
         })
         .ok();

crates/agent_ui/src/agent_configuration/configure_context_server_modal.rs 🔗

@@ -422,18 +422,17 @@ impl ConfigureContextServerModal {
             workspace.update(cx, |workspace, cx| {
                 let fs = workspace.app_state().fs.clone();
                 let original_server_id = self.original_server_id.clone();
-                update_settings_file::<ProjectSettings>(
-                    fs.clone(),
-                    cx,
-                    move |project_settings, _| {
-                        if let Some(original_id) = original_server_id {
-                            if original_id != id {
-                                project_settings.context_servers.remove(&original_id.0);
-                            }
+                update_settings_file(fs.clone(), cx, move |current, _| {
+                    if let Some(original_id) = original_server_id {
+                        if original_id != id {
+                            current.project.context_servers.remove(&original_id.0);
                         }
-                        project_settings.context_servers.insert(id.0, settings);
-                    },
-                );
+                    }
+                    current
+                        .project
+                        .context_servers
+                        .insert(id.0, settings.into());
+                });
             });
         } else if let Some(existing_server) = existing_server {
             self.context_server_store

crates/agent_ui/src/agent_panel.rs 🔗

@@ -10,6 +10,7 @@ use project::agent_server_store::{
     AgentServerCommand, AllAgentServersSettings, CLAUDE_CODE_NAME, GEMINI_NAME,
 };
 use serde::{Deserialize, Serialize};
+use settings::DefaultAgentView as DefaultView;
 use zed_actions::OpenBrowser;
 use zed_actions::agent::{OpenClaudeCodeOnboardingModal, ReauthenticateAgent};
 
@@ -33,7 +34,7 @@ use agent::{
     history_store::{HistoryEntryId, HistoryStore},
     thread_store::{TextThreadStore, ThreadStore},
 };
-use agent_settings::{AgentDockPosition, AgentSettings, DefaultAgentView};
+use agent_settings::AgentSettings;
 use ai_onboarding::AgentPanelOnboarding;
 use anyhow::{Result, anyhow};
 use assistant_context::{AssistantContext, ContextEvent, ContextSummary};
@@ -1424,11 +1425,7 @@ impl Focusable for AgentPanel {
 }
 
 fn agent_panel_dock_position(cx: &App) -> DockPosition {
-    match AgentSettings::get_global(cx).dock {
-        AgentDockPosition::Left => DockPosition::Left,
-        AgentDockPosition::Bottom => DockPosition::Bottom,
-        AgentDockPosition::Right => DockPosition::Right,
-    }
+    AgentSettings::get_global(cx).dock
 }
 
 impl EventEmitter<PanelEvent> for AgentPanel {}

crates/agent_ui/src/context_server_configuration.rs 🔗

@@ -69,8 +69,9 @@ fn remove_context_server_settings(
     fs: Arc<dyn Fs>,
     cx: &mut App,
 ) {
-    update_settings_file::<ProjectSettings>(fs, cx, move |settings, _| {
+    update_settings_file(fs, cx, move |settings, _| {
         settings
+            .project
             .context_servers
             .retain(|server_id, _| !context_server_ids.contains(server_id));
     });

crates/onboarding/Cargo.toml 🔗

@@ -45,3 +45,6 @@ workspace-hack.workspace = true
 workspace.workspace = true
 zed_actions.workspace = true
 zlog.workspace = true
+
+[dev-dependencies]
+db = {workspace = true, features = ["test-support"]}

crates/onboarding/src/ai_setup_page.rs 🔗

@@ -264,8 +264,8 @@ pub(crate) fn render_ai_setup_page(
                     );
 
                     let fs = <dyn Fs>::global(cx);
-                    update_settings_file::<DisableAiSettings>(fs, cx, move |ai_settings, _| {
-                        ai_settings.disable_ai = Some(enabled);
+                    update_settings_file(fs, cx, move |settings, _| {
+                        settings.disable_ai = Some(enabled);
                     });
                 },
             )

crates/onboarding/src/base_keymap_picker.rs 🔗

@@ -186,8 +186,8 @@ impl PickerDelegate for BaseKeymapSelectorDelegate {
                 value = base_keymap.to_string()
             );
 
-            update_settings_file::<BaseKeymap>(self.fs.clone(), cx, move |setting, _| {
-                setting.base_keymap = Some(base_keymap)
+            update_settings_file(self.fs.clone(), cx, move |setting, _| {
+                setting.base_keymap = Some(base_keymap.into())
             });
         }
 

crates/onboarding/src/basics_page.rs 🔗

@@ -194,27 +194,27 @@ fn render_theme_section(tab_index: &mut isize, cx: &mut App) -> impl IntoElement
 
     fn write_mode_change(mode: ThemeMode, cx: &mut App) {
         let fs = <dyn Fs>::global(cx);
-        update_settings_file::<ThemeSettings>(fs, cx, move |settings, _cx| {
-            settings.set_mode(mode);
+        update_settings_file(fs, cx, move |settings, _cx| {
+            theme::set_mode(settings, mode);
         });
     }
 
     fn write_theme_change(theme: impl Into<Arc<str>>, theme_mode: ThemeMode, cx: &mut App) {
         let fs = <dyn Fs>::global(cx);
         let theme = theme.into();
-        update_settings_file::<ThemeSettings>(fs, cx, move |settings, cx| {
+        update_settings_file(fs, cx, move |settings, cx| {
             if theme_mode == ThemeMode::System {
                 let (light_theme, dark_theme) =
                     get_theme_family_themes(&theme).unwrap_or((theme.as_ref(), theme.as_ref()));
 
-                settings.theme = Some(ThemeSelection::Dynamic {
+                settings.theme.theme = Some(settings::ThemeSelection::Dynamic {
                     mode: ThemeMode::System,
                     light: ThemeName(light_theme.into()),
                     dark: ThemeName(dark_theme.into()),
                 });
             } else {
                 let appearance = *SystemAppearance::global(cx);
-                settings.set_theme(theme, appearance);
+                theme::set_theme(settings, theme, appearance);
             }
         });
     }
@@ -247,10 +247,10 @@ fn render_telemetry_section(tab_index: &mut isize, cx: &App) -> impl IntoElement
                     ToggleState::Indeterminate => { return; },
                 };
 
-                update_settings_file::<TelemetrySettings>(
+                update_settings_file(
                     fs.clone(),
                     cx,
-                    move |setting, _| setting.metrics = Some(enabled),
+                    move |setting, _| setting.telemetry.get_or_insert_default().metrics = Some(enabled),
                 );
 
                 // This telemetry event shouldn't fire when it's off. If it does we'll be alerted
@@ -286,10 +286,10 @@ fn render_telemetry_section(tab_index: &mut isize, cx: &App) -> impl IntoElement
                         ToggleState::Indeterminate => { return; },
                     };
 
-                    update_settings_file::<TelemetrySettings>(
+                    update_settings_file(
                         fs.clone(),
                         cx,
-                        move |setting, _| setting.diagnostics = Some(enabled),
+                        move |setting, _| setting.telemetry.get_or_insert_default().diagnostics = Some(enabled),
                     );
 
                     // This telemetry event shouldn't fire when it's off. If it does we'll be alerted
@@ -358,8 +358,8 @@ fn render_base_keymap_section(tab_index: &mut isize, cx: &mut App) -> impl IntoE
     fn write_keymap_base(keymap_base: BaseKeymap, cx: &App) {
         let fs = <dyn Fs>::global(cx);
 
-        update_settings_file::<BaseKeymap>(fs, cx, move |setting, _| {
-            setting.base_keymap = Some(keymap_base);
+        update_settings_file(fs, cx, move |setting, _| {
+            setting.base_keymap = Some(keymap_base.into());
         });
 
         telemetry::event!("Welcome Keymap Changed", keymap = keymap_base);
@@ -387,7 +387,7 @@ fn render_vim_mode_switch(tab_index: &mut isize, cx: &mut App) -> impl IntoEleme
                         return;
                     }
                 };
-                update_settings_file::<VimModeSetting>(fs.clone(), cx, move |setting, _| {
+                update_settings_file(fs.clone(), cx, move |setting, _| {
                     setting.vim_mode = Some(vim_mode);
                 });
 

crates/onboarding/src/editing_page.rs 🔗

@@ -34,13 +34,13 @@ fn write_show_mini_map(show: ShowMinimap, cx: &mut App) {
     curr_settings.minimap.show = show;
     EditorSettings::override_global(curr_settings, cx);
 
-    update_settings_file::<EditorSettings>(fs, cx, move |editor_settings, _| {
+    update_settings_file(fs, cx, move |settings, _| {
         telemetry::event!(
             "Welcome Minimap Clicked",
-            from = editor_settings.minimap.unwrap_or_default(),
+            from = settings.editor.minimap.clone().unwrap_or_default(),
             to = show
         );
-        editor_settings.minimap.get_or_insert_default().show = Some(show);
+        settings.editor.minimap.get_or_insert_default().show = Some(show);
     });
 }
 
@@ -58,8 +58,10 @@ fn write_inlay_hints(enabled: bool, cx: &mut App) {
     curr_settings.defaults.inlay_hints.enabled = enabled;
     AllLanguageSettings::override_global(curr_settings, cx);
 
-    update_settings_file::<AllLanguageSettings>(fs, cx, move |all_language_settings, cx| {
-        all_language_settings
+    update_settings_file(fs, cx, move |settings, cx| {
+        settings
+            .project
+            .all_languages
             .defaults
             .inlay_hints
             .get_or_insert_with(|| {
@@ -80,64 +82,61 @@ fn write_git_blame(enabled: bool, cx: &mut App) {
     let fs = <dyn Fs>::global(cx);
 
     let mut curr_settings = ProjectSettings::get_global(cx).clone();
-    curr_settings
-        .git
-        .inline_blame
-        .get_or_insert_default()
-        .enabled = enabled;
+    curr_settings.git.inline_blame.enabled = enabled;
     ProjectSettings::override_global(curr_settings, cx);
 
-    update_settings_file::<ProjectSettings>(fs, cx, move |project_settings, _| {
-        project_settings
+    update_settings_file(fs, cx, move |settings, _| {
+        settings
             .git
+            .get_or_insert_default()
             .inline_blame
             .get_or_insert_default()
-            .enabled = enabled;
+            .enabled = Some(enabled);
     });
 }
 
 fn write_ui_font_family(font: SharedString, cx: &mut App) {
     let fs = <dyn Fs>::global(cx);
 
-    update_settings_file::<ThemeSettings>(fs, cx, move |theme_settings, _| {
+    update_settings_file(fs, cx, move |settings, _| {
         telemetry::event!(
             "Welcome Font Changed",
             type = "ui font",
-            old = theme_settings.ui_font_family,
+            old = settings.theme.ui_font_family,
             new = font
         );
-        theme_settings.ui_font_family = Some(FontFamilyName(font.into()));
+        settings.theme.ui_font_family = Some(FontFamilyName(font.into()));
     });
 }
 
 fn write_ui_font_size(size: Pixels, cx: &mut App) {
     let fs = <dyn Fs>::global(cx);
 
-    update_settings_file::<ThemeSettings>(fs, cx, move |theme_settings, _| {
-        theme_settings.ui_font_size = Some(size.into());
+    update_settings_file(fs, cx, move |settings, _| {
+        settings.theme.ui_font_size = Some(size.into());
     });
 }
 
 fn write_buffer_font_size(size: Pixels, cx: &mut App) {
     let fs = <dyn Fs>::global(cx);
 
-    update_settings_file::<ThemeSettings>(fs, cx, move |theme_settings, _| {
-        theme_settings.buffer_font_size = Some(size.into());
+    update_settings_file(fs, cx, move |settings, _| {
+        settings.theme.buffer_font_size = Some(size.into());
     });
 }
 
 fn write_buffer_font_family(font_family: SharedString, cx: &mut App) {
     let fs = <dyn Fs>::global(cx);
 
-    update_settings_file::<ThemeSettings>(fs, cx, move |theme_settings, _| {
+    update_settings_file(fs, cx, move |settings, _| {
         telemetry::event!(
             "Welcome Font Changed",
             type = "editor font",
-            old = theme_settings.buffer_font_family,
+            old = settings.theme.buffer_font_family,
             new = font_family
         );
 
-        theme_settings.buffer_font_family = Some(FontFamilyName(font_family.into()));
+        settings.theme.buffer_font_family = Some(FontFamilyName(font_family.into()));
     });
 }
 
@@ -153,8 +152,9 @@ fn write_font_ligatures(enabled: bool, cx: &mut App) {
     let fs = <dyn Fs>::global(cx);
     let bit = if enabled { 1 } else { 0 };
 
-    update_settings_file::<ThemeSettings>(fs, cx, move |theme_settings, _| {
-        let mut features = theme_settings
+    update_settings_file(fs, cx, move |settings, _| {
+        let mut features = settings
+            .theme
             .buffer_font_features
             .as_mut()
             .map(|features| features.tag_value_list().to_vec())
@@ -166,7 +166,7 @@ fn write_font_ligatures(enabled: bool, cx: &mut App) {
             features.push(("calt".into(), bit));
         }
 
-        theme_settings.buffer_font_features = Some(FontFeatures(Arc::new(features)));
+        settings.theme.buffer_font_features = Some(FontFeatures(Arc::new(features)));
     });
 }
 
@@ -180,8 +180,8 @@ fn read_format_on_save(cx: &App) -> bool {
 fn write_format_on_save(format_on_save: bool, cx: &mut App) {
     let fs = <dyn Fs>::global(cx);
 
-    update_settings_file::<AllLanguageSettings>(fs, cx, move |language_settings, _| {
-        language_settings.defaults.format_on_save = Some(match format_on_save {
+    update_settings_file(fs, cx, move |settings, _| {
+        settings.project.all_languages.defaults.format_on_save = Some(match format_on_save {
             true => FormatOnSave::On,
             false => FormatOnSave::Off,
         });

crates/project/src/project_settings.rs 🔗

@@ -150,6 +150,18 @@ impl From<settings::ContextServerSettingsContent> for ContextServerSettings {
         }
     }
 }
+impl Into<settings::ContextServerSettingsContent> for ContextServerSettings {
+    fn into(self) -> settings::ContextServerSettingsContent {
+        match self {
+            ContextServerSettings::Custom { enabled, command } => {
+                settings::ContextServerSettingsContent::Custom { enabled, command }
+            }
+            ContextServerSettings::Extension { enabled, settings } => {
+                settings::ContextServerSettingsContent::Extension { enabled, settings }
+            }
+        }
+    }
+}
 
 impl ContextServerSettings {
     pub fn default_extension() -> Self {

crates/settings/src/base_keymap_setting.rs 🔗

@@ -42,6 +42,20 @@ impl From<BaseKeymapContent> for BaseKeymap {
         }
     }
 }
+impl Into<BaseKeymapContent> for BaseKeymap {
+    fn into(self) -> BaseKeymapContent {
+        match self {
+            BaseKeymap::VSCode => BaseKeymapContent::VSCode,
+            BaseKeymap::JetBrains => BaseKeymapContent::JetBrains,
+            BaseKeymap::SublimeText => BaseKeymapContent::SublimeText,
+            BaseKeymap::Atom => BaseKeymapContent::Atom,
+            BaseKeymap::TextMate => BaseKeymapContent::TextMate,
+            BaseKeymap::Emacs => BaseKeymapContent::Emacs,
+            BaseKeymap::Cursor => BaseKeymapContent::Cursor,
+            BaseKeymap::None => BaseKeymapContent::None,
+        }
+    }
+}
 
 impl Display for BaseKeymap {
     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {

crates/settings/src/settings_content/agent.rs 🔗

@@ -4,6 +4,8 @@ use schemars::{JsonSchema, json_schema};
 use serde::{Deserialize, Serialize};
 use std::{borrow::Cow, path::PathBuf, sync::Arc};
 
+use crate::DockPosition;
+
 #[derive(Clone, PartialEq, Serialize, Deserialize, JsonSchema, Debug, Default)]
 pub struct AgentSettingsContent {
     /// Whether the Agent is enabled.
@@ -17,7 +19,7 @@ pub struct AgentSettingsContent {
     /// Where to dock the agent panel.
     ///
     /// Default: right
-    pub dock: Option<AgentDockPosition>,
+    pub dock: Option<DockPosition>,
     /// Default width in pixels when the agent panel is docked to the left or right.
     ///
     /// Default: 640
@@ -103,7 +105,7 @@ pub struct AgentSettingsContent {
 }
 
 impl AgentSettingsContent {
-    pub fn set_dock(&mut self, dock: AgentDockPosition) {
+    pub fn set_dock(&mut self, dock: DockPosition) {
         self.dock = Some(dock);
     }
 
@@ -174,15 +176,6 @@ pub struct ContextServerPresetContent {
     pub tools: IndexMap<Arc<str>, bool>,
 }
 
-#[derive(Copy, Clone, Default, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
-#[serde(rename_all = "snake_case")]
-pub enum AgentDockPosition {
-    Left,
-    #[default]
-    Right,
-    Bottom,
-}
-
 #[derive(Copy, Clone, Default, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
 #[serde(rename_all = "snake_case")]
 pub enum DefaultAgentView {

crates/theme/src/settings.rs 🔗

@@ -416,26 +416,32 @@ impl IconThemeSelection {
 }
 
 // impl ThemeSettingsContent {
-//     /// Sets the theme for the given appearance to the theme with the specified name.
-//     pub fn set_theme(&mut self, theme_name: impl Into<Arc<str>>, appearance: Appearance) {
-//         if let Some(selection) = self.theme.as_mut() {
-//             let theme_to_update = match selection {
-//                 ThemeSelection::Static(theme) => theme,
-//                 ThemeSelection::Dynamic { mode, light, dark } => match mode {
-//                     ThemeMode::Light => light,
-//                     ThemeMode::Dark => dark,
-//                     ThemeMode::System => match appearance {
-//                         Appearance::Light => light,
-//                         Appearance::Dark => dark,
-//                     },
-//                 },
-//             };
+/// Sets the theme for the given appearance to the theme with the specified name.
+pub fn set_theme(
+    current: &mut SettingsContent,
+    theme_name: impl Into<Arc<str>>,
+    appearance: Appearance,
+) {
+    if let Some(selection) = current.theme.theme.as_mut() {
+        let theme_to_update = match selection {
+            settings::ThemeSelection::Static(theme) => theme,
+            settings::ThemeSelection::Dynamic { mode, light, dark } => match mode {
+                ThemeMode::Light => light,
+                ThemeMode::Dark => dark,
+                ThemeMode::System => match appearance {
+                    Appearance::Light => light,
+                    Appearance::Dark => dark,
+                },
+            },
+        };
 
-//             *theme_to_update = ThemeName(theme_name.into());
-//         } else {
-//             self.theme = Some(ThemeSelection::Static(ThemeName(theme_name.into())));
-//         }
-//     }
+        *theme_to_update = ThemeName(theme_name.into());
+    } else {
+        current.theme.theme = Some(settings::ThemeSelection::Static(ThemeName(
+            theme_name.into(),
+        )));
+    }
+}
 
 //     /// Sets the icon theme for the given appearance to the icon theme with the specified name.
 //     pub fn set_icon_theme(&mut self, icon_theme_name: String, appearance: Appearance) {
@@ -460,56 +466,58 @@ impl IconThemeSelection {
 //         }
 //     }
 
-//     /// Sets the mode for the theme.
-//     pub fn set_mode(&mut self, mode: ThemeMode) {
-//         if let Some(selection) = self.theme.as_mut() {
-//             match selection {
-//                 ThemeSelection::Static(theme) => {
-//                     // If the theme was previously set to a single static theme,
-//                     // we don't know whether it was a light or dark theme, so we
-//                     // just use it for both.
-//                     self.theme = Some(ThemeSelection::Dynamic {
-//                         mode,
-//                         light: theme.clone(),
-//                         dark: theme.clone(),
-//                     });
-//                 }
-//                 ThemeSelection::Dynamic {
-//                     mode: mode_to_update,
-//                     ..
-//                 } => *mode_to_update = mode,
-//             }
-//         } else {
-//             self.theme = Some(ThemeSelection::Dynamic {
-//                 mode,
-//                 light: ThemeName(ThemeSettings::DEFAULT_LIGHT_THEME.into()),
-//                 dark: ThemeName(ThemeSettings::DEFAULT_DARK_THEME.into()),
-//             });
-//         }
+/// Sets the mode for the theme.
+pub fn set_mode(content: &mut SettingsContent, mode: ThemeMode) {
+    let theme = content.theme.as_mut();
 
-//         if let Some(selection) = self.icon_theme.as_mut() {
-//             match selection {
-//                 IconThemeSelection::Static(icon_theme) => {
-//                     // If the icon theme was previously set to a single static
-//                     // theme, we don't know whether it was a light or dark
-//                     // theme, so we just use it for both.
-//                     self.icon_theme = Some(IconThemeSelection::Dynamic {
-//                         mode,
-//                         light: icon_theme.clone(),
-//                         dark: icon_theme.clone(),
-//                     });
-//                 }
-//                 IconThemeSelection::Dynamic {
-//                     mode: mode_to_update,
-//                     ..
-//                 } => *mode_to_update = mode,
-//             }
-//         } else {
-//             self.icon_theme = Some(IconThemeSelection::Static(IconThemeName(
-//                 DEFAULT_ICON_THEME_NAME.into(),
-//             )));
-//         }
-//     }
+    if let Some(selection) = theme.theme.as_mut() {
+        match selection {
+            settings::ThemeSelection::Static(theme) => {
+                // If the theme was previously set to a single static theme,
+                // we don't know whether it was a light or dark theme, so we
+                // just use it for both.
+                *selection = settings::ThemeSelection::Dynamic {
+                    mode,
+                    light: theme.clone(),
+                    dark: theme.clone(),
+                };
+            }
+            settings::ThemeSelection::Dynamic {
+                mode: mode_to_update,
+                ..
+            } => *mode_to_update = mode,
+        }
+    } else {
+        theme.theme = Some(settings::ThemeSelection::Dynamic {
+            mode,
+            light: ThemeName(ThemeSettings::DEFAULT_LIGHT_THEME.into()),
+            dark: ThemeName(ThemeSettings::DEFAULT_DARK_THEME.into()),
+        });
+    }
+
+    if let Some(selection) = theme.icon_theme.as_mut() {
+        match selection {
+            settings::IconThemeSelection::Static(icon_theme) => {
+                // If the icon theme was previously set to a single static
+                // theme, we don't know whether it was a light or dark
+                // theme, so we just use it for both.
+                *selection = settings::IconThemeSelection::Dynamic {
+                    mode,
+                    light: icon_theme.clone(),
+                    dark: icon_theme.clone(),
+                };
+            }
+            settings::IconThemeSelection::Dynamic {
+                mode: mode_to_update,
+                ..
+            } => *mode_to_update = mode,
+        }
+    } else {
+        theme.icon_theme = Some(settings::IconThemeSelection::Static(IconThemeName(
+            DEFAULT_ICON_THEME_NAME.into(),
+        )));
+    }
+}
 // }
 
 /// The buffer's line height.