mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +07:00
This reverts commit a2a7bd139a.
This caused themes to not load correctly on startup, you needed to edit
your settings.
Release Notes:
- N/A
This commit is contained in:
parent
e765818487
commit
41cf114d8a
60 changed files with 423 additions and 360 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -5921,6 +5921,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"gpui",
|
||||
"serde",
|
||||
"settings",
|
||||
"theme",
|
||||
"workspace-hack",
|
||||
"zed-util",
|
||||
|
|
|
|||
|
|
@ -3220,6 +3220,7 @@ mod tests {
|
|||
use settings::{LanguageModelParameters, Settings, SettingsStore};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use theme::ThemeSettings;
|
||||
use util::path;
|
||||
use workspace::Workspace;
|
||||
|
||||
|
|
@ -5280,7 +5281,7 @@ fn main() {{
|
|||
thread_store::init(fs.clone(), cx);
|
||||
workspace::init_settings(cx);
|
||||
language_model::init_settings(cx);
|
||||
theme::init(theme::LoadThemes::JustBase, cx);
|
||||
ThemeSettings::register(cx);
|
||||
ToolRegistry::default_global(cx);
|
||||
assistant_tool::init(cx);
|
||||
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ impl Default for AgentProfileId {
|
|||
}
|
||||
|
||||
impl Settings for AgentSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
let agent = content.agent.clone().unwrap();
|
||||
Self {
|
||||
enabled: agent.enabled.unwrap(),
|
||||
|
|
|
|||
|
|
@ -414,6 +414,7 @@ mod tests {
|
|||
use project::Project;
|
||||
use serde_json::json;
|
||||
use settings::{Settings as _, SettingsStore};
|
||||
use theme::ThemeSettings;
|
||||
use util::path;
|
||||
use workspace::Workspace;
|
||||
|
||||
|
|
@ -543,7 +544,7 @@ mod tests {
|
|||
Project::init_settings(cx);
|
||||
AgentSettings::register(cx);
|
||||
workspace::init_settings(cx);
|
||||
theme::init(theme::LoadThemes::JustBase, cx);
|
||||
ThemeSettings::register(cx);
|
||||
release_channel::init(SemanticVersion::default(), cx);
|
||||
EditorSettings::register(cx);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -6086,7 +6086,7 @@ pub(crate) mod tests {
|
|||
Project::init_settings(cx);
|
||||
AgentSettings::register(cx);
|
||||
workspace::init_settings(cx);
|
||||
theme::init(theme::LoadThemes::JustBase, cx);
|
||||
ThemeSettings::register(cx);
|
||||
release_channel::init(SemanticVersion::default(), cx);
|
||||
EditorSettings::register(cx);
|
||||
prompt_store::init(cx)
|
||||
|
|
|
|||
|
|
@ -1814,6 +1814,7 @@ mod tests {
|
|||
use serde_json::json;
|
||||
use settings::{Settings, SettingsStore};
|
||||
use std::{path::Path, rc::Rc};
|
||||
use theme::ThemeSettings;
|
||||
use util::path;
|
||||
|
||||
#[gpui::test]
|
||||
|
|
@ -1826,7 +1827,7 @@ mod tests {
|
|||
AgentSettings::register(cx);
|
||||
prompt_store::init(cx);
|
||||
workspace::init_settings(cx);
|
||||
theme::init(theme::LoadThemes::JustBase, cx);
|
||||
ThemeSettings::register(cx);
|
||||
EditorSettings::register(cx);
|
||||
language_model::init_settings(cx);
|
||||
});
|
||||
|
|
@ -1978,7 +1979,7 @@ mod tests {
|
|||
AgentSettings::register(cx);
|
||||
prompt_store::init(cx);
|
||||
workspace::init_settings(cx);
|
||||
theme::init(theme::LoadThemes::JustBase, cx);
|
||||
ThemeSettings::register(cx);
|
||||
EditorSettings::register(cx);
|
||||
language_model::init_settings(cx);
|
||||
workspace::register_project_item::<Editor>(cx);
|
||||
|
|
|
|||
|
|
@ -704,6 +704,7 @@ mod tests {
|
|||
use serde_json::json;
|
||||
use settings::{Settings, SettingsStore};
|
||||
use terminal::terminal_settings::TerminalSettings;
|
||||
use theme::ThemeSettings;
|
||||
use util::{ResultExt as _, test::TempTree};
|
||||
|
||||
use super::*;
|
||||
|
|
@ -718,7 +719,7 @@ mod tests {
|
|||
language::init(cx);
|
||||
Project::init_settings(cx);
|
||||
workspace::init_settings(cx);
|
||||
theme::init(theme::LoadThemes::JustBase, cx);
|
||||
ThemeSettings::register(cx);
|
||||
TerminalSettings::register(cx);
|
||||
EditorSettings::register(cx);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ pub struct AudioSettings {
|
|||
|
||||
/// Configuration of audio in Zed
|
||||
impl Settings for AudioSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
let audio = &content.audio.as_ref().unwrap();
|
||||
AudioSettings {
|
||||
rodio_audio: audio.rodio_audio.unwrap(),
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ struct AutoUpdateSetting(bool);
|
|||
///
|
||||
/// Default: true
|
||||
impl Settings for AutoUpdateSetting {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
Self(content.auto_update.unwrap())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use gpui::App;
|
||||
use settings::Settings;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -7,11 +8,17 @@ pub struct CallSettings {
|
|||
}
|
||||
|
||||
impl Settings for CallSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
let call = content.calls.clone().unwrap();
|
||||
CallSettings {
|
||||
mute_on_join: call.mute_on_join.unwrap(),
|
||||
share_on_join: call.share_on_join.unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
fn import_from_vscode(
|
||||
_vscode: &settings::VsCodeSettings,
|
||||
_current: &mut settings::SettingsContent,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ pub struct ClientSettings {
|
|||
}
|
||||
|
||||
impl Settings for ClientSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
if let Some(server_url) = &*ZED_SERVER_URL {
|
||||
return Self {
|
||||
server_url: server_url.clone(),
|
||||
|
|
@ -133,7 +133,7 @@ impl ProxySettings {
|
|||
}
|
||||
|
||||
impl Settings for ProxySettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
Self {
|
||||
proxy: content.proxy.clone(),
|
||||
}
|
||||
|
|
@ -519,7 +519,7 @@ pub struct TelemetrySettings {
|
|||
}
|
||||
|
||||
impl settings::Settings for TelemetrySettings {
|
||||
fn from_settings(content: &SettingsContent) -> Self {
|
||||
fn from_settings(content: &SettingsContent, _cx: &mut App) -> Self {
|
||||
Self {
|
||||
diagnostics: content.telemetry.as_ref().unwrap().diagnostics.unwrap(),
|
||||
metrics: content.telemetry.as_ref().unwrap().metrics.unwrap(),
|
||||
|
|
|
|||
|
|
@ -2041,10 +2041,6 @@ async fn test_mutual_editor_inlay_hint_cache_update(
|
|||
});
|
||||
}
|
||||
|
||||
// This test started hanging on seed 2 after the theme settings
|
||||
// PR. The hypothesis is that it's been buggy for a while, but got lucky
|
||||
// on seeds.
|
||||
#[ignore]
|
||||
#[gpui::test(iterations = 10)]
|
||||
async fn test_inlay_hint_refresh_is_forwarded(
|
||||
cx_a: &mut TestAppContext,
|
||||
|
|
|
|||
|
|
@ -183,10 +183,9 @@ pub async fn run_randomized_test<T: RandomizedTest>(
|
|||
|
||||
for (client, cx) in clients {
|
||||
cx.update(|cx| {
|
||||
let settings = cx.remove_global::<SettingsStore>();
|
||||
let store = cx.remove_global::<SettingsStore>();
|
||||
cx.clear_globals();
|
||||
cx.set_global(settings);
|
||||
theme::init(theme::LoadThemes::JustBase, cx);
|
||||
cx.set_global(store);
|
||||
drop(client);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -172,7 +172,6 @@ impl TestServer {
|
|||
}
|
||||
let settings = SettingsStore::test(cx);
|
||||
cx.set_global(settings);
|
||||
theme::init(theme::LoadThemes::JustBase, cx);
|
||||
release_channel::init(SemanticVersion::default(), cx);
|
||||
client::init_settings(cx);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ pub struct NotificationPanelSettings {
|
|||
}
|
||||
|
||||
impl Settings for CollaborationPanelSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut ui::App) -> Self {
|
||||
let panel = content.collaboration_panel.as_ref().unwrap();
|
||||
|
||||
Self {
|
||||
|
|
@ -30,7 +30,7 @@ impl Settings for CollaborationPanelSettings {
|
|||
}
|
||||
|
||||
impl Settings for NotificationPanelSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut ui::App) -> Self {
|
||||
let panel = content.notification_panel.as_ref().unwrap();
|
||||
return Self {
|
||||
button: panel.button.unwrap(),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use dap_types::SteppingGranularity;
|
||||
use gpui::App;
|
||||
use settings::{Settings, SettingsContent};
|
||||
|
||||
pub struct DebuggerSettings {
|
||||
|
|
@ -33,7 +34,7 @@ pub struct DebuggerSettings {
|
|||
}
|
||||
|
||||
impl Settings for DebuggerSettings {
|
||||
fn from_settings(content: &SettingsContent) -> Self {
|
||||
fn from_settings(content: &SettingsContent, _cx: &mut App) -> Self {
|
||||
let content = content.debugger.clone().unwrap();
|
||||
Self {
|
||||
stepping_granularity: dap_granularity_from_settings(
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ impl ScrollbarVisibility for EditorSettings {
|
|||
}
|
||||
|
||||
impl Settings for EditorSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
let editor = content.editor.clone();
|
||||
let scrollbar = editor.scrollbar.unwrap();
|
||||
let minimap = editor.minimap.unwrap();
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use collections::HashMap;
|
|||
use extension::{
|
||||
DownloadFileCapability, ExtensionCapability, NpmInstallPackageCapability, ProcessExecCapability,
|
||||
};
|
||||
use gpui::App;
|
||||
use settings::Settings;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
|
@ -36,7 +37,7 @@ impl ExtensionSettings {
|
|||
}
|
||||
|
||||
impl Settings for ExtensionSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
Self {
|
||||
auto_install_extensions: content.extension.auto_install_extensions.clone(),
|
||||
auto_update_extensions: content.extension.auto_update_extensions.clone(),
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ pub struct FileFinderSettings {
|
|||
}
|
||||
|
||||
impl Settings for FileFinderSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut ui::App) -> Self {
|
||||
let file_finder = content.file_finder.as_ref().unwrap();
|
||||
|
||||
Self {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ doctest = false
|
|||
[dependencies]
|
||||
gpui.workspace = true
|
||||
serde.workspace = true
|
||||
settings.workspace = true
|
||||
theme.workspace = true
|
||||
util.workspace = true
|
||||
workspace-hack.workspace = true
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ use std::sync::Arc;
|
|||
use std::{path::Path, str};
|
||||
|
||||
use gpui::{App, SharedString};
|
||||
use theme::{GlobalTheme, IconTheme, ThemeRegistry};
|
||||
use settings::Settings;
|
||||
use theme::{IconTheme, ThemeRegistry, ThemeSettings};
|
||||
use util::paths::PathExt;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -12,8 +13,10 @@ pub struct FileIcons {
|
|||
|
||||
impl FileIcons {
|
||||
pub fn get(cx: &App) -> Self {
|
||||
let theme_settings = ThemeSettings::get_global(cx);
|
||||
|
||||
Self {
|
||||
icon_theme: GlobalTheme::icon_theme(cx).clone(),
|
||||
icon_theme: theme_settings.active_icon_theme.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -94,7 +97,7 @@ impl FileIcons {
|
|||
.map(|icon_definition| icon_definition.path.clone())
|
||||
}
|
||||
|
||||
get_icon_for_type(GlobalTheme::icon_theme(cx), typ).or_else(|| {
|
||||
get_icon_for_type(&ThemeSettings::get_global(cx).active_icon_theme, typ).or_else(|| {
|
||||
Self::default_icon_theme(cx).and_then(|icon_theme| get_icon_for_type(&icon_theme, typ))
|
||||
})
|
||||
}
|
||||
|
|
@ -119,16 +122,20 @@ impl FileIcons {
|
|||
}
|
||||
}
|
||||
|
||||
get_folder_icon(GlobalTheme::icon_theme(cx), path, expanded)
|
||||
.or_else(|| {
|
||||
Self::default_icon_theme(cx)
|
||||
.and_then(|icon_theme| get_folder_icon(&icon_theme, path, expanded))
|
||||
})
|
||||
.or_else(|| {
|
||||
// If we can't find a specific folder icon for the folder at the given path, fall back to the generic folder
|
||||
// icon.
|
||||
Self::get_generic_folder_icon(expanded, cx)
|
||||
})
|
||||
get_folder_icon(
|
||||
&ThemeSettings::get_global(cx).active_icon_theme,
|
||||
path,
|
||||
expanded,
|
||||
)
|
||||
.or_else(|| {
|
||||
Self::default_icon_theme(cx)
|
||||
.and_then(|icon_theme| get_folder_icon(&icon_theme, path, expanded))
|
||||
})
|
||||
.or_else(|| {
|
||||
// If we can't find a specific folder icon for the folder at the given path, fall back to the generic folder
|
||||
// icon.
|
||||
Self::get_generic_folder_icon(expanded, cx)
|
||||
})
|
||||
}
|
||||
|
||||
fn get_generic_folder_icon(expanded: bool, cx: &App) -> Option<SharedString> {
|
||||
|
|
@ -143,10 +150,12 @@ impl FileIcons {
|
|||
}
|
||||
}
|
||||
|
||||
get_generic_folder_icon(GlobalTheme::icon_theme(cx), expanded).or_else(|| {
|
||||
Self::default_icon_theme(cx)
|
||||
.and_then(|icon_theme| get_generic_folder_icon(&icon_theme, expanded))
|
||||
})
|
||||
get_generic_folder_icon(&ThemeSettings::get_global(cx).active_icon_theme, expanded).or_else(
|
||||
|| {
|
||||
Self::default_icon_theme(cx)
|
||||
.and_then(|icon_theme| get_generic_folder_icon(&icon_theme, expanded))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_chevron_icon(expanded: bool, cx: &App) -> Option<SharedString> {
|
||||
|
|
@ -158,7 +167,7 @@ impl FileIcons {
|
|||
}
|
||||
}
|
||||
|
||||
get_chevron_icon(GlobalTheme::icon_theme(cx), expanded).or_else(|| {
|
||||
get_chevron_icon(&ThemeSettings::get_global(cx).active_icon_theme, expanded).or_else(|| {
|
||||
Self::default_icon_theme(cx)
|
||||
.and_then(|icon_theme| get_chevron_icon(&icon_theme, expanded))
|
||||
})
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ pub struct GitHostingProviderSettings {
|
|||
}
|
||||
|
||||
impl Settings for GitHostingProviderSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
Self {
|
||||
git_hosting_providers: content
|
||||
.project
|
||||
|
|
|
|||
|
|
@ -360,7 +360,7 @@ mod tests {
|
|||
use editor::test::editor_test_context::assert_state_with_diff;
|
||||
use gpui::TestAppContext;
|
||||
use project::{FakeFs, Fs, Project};
|
||||
use settings::SettingsStore;
|
||||
use settings::{Settings, SettingsStore};
|
||||
use std::path::PathBuf;
|
||||
use unindent::unindent;
|
||||
use util::path;
|
||||
|
|
@ -374,7 +374,7 @@ mod tests {
|
|||
Project::init_settings(cx);
|
||||
workspace::init_settings(cx);
|
||||
editor::init_settings(cx);
|
||||
theme::init(theme::LoadThemes::JustBase, cx);
|
||||
theme::ThemeSettings::register(cx)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ impl ScrollbarVisibility for GitPanelSettings {
|
|||
}
|
||||
|
||||
impl Settings for GitPanelSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut ui::App) -> Self {
|
||||
let git_panel = content.git_panel.clone().unwrap();
|
||||
Self {
|
||||
button: git_panel.button.unwrap(),
|
||||
|
|
|
|||
|
|
@ -450,7 +450,7 @@ mod tests {
|
|||
use gpui::{TestAppContext, VisualContext};
|
||||
use project::{FakeFs, Project};
|
||||
use serde_json::json;
|
||||
use settings::SettingsStore;
|
||||
use settings::{Settings, SettingsStore};
|
||||
use unindent::unindent;
|
||||
use util::{path, test::marked_text_ranges};
|
||||
|
||||
|
|
@ -462,7 +462,7 @@ mod tests {
|
|||
Project::init_settings(cx);
|
||||
workspace::init_settings(cx);
|
||||
editor::init_settings(cx);
|
||||
theme::init(theme::LoadThemes::JustBase, cx);
|
||||
theme::ThemeSettings::register(cx)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ impl From<settings::LineIndicatorFormat> for LineIndicatorFormat {
|
|||
}
|
||||
|
||||
impl Settings for LineIndicatorFormat {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
content.line_indicator_format.unwrap().into()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use gpui::App;
|
||||
pub use settings::ImageFileSizeUnit;
|
||||
use settings::Settings;
|
||||
|
||||
|
|
@ -11,7 +12,7 @@ pub struct ImageViewerSettings {
|
|||
}
|
||||
|
||||
impl Settings for ImageViewerSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
Self {
|
||||
unit: content.image_viewer.clone().unwrap().unit.unwrap(),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ pub struct JournalSettings {
|
|||
}
|
||||
|
||||
impl settings::Settings for JournalSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
let journal = content.journal.clone().unwrap();
|
||||
|
||||
Self {
|
||||
|
|
|
|||
|
|
@ -500,7 +500,7 @@ fn merge_with_editorconfig(settings: &mut LanguageSettings, cfg: &EditorconfigPr
|
|||
}
|
||||
|
||||
impl settings::Settings for AllLanguageSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
let all_languages = &content.project.all_languages;
|
||||
|
||||
fn load_from_content(settings: LanguageSettingsContent) -> LanguageSettings {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ pub struct AllLanguageModelSettings {
|
|||
impl settings::Settings for AllLanguageModelSettings {
|
||||
const PRESERVED_KEYS: Option<&'static [&'static str]> = Some(&["version"]);
|
||||
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
let language_models = content.language_models.clone().unwrap();
|
||||
let anthropic = language_models.anthropic.unwrap();
|
||||
let bedrock = language_models.bedrock.unwrap();
|
||||
|
|
|
|||
|
|
@ -34,8 +34,16 @@ fn get_theme_family_themes(theme_name: &str) -> Option<(&'static str, &'static s
|
|||
}
|
||||
|
||||
fn render_theme_section(tab_index: &mut isize, cx: &mut App) -> impl IntoElement {
|
||||
let theme_selection = ThemeSettings::get_global(cx).theme.clone();
|
||||
let theme_selection = ThemeSettings::get_global(cx).theme_selection.clone();
|
||||
let system_appearance = theme::SystemAppearance::global(cx);
|
||||
let theme_selection = theme_selection.unwrap_or_else(|| ThemeSelection::Dynamic {
|
||||
mode: match *system_appearance {
|
||||
Appearance::Light => ThemeMode::Light,
|
||||
Appearance::Dark => ThemeMode::Dark,
|
||||
},
|
||||
light: ThemeName("One Light".into()),
|
||||
dark: ThemeName("One Dark".into()),
|
||||
});
|
||||
|
||||
let theme_mode = theme_selection
|
||||
.mode()
|
||||
|
|
@ -103,7 +111,7 @@ fn render_theme_section(tab_index: &mut isize, cx: &mut App) -> impl IntoElement
|
|||
ThemeMode::Dark => Appearance::Dark,
|
||||
ThemeMode::System => *system_appearance,
|
||||
};
|
||||
let current_theme_name: SharedString = theme_selection.name(appearance).0.into();
|
||||
let current_theme_name = SharedString::new(theme_selection.theme(appearance));
|
||||
|
||||
let theme_names = match appearance {
|
||||
Appearance::Light => LIGHT_THEMES,
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ impl ScrollbarVisibility for OutlinePanelSettings {
|
|||
}
|
||||
|
||||
impl Settings for OutlinePanelSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
let panel = content.outline_panel.as_ref().unwrap();
|
||||
Self {
|
||||
button: panel.button.unwrap(),
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use feature_flags::FeatureFlagAppExt as _;
|
|||
use fs::{Fs, RemoveOptions, RenameOptions};
|
||||
use futures::StreamExt as _;
|
||||
use gpui::{
|
||||
AppContext as _, AsyncApp, Context, Entity, EventEmitter, SharedString, Subscription, Task,
|
||||
App, AppContext as _, AsyncApp, Context, Entity, EventEmitter, SharedString, Subscription, Task,
|
||||
};
|
||||
use http_client::github::AssetKind;
|
||||
use node_runtime::NodeRuntime;
|
||||
|
|
@ -22,7 +22,7 @@ use remote::RemoteClient;
|
|||
use rpc::{AnyProtoClient, TypedEnvelope, proto};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use settings::SettingsStore;
|
||||
use settings::{SettingsContent, SettingsStore};
|
||||
use util::{ResultExt as _, debug_panic};
|
||||
|
||||
use crate::ProjectEnvironment;
|
||||
|
|
@ -1294,7 +1294,7 @@ impl From<settings::CustomAgentServerSettings> for CustomAgentServerSettings {
|
|||
}
|
||||
|
||||
impl settings::Settings for AllAgentServersSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
let agent_settings = content.agent_servers.clone().unwrap();
|
||||
Self {
|
||||
gemini: agent_settings.gemini.map(Into::into),
|
||||
|
|
@ -1307,4 +1307,6 @@ impl settings::Settings for AllAgentServersSettings {
|
|||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
fn import_from_vscode(_vscode: &settings::VsCodeSettings, _current: &mut SettingsContent) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -980,7 +980,7 @@ pub struct DisableAiSettings {
|
|||
}
|
||||
|
||||
impl settings::Settings for DisableAiSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
Self {
|
||||
disable_ai: content.disable_ai.unwrap().0,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use context_server::ContextServerCommand;
|
|||
use dap::adapters::DebugAdapterName;
|
||||
use fs::Fs;
|
||||
use futures::StreamExt as _;
|
||||
use gpui::{AsyncApp, BorrowAppContext, Context, Entity, EventEmitter, Subscription, Task};
|
||||
use gpui::{App, AsyncApp, BorrowAppContext, Context, Entity, EventEmitter, Subscription, Task};
|
||||
use lsp::LanguageServerName;
|
||||
use paths::{
|
||||
EDITORCONFIG_NAME, local_debug_file_relative_path, local_settings_file_relative_path,
|
||||
|
|
@ -437,7 +437,7 @@ pub struct LspPullDiagnosticsSettings {
|
|||
}
|
||||
|
||||
impl Settings for ProjectSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
let project = &content.project.clone();
|
||||
let diagnostics = content.diagnostics.as_ref().unwrap();
|
||||
let lsp_pull_diagnostics = diagnostics.lsp_pull_diagnostics.as_ref().unwrap();
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ impl ScrollbarVisibility for ProjectPanelSettings {
|
|||
}
|
||||
|
||||
impl Settings for ProjectPanelSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut ui::App) -> Self {
|
||||
let project_panel = content.project_panel.clone().unwrap();
|
||||
Self {
|
||||
button: project_panel.button.unwrap(),
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ impl From<WslConnection> for Connection {
|
|||
}
|
||||
|
||||
impl Settings for SshSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
let remote = &content.remote;
|
||||
Self {
|
||||
ssh_connections: remote.ssh_connections.clone().unwrap_or_default().into(),
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ impl JupyterSettings {
|
|||
}
|
||||
|
||||
impl Settings for JupyterSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
let jupyter = content.editor.jupyter.clone().unwrap();
|
||||
Self {
|
||||
kernel_selections: jupyter.kernel_selections.unwrap_or_default(),
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use gpui::App;
|
||||
use settings::Settings;
|
||||
|
||||
/// Settings for configuring REPL display and behavior.
|
||||
|
|
@ -16,7 +17,7 @@ pub struct ReplSettings {
|
|||
}
|
||||
|
||||
impl Settings for ReplSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
let repl = content.repl.as_ref().unwrap();
|
||||
|
||||
Self {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use crate::{
|
|||
self as settings,
|
||||
settings_content::{BaseKeymapContent, SettingsContent},
|
||||
};
|
||||
use gpui::App;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use settings::{Settings, VsCodeSettings};
|
||||
|
|
@ -130,7 +131,7 @@ impl BaseKeymap {
|
|||
}
|
||||
|
||||
impl Settings for BaseKeymap {
|
||||
fn from_settings(s: &crate::settings_content::SettingsContent) -> Self {
|
||||
fn from_settings(s: &crate::settings_content::SettingsContent, _cx: &mut App) -> Self {
|
||||
s.base_keymap.unwrap().into()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,11 @@ pub trait Settings: 'static + Send + Sync + Sized {
|
|||
///
|
||||
/// This function *should* panic if default values are missing,
|
||||
/// and you should add a default to default.json for documentation.
|
||||
fn from_settings(content: &SettingsContent) -> Self;
|
||||
fn from_settings(content: &SettingsContent, cx: &mut App) -> Self;
|
||||
|
||||
fn missing_default() -> anyhow::Error {
|
||||
anyhow::anyhow!("missing default for: {}", std::any::type_name::<Self>())
|
||||
}
|
||||
|
||||
/// Use [the helpers in the vscode_import module](crate::vscode_import) to apply known
|
||||
/// equivalent settings from a vscode config to our config
|
||||
|
|
@ -78,8 +82,8 @@ pub trait Settings: 'static + Send + Sync + Sized {
|
|||
where
|
||||
Self: Sized,
|
||||
{
|
||||
SettingsStore::update_global(cx, |store, _| {
|
||||
store.register_setting::<Self>();
|
||||
SettingsStore::update_global(cx, |store, cx| {
|
||||
store.register_setting::<Self>(cx);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -201,7 +205,7 @@ struct SettingValue<T> {
|
|||
trait AnySettingValue: 'static + Send + Sync {
|
||||
fn setting_type_name(&self) -> &'static str;
|
||||
|
||||
fn from_settings(&self, s: &SettingsContent) -> Box<dyn Any>;
|
||||
fn from_settings(&self, s: &SettingsContent, cx: &mut App) -> Box<dyn Any>;
|
||||
|
||||
fn value_for_path(&self, path: Option<SettingsLocation>) -> &dyn Any;
|
||||
fn all_local_values(&self) -> Vec<(WorktreeId, Arc<RelPath>, &dyn Any)>;
|
||||
|
|
@ -255,7 +259,7 @@ impl SettingsStore {
|
|||
}
|
||||
|
||||
/// Add a new type of setting to the store.
|
||||
pub fn register_setting<T: Settings>(&mut self) {
|
||||
pub fn register_setting<T: Settings>(&mut self, cx: &mut App) {
|
||||
let setting_type_id = TypeId::of::<T>();
|
||||
let entry = self.setting_values.entry(setting_type_id);
|
||||
|
||||
|
|
@ -267,7 +271,7 @@ impl SettingsStore {
|
|||
global_value: None,
|
||||
local_values: Vec::new(),
|
||||
}));
|
||||
let value = T::from_settings(&self.merged_settings);
|
||||
let value = T::from_settings(&self.merged_settings, cx);
|
||||
setting_value.set_global_value(Box::new(value));
|
||||
}
|
||||
|
||||
|
|
@ -940,7 +944,7 @@ impl SettingsStore {
|
|||
self.merged_settings = Rc::new(merged);
|
||||
|
||||
for setting_value in self.setting_values.values_mut() {
|
||||
let value = setting_value.from_settings(&self.merged_settings);
|
||||
let value = setting_value.from_settings(&self.merged_settings, cx);
|
||||
setting_value.set_global_value(value);
|
||||
}
|
||||
}
|
||||
|
|
@ -977,7 +981,8 @@ impl SettingsStore {
|
|||
}
|
||||
|
||||
for setting_value in self.setting_values.values_mut() {
|
||||
let value = setting_value.from_settings(&project_settings_stack.last().unwrap());
|
||||
let value =
|
||||
setting_value.from_settings(&project_settings_stack.last().unwrap(), cx);
|
||||
setting_value.set_local_value(*root_id, directory_path.clone(), value);
|
||||
}
|
||||
}
|
||||
|
|
@ -1061,8 +1066,8 @@ impl Debug for SettingsStore {
|
|||
}
|
||||
|
||||
impl<T: Settings> AnySettingValue for SettingValue<T> {
|
||||
fn from_settings(&self, s: &SettingsContent) -> Box<dyn Any> {
|
||||
Box::new(T::from_settings(s)) as _
|
||||
fn from_settings(&self, s: &SettingsContent, cx: &mut App) -> Box<dyn Any> {
|
||||
Box::new(T::from_settings(s, cx)) as _
|
||||
}
|
||||
|
||||
fn setting_type_name(&self) -> &'static str {
|
||||
|
|
@ -1133,7 +1138,7 @@ mod tests {
|
|||
}
|
||||
|
||||
impl Settings for AutoUpdateSetting {
|
||||
fn from_settings(content: &SettingsContent) -> Self {
|
||||
fn from_settings(content: &SettingsContent, _: &mut App) -> Self {
|
||||
AutoUpdateSetting {
|
||||
auto_update: content.auto_update.unwrap(),
|
||||
}
|
||||
|
|
@ -1147,7 +1152,7 @@ mod tests {
|
|||
}
|
||||
|
||||
impl Settings for ItemSettings {
|
||||
fn from_settings(content: &SettingsContent) -> Self {
|
||||
fn from_settings(content: &SettingsContent, _: &mut App) -> Self {
|
||||
let content = content.tabs.clone().unwrap();
|
||||
ItemSettings {
|
||||
close_position: content.close_position.unwrap(),
|
||||
|
|
@ -1176,7 +1181,7 @@ mod tests {
|
|||
}
|
||||
|
||||
impl Settings for DefaultLanguageSettings {
|
||||
fn from_settings(content: &SettingsContent) -> Self {
|
||||
fn from_settings(content: &SettingsContent, _: &mut App) -> Self {
|
||||
let content = &content.project.all_languages.defaults;
|
||||
DefaultLanguageSettings {
|
||||
tab_size: content.tab_size.unwrap(),
|
||||
|
|
@ -1200,9 +1205,9 @@ mod tests {
|
|||
#[gpui::test]
|
||||
fn test_settings_store_basic(cx: &mut App) {
|
||||
let mut store = SettingsStore::new(cx, &default_settings());
|
||||
store.register_setting::<AutoUpdateSetting>();
|
||||
store.register_setting::<ItemSettings>();
|
||||
store.register_setting::<DefaultLanguageSettings>();
|
||||
store.register_setting::<AutoUpdateSetting>(cx);
|
||||
store.register_setting::<ItemSettings>(cx);
|
||||
store.register_setting::<DefaultLanguageSettings>(cx);
|
||||
|
||||
assert_eq!(
|
||||
store.get::<AutoUpdateSetting>(None),
|
||||
|
|
@ -1308,7 +1313,7 @@ mod tests {
|
|||
store
|
||||
.set_user_settings(r#"{ "auto_update": false }"#, cx)
|
||||
.unwrap();
|
||||
store.register_setting::<AutoUpdateSetting>();
|
||||
store.register_setting::<AutoUpdateSetting>(cx);
|
||||
|
||||
assert_eq!(
|
||||
store.get::<AutoUpdateSetting>(None),
|
||||
|
|
@ -1516,9 +1521,9 @@ mod tests {
|
|||
#[gpui::test]
|
||||
fn test_vscode_import(cx: &mut App) {
|
||||
let mut store = SettingsStore::new(cx, &test_settings());
|
||||
store.register_setting::<DefaultLanguageSettings>();
|
||||
store.register_setting::<ItemSettings>();
|
||||
store.register_setting::<AutoUpdateSetting>();
|
||||
store.register_setting::<DefaultLanguageSettings>(cx);
|
||||
store.register_setting::<ItemSettings>(cx);
|
||||
store.register_setting::<AutoUpdateSetting>(cx);
|
||||
|
||||
// create settings that werent present
|
||||
check_vscode_import(
|
||||
|
|
@ -1637,7 +1642,7 @@ mod tests {
|
|||
#[gpui::test]
|
||||
fn test_global_settings(cx: &mut App) {
|
||||
let mut store = SettingsStore::new(cx, &test_settings());
|
||||
store.register_setting::<ItemSettings>();
|
||||
store.register_setting::<ItemSettings>(cx);
|
||||
|
||||
// Set global settings - these should override defaults but not user settings
|
||||
store
|
||||
|
|
@ -1686,7 +1691,7 @@ mod tests {
|
|||
#[gpui::test]
|
||||
fn test_get_value_for_field_basic(cx: &mut App) {
|
||||
let mut store = SettingsStore::new(cx, &test_settings());
|
||||
store.register_setting::<DefaultLanguageSettings>();
|
||||
store.register_setting::<DefaultLanguageSettings>(cx);
|
||||
|
||||
store
|
||||
.set_user_settings(r#"{"preferred_line_length": 0}"#, cx)
|
||||
|
|
@ -1743,8 +1748,8 @@ mod tests {
|
|||
#[gpui::test]
|
||||
fn test_get_value_for_field_local_worktrees_dont_interfere(cx: &mut App) {
|
||||
let mut store = SettingsStore::new(cx, &test_settings());
|
||||
store.register_setting::<DefaultLanguageSettings>();
|
||||
store.register_setting::<AutoUpdateSetting>();
|
||||
store.register_setting::<DefaultLanguageSettings>(cx);
|
||||
store.register_setting::<AutoUpdateSetting>(cx);
|
||||
|
||||
let local_1 = (WorktreeId::from_usize(0), RelPath::empty().into_arc());
|
||||
|
||||
|
|
@ -1872,7 +1877,7 @@ mod tests {
|
|||
#[gpui::test]
|
||||
fn test_get_overrides_for_field(cx: &mut App) {
|
||||
let mut store = SettingsStore::new(cx, &test_settings());
|
||||
store.register_setting::<DefaultLanguageSettings>();
|
||||
store.register_setting::<DefaultLanguageSettings>(cx);
|
||||
|
||||
let wt0_root = (WorktreeId::from_usize(0), RelPath::empty().into_arc());
|
||||
let wt0_child1 = (WorktreeId::from_usize(0), rel_path("child1").into_arc());
|
||||
|
|
|
|||
|
|
@ -302,6 +302,7 @@ mod tests {
|
|||
cx.set_global(settings_store);
|
||||
settings::init(cx);
|
||||
theme::init(theme::LoadThemes::JustBase, cx);
|
||||
ThemeSettings::register(cx);
|
||||
client::init_settings(cx);
|
||||
language::init(cx);
|
||||
super::init(cx);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use reqwest_client::ReqwestClient;
|
|||
use settings::{KeymapFile, Settings};
|
||||
use simplelog::SimpleLogger;
|
||||
use strum::IntoEnumIterator;
|
||||
use theme::ThemeSettings;
|
||||
use theme::{ThemeRegistry, ThemeSettings};
|
||||
use ui::prelude::*;
|
||||
use workspace;
|
||||
|
||||
|
|
@ -80,9 +80,9 @@ fn main() {
|
|||
|
||||
let selector = story_selector;
|
||||
|
||||
let theme_registry = ThemeRegistry::global(cx);
|
||||
let mut theme_settings = ThemeSettings::get_global(cx).clone();
|
||||
theme_settings.theme =
|
||||
theme::ThemeSelection::Static(settings::ThemeName(theme_name.into()));
|
||||
theme_settings.active_theme = theme_registry.get(&theme_name).unwrap();
|
||||
ThemeSettings::override_global(theme_settings, cx);
|
||||
|
||||
language::init(cx);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use alacritty_terminal::vte::ansi::{
|
|||
CursorShape as AlacCursorShape, CursorStyle as AlacCursorStyle,
|
||||
};
|
||||
use collections::HashMap;
|
||||
use gpui::{FontFallbacks, FontFeatures, FontWeight, Pixels, px};
|
||||
use gpui::{App, FontFallbacks, FontFeatures, FontWeight, Pixels, px};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ fn settings_shell_to_task_shell(shell: settings::Shell) -> Shell {
|
|||
}
|
||||
|
||||
impl settings::Settings for TerminalSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
let content = content.terminal.clone().unwrap();
|
||||
TerminalSettings {
|
||||
shell: settings_shell_to_task_shell(content.shell.unwrap()),
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ use std::sync::Arc;
|
|||
use gpui::{FontStyle, FontWeight, HighlightStyle, Hsla, WindowBackgroundAppearance, hsla};
|
||||
|
||||
use crate::{
|
||||
AccentColors, Appearance, DEFAULT_DARK_THEME, PlayerColors, StatusColors,
|
||||
StatusColorsRefinement, SyntaxTheme, SystemColors, Theme, ThemeColors, ThemeColorsRefinement,
|
||||
ThemeFamily, ThemeStyles, default_color_scales,
|
||||
AccentColors, Appearance, PlayerColors, StatusColors, StatusColorsRefinement, SyntaxTheme,
|
||||
SystemColors, Theme, ThemeColors, ThemeColorsRefinement, ThemeFamily, ThemeStyles,
|
||||
default_color_scales,
|
||||
};
|
||||
|
||||
/// The default theme family for Zed.
|
||||
|
|
@ -92,7 +92,7 @@ pub(crate) fn zed_default_dark() -> Theme {
|
|||
let player = PlayerColors::dark();
|
||||
Theme {
|
||||
id: "one_dark".to_string(),
|
||||
name: DEFAULT_DARK_THEME.into(),
|
||||
name: "One Dark".into(),
|
||||
appearance: Appearance::Dark,
|
||||
styles: ThemeStyles {
|
||||
window_background_appearance: WindowBackgroundAppearance::Opaque,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
use crate::fallback_themes::zed_default_dark;
|
||||
use crate::{
|
||||
Appearance, DEFAULT_ICON_THEME_NAME, SyntaxTheme, Theme, status_colors_refinement,
|
||||
syntax_overrides, theme_colors_refinement,
|
||||
Appearance, DEFAULT_ICON_THEME_NAME, IconTheme, IconThemeNotFoundError, SyntaxTheme, Theme,
|
||||
ThemeNotFoundError, ThemeRegistry, status_colors_refinement, syntax_overrides,
|
||||
theme_colors_refinement,
|
||||
};
|
||||
use collections::HashMap;
|
||||
use derive_more::{Deref, DerefMut};
|
||||
|
|
@ -14,6 +16,7 @@ use serde::{Deserialize, Serialize};
|
|||
pub use settings::{FontFamilyName, IconThemeName, ThemeMode, ThemeName};
|
||||
use settings::{Settings, SettingsContent};
|
||||
use std::sync::Arc;
|
||||
use util::ResultExt as _;
|
||||
|
||||
const MIN_FONT_SIZE: Pixels = px(6.0);
|
||||
const MAX_FONT_SIZE: Pixels = px(100.0);
|
||||
|
|
@ -122,7 +125,9 @@ pub struct ThemeSettings {
|
|||
/// The terminal font family can be overridden using it's own setting.
|
||||
pub buffer_line_height: BufferLineHeight,
|
||||
/// The current theme selection.
|
||||
pub theme: ThemeSelection,
|
||||
pub theme_selection: Option<ThemeSelection>,
|
||||
/// The active theme.
|
||||
pub active_theme: Arc<Theme>,
|
||||
/// Manual overrides for the active theme.
|
||||
///
|
||||
/// Note: This setting is still experimental. See [this tracking issue](https://github.com/zed-industries/zed/issues/18078)
|
||||
|
|
@ -130,7 +135,9 @@ pub struct ThemeSettings {
|
|||
/// Manual overrides per theme
|
||||
pub theme_overrides: HashMap<String, settings::ThemeStyleContent>,
|
||||
/// The current icon theme selection.
|
||||
pub icon_theme: IconThemeSelection,
|
||||
pub icon_theme_selection: Option<IconThemeSelection>,
|
||||
/// The active icon theme.
|
||||
pub active_icon_theme: Arc<IconTheme>,
|
||||
/// The density of the UI.
|
||||
/// Note: This setting is still experimental. See [this tracking issue](
|
||||
pub ui_density: UiDensity,
|
||||
|
|
@ -138,14 +145,73 @@ pub struct ThemeSettings {
|
|||
pub unnecessary_code_fade: f32,
|
||||
}
|
||||
|
||||
pub(crate) const DEFAULT_LIGHT_THEME: &'static str = "One Light";
|
||||
pub(crate) const DEFAULT_DARK_THEME: &'static str = "One Dark";
|
||||
impl ThemeSettings {
|
||||
const DEFAULT_LIGHT_THEME: &'static str = "One Light";
|
||||
const DEFAULT_DARK_THEME: &'static str = "One Dark";
|
||||
|
||||
/// Returns the name of the default theme for the given [`Appearance`].
|
||||
pub fn default_theme(appearance: Appearance) -> &'static str {
|
||||
match appearance {
|
||||
Appearance::Light => DEFAULT_LIGHT_THEME,
|
||||
Appearance::Dark => DEFAULT_DARK_THEME,
|
||||
/// Returns the name of the default theme for the given [`Appearance`].
|
||||
pub fn default_theme(appearance: Appearance) -> &'static str {
|
||||
match appearance {
|
||||
Appearance::Light => Self::DEFAULT_LIGHT_THEME,
|
||||
Appearance::Dark => Self::DEFAULT_DARK_THEME,
|
||||
}
|
||||
}
|
||||
|
||||
/// Reloads the current theme.
|
||||
///
|
||||
/// Reads the [`ThemeSettings`] to know which theme should be loaded,
|
||||
/// taking into account the current [`SystemAppearance`].
|
||||
pub fn reload_current_theme(cx: &mut App) {
|
||||
let mut theme_settings = ThemeSettings::get_global(cx).clone();
|
||||
let system_appearance = SystemAppearance::global(cx);
|
||||
|
||||
if let Some(theme_selection) = theme_settings.theme_selection.clone() {
|
||||
let mut theme_name = theme_selection.theme(*system_appearance);
|
||||
|
||||
// If the selected theme doesn't exist, fall back to a default theme
|
||||
// based on the system appearance.
|
||||
let theme_registry = ThemeRegistry::global(cx);
|
||||
if let Err(err @ ThemeNotFoundError(_)) = theme_registry.get(theme_name) {
|
||||
if theme_registry.extensions_loaded() {
|
||||
log::error!("{err}");
|
||||
}
|
||||
|
||||
theme_name = Self::default_theme(*system_appearance);
|
||||
};
|
||||
|
||||
if let Some(_theme) = theme_settings.switch_theme(theme_name, cx) {
|
||||
ThemeSettings::override_global(theme_settings, cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Reloads the current icon theme.
|
||||
///
|
||||
/// Reads the [`ThemeSettings`] to know which icon theme should be loaded,
|
||||
/// taking into account the current [`SystemAppearance`].
|
||||
pub fn reload_current_icon_theme(cx: &mut App) {
|
||||
let mut theme_settings = ThemeSettings::get_global(cx).clone();
|
||||
let system_appearance = SystemAppearance::global(cx);
|
||||
|
||||
if let Some(icon_theme_selection) = theme_settings.icon_theme_selection.clone() {
|
||||
let mut icon_theme_name = icon_theme_selection.icon_theme(*system_appearance);
|
||||
|
||||
// If the selected icon theme doesn't exist, fall back to the default theme.
|
||||
let theme_registry = ThemeRegistry::global(cx);
|
||||
if let Err(err @ IconThemeNotFoundError(_)) =
|
||||
theme_registry.get_icon_theme(icon_theme_name)
|
||||
{
|
||||
if theme_registry.extensions_loaded() {
|
||||
log::error!("{err}");
|
||||
}
|
||||
|
||||
icon_theme_name = DEFAULT_ICON_THEME_NAME;
|
||||
};
|
||||
|
||||
if let Some(_theme) = theme_settings.switch_icon_theme(icon_theme_name, cx) {
|
||||
ThemeSettings::override_global(theme_settings, cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -171,6 +237,13 @@ impl SystemAppearance {
|
|||
GlobalSystemAppearance(SystemAppearance(cx.window_appearance().into()));
|
||||
}
|
||||
|
||||
/// Returns the global [`SystemAppearance`].
|
||||
///
|
||||
/// Inserts a default [`SystemAppearance`] if one does not yet exist.
|
||||
pub(crate) fn default_global(cx: &mut App) -> Self {
|
||||
cx.default_global::<GlobalSystemAppearance>().0
|
||||
}
|
||||
|
||||
/// Returns the global [`SystemAppearance`].
|
||||
pub fn global(cx: &App) -> Self {
|
||||
cx.global::<GlobalSystemAppearance>().0
|
||||
|
|
@ -229,15 +302,15 @@ impl From<settings::ThemeSelection> for ThemeSelection {
|
|||
|
||||
impl ThemeSelection {
|
||||
/// Returns the theme name for the selected [ThemeMode].
|
||||
pub fn name(&self, system_appearance: Appearance) -> ThemeName {
|
||||
pub fn theme(&self, system_appearance: Appearance) -> &str {
|
||||
match self {
|
||||
Self::Static(theme) => theme.clone(),
|
||||
Self::Static(theme) => &theme.0,
|
||||
Self::Dynamic { mode, light, dark } => match mode {
|
||||
ThemeMode::Light => light.clone(),
|
||||
ThemeMode::Dark => dark.clone(),
|
||||
ThemeMode::Light => &light.0,
|
||||
ThemeMode::Dark => &dark.0,
|
||||
ThemeMode::System => match system_appearance {
|
||||
Appearance::Light => light.clone(),
|
||||
Appearance::Dark => dark.clone(),
|
||||
Appearance::Light => &light.0,
|
||||
Appearance::Dark => &dark.0,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -281,15 +354,15 @@ impl From<settings::IconThemeSelection> for IconThemeSelection {
|
|||
|
||||
impl IconThemeSelection {
|
||||
/// Returns the icon theme name based on the given [`Appearance`].
|
||||
pub fn name(&self, system_appearance: Appearance) -> IconThemeName {
|
||||
pub fn icon_theme(&self, system_appearance: Appearance) -> &str {
|
||||
match self {
|
||||
Self::Static(theme) => theme.clone(),
|
||||
Self::Static(theme) => &theme.0,
|
||||
Self::Dynamic { mode, light, dark } => match mode {
|
||||
ThemeMode::Light => light.clone(),
|
||||
ThemeMode::Dark => dark.clone(),
|
||||
ThemeMode::Light => &light.0,
|
||||
ThemeMode::Dark => &dark.0,
|
||||
ThemeMode::System => match system_appearance {
|
||||
Appearance::Light => light.clone(),
|
||||
Appearance::Dark => dark.clone(),
|
||||
Appearance::Light => &light.0,
|
||||
Appearance::Dark => &dark.0,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -335,7 +408,7 @@ pub fn set_theme(
|
|||
/// Sets the icon theme for the given appearance to the icon theme with the specified name.
|
||||
pub fn set_icon_theme(
|
||||
current: &mut SettingsContent,
|
||||
icon_theme_name: IconThemeName,
|
||||
icon_theme_name: String,
|
||||
appearance: Appearance,
|
||||
) {
|
||||
if let Some(selection) = current.theme.icon_theme.as_mut() {
|
||||
|
|
@ -351,9 +424,11 @@ pub fn set_icon_theme(
|
|||
},
|
||||
};
|
||||
|
||||
*icon_theme_to_update = icon_theme_name;
|
||||
*icon_theme_to_update = IconThemeName(icon_theme_name.into());
|
||||
} else {
|
||||
current.theme.icon_theme = Some(settings::IconThemeSelection::Static(icon_theme_name));
|
||||
current.theme.icon_theme = Some(settings::IconThemeSelection::Static(IconThemeName(
|
||||
icon_theme_name.into(),
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -381,8 +456,8 @@ pub fn set_mode(content: &mut SettingsContent, mode: ThemeMode) {
|
|||
} else {
|
||||
theme.theme = Some(settings::ThemeSelection::Dynamic {
|
||||
mode,
|
||||
light: ThemeName(DEFAULT_LIGHT_THEME.into()),
|
||||
dark: ThemeName(DEFAULT_DARK_THEME.into()),
|
||||
light: ThemeName(ThemeSettings::DEFAULT_LIGHT_THEME.into()),
|
||||
dark: ThemeName(ThemeSettings::DEFAULT_DARK_THEME.into()),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -521,22 +596,44 @@ impl ThemeSettings {
|
|||
f32::max(self.buffer_line_height.value(), MIN_LINE_HEIGHT)
|
||||
}
|
||||
|
||||
/// Switches to the theme with the given name, if it exists.
|
||||
///
|
||||
/// Returns a `Some` containing the new theme if it was successful.
|
||||
/// Returns `None` otherwise.
|
||||
pub fn switch_theme(&mut self, theme: &str, cx: &mut App) -> Option<Arc<Theme>> {
|
||||
let themes = ThemeRegistry::default_global(cx);
|
||||
|
||||
let mut new_theme = None;
|
||||
|
||||
match themes.get(theme) {
|
||||
Ok(theme) => {
|
||||
self.active_theme = theme.clone();
|
||||
new_theme = Some(theme);
|
||||
}
|
||||
Err(err @ ThemeNotFoundError(_)) => {
|
||||
log::error!("{err}");
|
||||
}
|
||||
}
|
||||
|
||||
self.apply_theme_overrides();
|
||||
|
||||
new_theme
|
||||
}
|
||||
|
||||
/// Applies the theme overrides, if there are any, to the current theme.
|
||||
pub fn apply_theme_overrides(&self, mut arc_theme: Arc<Theme>) -> Arc<Theme> {
|
||||
pub fn apply_theme_overrides(&mut self) {
|
||||
// Apply the old overrides setting first, so that the new setting can override those.
|
||||
if let Some(experimental_theme_overrides) = &self.experimental_theme_overrides {
|
||||
let mut theme = (*arc_theme).clone();
|
||||
let mut theme = (*self.active_theme).clone();
|
||||
ThemeSettings::modify_theme(&mut theme, experimental_theme_overrides);
|
||||
arc_theme = Arc::new(theme);
|
||||
self.active_theme = Arc::new(theme);
|
||||
}
|
||||
|
||||
if let Some(theme_overrides) = self.theme_overrides.get(arc_theme.name.as_ref()) {
|
||||
let mut theme = (*arc_theme).clone();
|
||||
if let Some(theme_overrides) = self.theme_overrides.get(self.active_theme.name.as_ref()) {
|
||||
let mut theme = (*self.active_theme).clone();
|
||||
ThemeSettings::modify_theme(&mut theme, theme_overrides);
|
||||
arc_theme = Arc::new(theme);
|
||||
self.active_theme = Arc::new(theme);
|
||||
}
|
||||
|
||||
arc_theme
|
||||
}
|
||||
|
||||
fn modify_theme(base_theme: &mut Theme, theme_overrides: &settings::ThemeStyleContent) {
|
||||
|
|
@ -557,6 +654,24 @@ impl ThemeSettings {
|
|||
syntax_overrides(&theme_overrides),
|
||||
);
|
||||
}
|
||||
|
||||
/// Switches to the icon theme with the given name, if it exists.
|
||||
///
|
||||
/// Returns a `Some` containing the new icon theme if it was successful.
|
||||
/// Returns `None` otherwise.
|
||||
pub fn switch_icon_theme(&mut self, icon_theme: &str, cx: &mut App) -> Option<Arc<IconTheme>> {
|
||||
let themes = ThemeRegistry::default_global(cx);
|
||||
|
||||
let mut new_icon_theme = None;
|
||||
|
||||
if let Some(icon_theme) = themes.get_icon_theme(icon_theme).log_err() {
|
||||
self.active_icon_theme = icon_theme.clone();
|
||||
new_icon_theme = Some(icon_theme);
|
||||
cx.refresh_windows();
|
||||
}
|
||||
|
||||
new_icon_theme
|
||||
}
|
||||
}
|
||||
|
||||
/// Observe changes to the adjusted buffer font size.
|
||||
|
|
@ -689,11 +804,14 @@ pub fn font_fallbacks_from_settings(
|
|||
}
|
||||
|
||||
impl settings::Settings for ThemeSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, cx: &mut App) -> Self {
|
||||
let content = &content.theme;
|
||||
// todo(settings_refactor). This should *not* require cx...
|
||||
let themes = ThemeRegistry::default_global(cx);
|
||||
let system_appearance = SystemAppearance::default_global(cx);
|
||||
let theme_selection: ThemeSelection = content.theme.clone().unwrap().into();
|
||||
let icon_theme_selection: IconThemeSelection = content.icon_theme.clone().unwrap().into();
|
||||
Self {
|
||||
let mut this = Self {
|
||||
ui_font_size: clamp_font_size(content.ui_font_size.unwrap().into()),
|
||||
ui_font: Font {
|
||||
family: content.ui_font_family.as_ref().unwrap().0.clone().into(),
|
||||
|
|
@ -719,13 +837,23 @@ impl settings::Settings for ThemeSettings {
|
|||
buffer_line_height: content.buffer_line_height.unwrap().into(),
|
||||
agent_ui_font_size: content.agent_ui_font_size.map(Into::into),
|
||||
agent_buffer_font_size: content.agent_buffer_font_size.map(Into::into),
|
||||
theme: theme_selection,
|
||||
active_theme: themes
|
||||
.get(theme_selection.theme(*system_appearance))
|
||||
.or(themes.get(&zed_default_dark().name))
|
||||
.unwrap(),
|
||||
theme_selection: Some(theme_selection),
|
||||
experimental_theme_overrides: content.experimental_theme_overrides.clone(),
|
||||
theme_overrides: content.theme_overrides.clone(),
|
||||
icon_theme: icon_theme_selection,
|
||||
active_icon_theme: themes
|
||||
.get_icon_theme(icon_theme_selection.icon_theme(*system_appearance))
|
||||
.or_else(|_| themes.default_icon_theme())
|
||||
.unwrap(),
|
||||
icon_theme_selection: Some(icon_theme_selection),
|
||||
ui_density: content.ui_density.unwrap_or_default().into(),
|
||||
unnecessary_code_fade: content.unnecessary_code_fade.unwrap().0.clamp(0.0, 0.9),
|
||||
}
|
||||
};
|
||||
this.apply_theme_overrides();
|
||||
this
|
||||
}
|
||||
|
||||
fn import_from_vscode(vscode: &settings::VsCodeSettings, current: &mut SettingsContent) {
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@ use ::settings::SettingsStore;
|
|||
use anyhow::Result;
|
||||
use fallback_themes::apply_status_color_defaults;
|
||||
use fs::Fs;
|
||||
use gpui::BorrowAppContext;
|
||||
use gpui::Global;
|
||||
use gpui::{
|
||||
App, AssetSource, HighlightStyle, Hsla, Pixels, Refineable, SharedString, WindowAppearance,
|
||||
WindowBackgroundAppearance, px,
|
||||
|
|
@ -97,7 +95,6 @@ pub enum LoadThemes {
|
|||
|
||||
/// Initialize the theme system.
|
||||
pub fn init(themes_to_load: LoadThemes, cx: &mut App) {
|
||||
SystemAppearance::init(cx);
|
||||
let (assets, load_user_themes) = match themes_to_load {
|
||||
LoadThemes::JustBase => (Box::new(()) as Box<dyn AssetSource>, false),
|
||||
LoadThemes::All(assets) => (assets, true),
|
||||
|
|
@ -111,67 +108,40 @@ pub fn init(themes_to_load: LoadThemes, cx: &mut App) {
|
|||
ThemeSettings::register(cx);
|
||||
FontFamilyCache::init_global(cx);
|
||||
|
||||
let theme = GlobalTheme::configured_theme(cx);
|
||||
let icon_theme = GlobalTheme::configured_icon_theme(cx);
|
||||
cx.set_global(GlobalTheme { theme, icon_theme });
|
||||
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
|
||||
let mut prev_buffer_font_size_settings = settings.buffer_font_size_settings();
|
||||
let mut prev_ui_font_size_settings = settings.ui_font_size_settings();
|
||||
let mut prev_agent_ui_font_size_settings = settings.agent_ui_font_size_settings();
|
||||
let mut prev_agent_buffer_font_size_settings = settings.agent_buffer_font_size_settings();
|
||||
let mut prev_theme_name = settings.theme.name(SystemAppearance::global(cx).0);
|
||||
let mut prev_icon_theme_name = settings.icon_theme.name(SystemAppearance::global(cx).0);
|
||||
let mut prev_theme_overrides = (
|
||||
settings.experimental_theme_overrides.clone(),
|
||||
settings.theme_overrides.clone(),
|
||||
);
|
||||
let mut prev_buffer_font_size_settings =
|
||||
ThemeSettings::get_global(cx).buffer_font_size_settings();
|
||||
let mut prev_ui_font_size_settings = ThemeSettings::get_global(cx).ui_font_size_settings();
|
||||
let mut prev_agent_ui_font_size_settings =
|
||||
ThemeSettings::get_global(cx).agent_ui_font_size_settings();
|
||||
let mut prev_agent_buffer_font_size_settings =
|
||||
ThemeSettings::get_global(cx).agent_buffer_font_size_settings();
|
||||
|
||||
cx.observe_global::<SettingsStore>(move |cx| {
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
|
||||
let buffer_font_size_settings = settings.buffer_font_size_settings();
|
||||
let ui_font_size_settings = settings.ui_font_size_settings();
|
||||
let agent_ui_font_size_settings = settings.agent_ui_font_size_settings();
|
||||
let agent_buffer_font_size_settings = settings.agent_buffer_font_size_settings();
|
||||
let theme_name = settings.theme.name(SystemAppearance::global(cx).0);
|
||||
let icon_theme_name = settings.icon_theme.name(SystemAppearance::global(cx).0);
|
||||
let theme_overrides = (
|
||||
settings.experimental_theme_overrides.clone(),
|
||||
settings.theme_overrides.clone(),
|
||||
);
|
||||
|
||||
let buffer_font_size_settings = ThemeSettings::get_global(cx).buffer_font_size_settings();
|
||||
if buffer_font_size_settings != prev_buffer_font_size_settings {
|
||||
prev_buffer_font_size_settings = buffer_font_size_settings;
|
||||
reset_buffer_font_size(cx);
|
||||
}
|
||||
|
||||
let ui_font_size_settings = ThemeSettings::get_global(cx).ui_font_size_settings();
|
||||
if ui_font_size_settings != prev_ui_font_size_settings {
|
||||
prev_ui_font_size_settings = ui_font_size_settings;
|
||||
reset_ui_font_size(cx);
|
||||
}
|
||||
|
||||
let agent_ui_font_size_settings =
|
||||
ThemeSettings::get_global(cx).agent_ui_font_size_settings();
|
||||
if agent_ui_font_size_settings != prev_agent_ui_font_size_settings {
|
||||
prev_agent_ui_font_size_settings = agent_ui_font_size_settings;
|
||||
reset_agent_ui_font_size(cx);
|
||||
}
|
||||
|
||||
let agent_buffer_font_size_settings =
|
||||
ThemeSettings::get_global(cx).agent_buffer_font_size_settings();
|
||||
if agent_buffer_font_size_settings != prev_agent_buffer_font_size_settings {
|
||||
prev_agent_buffer_font_size_settings = agent_buffer_font_size_settings;
|
||||
reset_agent_buffer_font_size(cx);
|
||||
}
|
||||
|
||||
if theme_name != prev_theme_name || theme_overrides != prev_theme_overrides {
|
||||
prev_theme_name = theme_name;
|
||||
prev_theme_overrides = theme_overrides;
|
||||
GlobalTheme::reload_theme(cx);
|
||||
}
|
||||
|
||||
if icon_theme_name != prev_icon_theme_name {
|
||||
prev_icon_theme_name = icon_theme_name;
|
||||
GlobalTheme::reload_icon_theme(cx);
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
|
@ -184,7 +154,7 @@ pub trait ActiveTheme {
|
|||
|
||||
impl ActiveTheme for App {
|
||||
fn theme(&self) -> &Arc<Theme> {
|
||||
GlobalTheme::theme(self)
|
||||
&ThemeSettings::get_global(self).active_theme
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -438,82 +408,3 @@ pub async fn read_icon_theme(
|
|||
|
||||
Ok(icon_theme_family)
|
||||
}
|
||||
|
||||
/// The active theme
|
||||
pub struct GlobalTheme {
|
||||
theme: Arc<Theme>,
|
||||
icon_theme: Arc<IconTheme>,
|
||||
}
|
||||
impl Global for GlobalTheme {}
|
||||
|
||||
impl GlobalTheme {
|
||||
fn configured_theme(cx: &mut App) -> Arc<Theme> {
|
||||
let themes = ThemeRegistry::default_global(cx);
|
||||
let theme_settings = ThemeSettings::get_global(cx);
|
||||
let system_appearance = SystemAppearance::global(cx);
|
||||
|
||||
let theme_name = theme_settings.theme.name(*system_appearance);
|
||||
|
||||
let theme = match themes.get(&theme_name.0) {
|
||||
Ok(theme) => theme,
|
||||
Err(err) => {
|
||||
if themes.extensions_loaded() {
|
||||
log::error!("{err}");
|
||||
}
|
||||
themes
|
||||
.get(default_theme(*system_appearance))
|
||||
// fallback for tests.
|
||||
.unwrap_or_else(|_| themes.get(DEFAULT_DARK_THEME).unwrap())
|
||||
}
|
||||
};
|
||||
theme_settings.apply_theme_overrides(theme)
|
||||
}
|
||||
|
||||
/// Reloads the current theme.
|
||||
///
|
||||
/// Reads the [`ThemeSettings`] to know which theme should be loaded,
|
||||
/// taking into account the current [`SystemAppearance`].
|
||||
pub fn reload_theme(cx: &mut App) {
|
||||
let theme = Self::configured_theme(cx);
|
||||
cx.update_global::<Self, _>(|this, _| this.theme = theme);
|
||||
cx.refresh_windows();
|
||||
}
|
||||
|
||||
fn configured_icon_theme(cx: &mut App) -> Arc<IconTheme> {
|
||||
let themes = ThemeRegistry::default_global(cx);
|
||||
let theme_settings = ThemeSettings::get_global(cx);
|
||||
let system_appearance = SystemAppearance::global(cx);
|
||||
|
||||
let icon_theme_name = theme_settings.icon_theme.name(*system_appearance);
|
||||
|
||||
match themes.get_icon_theme(&icon_theme_name.0) {
|
||||
Ok(theme) => theme,
|
||||
Err(err) => {
|
||||
if themes.extensions_loaded() {
|
||||
log::error!("{err}");
|
||||
}
|
||||
themes.get_icon_theme(DEFAULT_ICON_THEME_NAME).unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Reloads the current icon theme.
|
||||
///
|
||||
/// Reads the [`ThemeSettings`] to know which icon theme should be loaded,
|
||||
/// taking into account the current [`SystemAppearance`].
|
||||
pub fn reload_icon_theme(cx: &mut App) {
|
||||
let icon_theme = Self::configured_icon_theme(cx);
|
||||
cx.update_global::<Self, _>(|this, _| this.icon_theme = icon_theme);
|
||||
cx.refresh_windows();
|
||||
}
|
||||
|
||||
/// the active theme
|
||||
pub fn theme(cx: &App) -> &Arc<Theme> {
|
||||
&cx.global::<Self>().theme
|
||||
}
|
||||
|
||||
/// the active icon theme
|
||||
pub fn icon_theme(cx: &App) -> &Arc<IconTheme> {
|
||||
&cx.global::<Self>().icon_theme
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use anyhow::Result;
|
|||
use extension::{ExtensionHostProxy, ExtensionThemeProxy};
|
||||
use fs::Fs;
|
||||
use gpui::{App, BackgroundExecutor, SharedString, Task};
|
||||
use theme::{GlobalTheme, ThemeRegistry};
|
||||
use theme::{ThemeRegistry, ThemeSettings};
|
||||
|
||||
pub fn init(
|
||||
extension_host_proxy: Arc<ExtensionHostProxy>,
|
||||
|
|
@ -46,7 +46,7 @@ impl ExtensionThemeProxy for ThemeRegistryProxy {
|
|||
}
|
||||
|
||||
fn reload_current_theme(&self, cx: &mut App) {
|
||||
GlobalTheme::reload_theme(cx)
|
||||
ThemeSettings::reload_current_theme(cx)
|
||||
}
|
||||
|
||||
fn list_icon_theme_names(
|
||||
|
|
@ -83,6 +83,6 @@ impl ExtensionThemeProxy for ThemeRegistryProxy {
|
|||
}
|
||||
|
||||
fn reload_current_icon_theme(&self, cx: &mut App) {
|
||||
GlobalTheme::reload_icon_theme(cx)
|
||||
ThemeSettings::reload_current_icon_theme(cx)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,7 @@ use gpui::{
|
|||
use picker::{Picker, PickerDelegate};
|
||||
use settings::{Settings as _, SettingsStore, update_settings_file};
|
||||
use std::sync::Arc;
|
||||
use theme::{
|
||||
Appearance, IconThemeName, IconThemeSelection, SystemAppearance, ThemeMeta, ThemeRegistry,
|
||||
ThemeSettings,
|
||||
};
|
||||
use theme::{Appearance, IconTheme, ThemeMeta, ThemeRegistry, ThemeSettings};
|
||||
use ui::{ListItem, ListItemSpacing, prelude::*, v_flex};
|
||||
use util::ResultExt;
|
||||
use workspace::{ModalView, ui::HighlightedLabel};
|
||||
|
|
@ -54,9 +51,9 @@ pub(crate) struct IconThemeSelectorDelegate {
|
|||
fs: Arc<dyn Fs>,
|
||||
themes: Vec<ThemeMeta>,
|
||||
matches: Vec<StringMatch>,
|
||||
original_theme: IconThemeName,
|
||||
original_theme: Arc<IconTheme>,
|
||||
selection_completed: bool,
|
||||
selected_theme: Option<IconThemeName>,
|
||||
selected_theme: Option<Arc<IconTheme>>,
|
||||
selected_index: usize,
|
||||
selector: WeakEntity<IconThemeSelector>,
|
||||
}
|
||||
|
|
@ -69,9 +66,7 @@ impl IconThemeSelectorDelegate {
|
|||
cx: &mut Context<IconThemeSelector>,
|
||||
) -> Self {
|
||||
let theme_settings = ThemeSettings::get_global(cx);
|
||||
let original_theme = theme_settings
|
||||
.icon_theme
|
||||
.name(SystemAppearance::global(cx).0);
|
||||
let original_theme = theme_settings.active_icon_theme.clone();
|
||||
|
||||
let registry = ThemeRegistry::global(cx);
|
||||
let mut themes = registry
|
||||
|
|
@ -112,18 +107,29 @@ impl IconThemeSelectorDelegate {
|
|||
selector,
|
||||
};
|
||||
|
||||
this.select_if_matching(&original_theme.0);
|
||||
this.select_if_matching(&original_theme.name);
|
||||
this
|
||||
}
|
||||
|
||||
fn show_selected_theme(
|
||||
&mut self,
|
||||
cx: &mut Context<Picker<IconThemeSelectorDelegate>>,
|
||||
) -> Option<IconThemeName> {
|
||||
let mat = self.matches.get(self.selected_index)?;
|
||||
let name = IconThemeName(mat.string.clone().into());
|
||||
Self::set_icon_theme(name.clone(), cx);
|
||||
Some(name)
|
||||
) -> Option<Arc<IconTheme>> {
|
||||
if let Some(mat) = self.matches.get(self.selected_index) {
|
||||
let registry = ThemeRegistry::global(cx);
|
||||
match registry.get_icon_theme(&mat.string) {
|
||||
Ok(theme) => {
|
||||
Self::set_icon_theme(theme.clone(), cx);
|
||||
Some(theme)
|
||||
}
|
||||
Err(err) => {
|
||||
log::error!("error loading icon theme {}: {err}", mat.string);
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn select_if_matching(&mut self, theme_name: &str) {
|
||||
|
|
@ -134,11 +140,12 @@ impl IconThemeSelectorDelegate {
|
|||
.unwrap_or(self.selected_index);
|
||||
}
|
||||
|
||||
fn set_icon_theme(name: IconThemeName, cx: &mut App) {
|
||||
SettingsStore::update_global(cx, |store, _| {
|
||||
fn set_icon_theme(theme: Arc<IconTheme>, cx: &mut App) {
|
||||
SettingsStore::update_global(cx, |store, cx| {
|
||||
let mut theme_settings = store.get::<ThemeSettings>(None).clone();
|
||||
theme_settings.icon_theme = IconThemeSelection::Static(name);
|
||||
theme_settings.active_icon_theme = theme;
|
||||
store.override_global(theme_settings);
|
||||
cx.refresh_windows();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -163,9 +170,7 @@ impl PickerDelegate for IconThemeSelectorDelegate {
|
|||
self.selection_completed = true;
|
||||
|
||||
let theme_settings = ThemeSettings::get_global(cx);
|
||||
let theme_name = theme_settings
|
||||
.icon_theme
|
||||
.name(SystemAppearance::global(cx).0);
|
||||
let theme_name = theme_settings.active_icon_theme.name.clone();
|
||||
|
||||
telemetry::event!(
|
||||
"Settings Changed",
|
||||
|
|
@ -176,7 +181,7 @@ impl PickerDelegate for IconThemeSelectorDelegate {
|
|||
let appearance = Appearance::from(window.appearance());
|
||||
|
||||
update_settings_file(self.fs.clone(), cx, move |settings, _| {
|
||||
theme::set_icon_theme(settings, theme_name, appearance);
|
||||
theme::set_icon_theme(settings, theme_name.to_string(), appearance);
|
||||
});
|
||||
|
||||
self.selector
|
||||
|
|
@ -263,7 +268,7 @@ impl PickerDelegate for IconThemeSelectorDelegate {
|
|||
.matches
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, mtch)| mtch.string.as_str() == selected.0.as_ref())
|
||||
.find(|(_, mtch)| mtch.string == selected.name)
|
||||
.map(|(ix, _)| ix)
|
||||
.unwrap_or_default();
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -203,11 +203,12 @@ impl ThemeSelectorDelegate {
|
|||
}
|
||||
|
||||
fn set_theme(theme: Arc<Theme>, cx: &mut App) {
|
||||
SettingsStore::update_global(cx, |store, _| {
|
||||
SettingsStore::update_global(cx, |store, cx| {
|
||||
let mut theme_settings = store.get::<ThemeSettings>(None).clone();
|
||||
let name = theme.as_ref().name.clone().into();
|
||||
theme_settings.theme = theme::ThemeSelection::Static(theme::ThemeName(name));
|
||||
theme_settings.active_theme = theme;
|
||||
theme_settings.apply_theme_overrides();
|
||||
store.override_global(theme_settings);
|
||||
cx.refresh_windows();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use settings::{Settings, SettingsContent};
|
||||
use ui::App;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct TitleBarSettings {
|
||||
|
|
@ -12,7 +13,7 @@ pub struct TitleBarSettings {
|
|||
}
|
||||
|
||||
impl Settings for TitleBarSettings {
|
||||
fn from_settings(s: &SettingsContent) -> Self {
|
||||
fn from_settings(s: &SettingsContent, _: &mut App) -> Self {
|
||||
let content = s.title_bar.clone().unwrap();
|
||||
TitleBarSettings {
|
||||
show_branch_icon: content.show_branch_icon.unwrap(),
|
||||
|
|
|
|||
|
|
@ -1913,7 +1913,7 @@ impl From<settings::ModeContent> for Mode {
|
|||
}
|
||||
|
||||
impl Settings for VimSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
let vim = content.vim.clone().unwrap();
|
||||
Self {
|
||||
default_mode: vim.default_mode.unwrap().into(),
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ pub fn init(cx: &mut App) {
|
|||
pub struct VimModeSetting(pub bool);
|
||||
|
||||
impl Settings for VimModeSetting {
|
||||
fn from_settings(content: &SettingsContent) -> Self {
|
||||
fn from_settings(content: &SettingsContent, _cx: &mut App) -> Self {
|
||||
Self(content.vim_mode.unwrap())
|
||||
}
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ impl Settings for VimModeSetting {
|
|||
pub struct HelixModeSetting(pub bool);
|
||||
|
||||
impl Settings for HelixModeSetting {
|
||||
fn from_settings(content: &SettingsContent) -> Self {
|
||||
fn from_settings(content: &SettingsContent, _cx: &mut App) -> Self {
|
||||
Self(content.helix_mode.unwrap())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ pub struct PreviewTabsSettings {
|
|||
}
|
||||
|
||||
impl Settings for ItemSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
let tabs = content.tabs.as_ref().unwrap();
|
||||
Self {
|
||||
git_status: tabs.git_status.unwrap(),
|
||||
|
|
@ -113,7 +113,7 @@ impl Settings for ItemSettings {
|
|||
}
|
||||
|
||||
impl Settings for PreviewTabsSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
let preview_tabs = content.preview_tabs.as_ref().unwrap();
|
||||
Self {
|
||||
enabled: preview_tabs.enabled.unwrap(),
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ use std::{
|
|||
time::Duration,
|
||||
};
|
||||
use task::{DebugScenario, SpawnInTerminal, TaskContext};
|
||||
use theme::{ActiveTheme, GlobalTheme, SystemAppearance, ThemeSettings};
|
||||
use theme::{ActiveTheme, SystemAppearance, ThemeSettings};
|
||||
pub use toolbar::{Toolbar, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView};
|
||||
pub use ui;
|
||||
use ui::{Window, prelude::*};
|
||||
|
|
@ -1435,8 +1435,8 @@ impl Workspace {
|
|||
|
||||
*SystemAppearance::global_mut(cx) = SystemAppearance(window_appearance.into());
|
||||
|
||||
GlobalTheme::reload_theme(cx);
|
||||
GlobalTheme::reload_icon_theme(cx);
|
||||
ThemeSettings::reload_current_theme(cx);
|
||||
ThemeSettings::reload_current_icon_theme(cx);
|
||||
}),
|
||||
cx.on_release(move |this, cx| {
|
||||
this.app_state.workspace_store.update(cx, move |store, _| {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use std::num::NonZeroUsize;
|
|||
|
||||
use crate::DockPosition;
|
||||
use collections::HashMap;
|
||||
use gpui::App;
|
||||
use serde::Deserialize;
|
||||
pub use settings::AutosaveSetting;
|
||||
use settings::Settings;
|
||||
|
|
@ -61,7 +62,7 @@ pub struct TabBarSettings {
|
|||
}
|
||||
|
||||
impl Settings for WorkspaceSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
let workspace = &content.workspace;
|
||||
Self {
|
||||
active_pane_modifiers: ActivePanelModifiers {
|
||||
|
|
@ -196,7 +197,7 @@ impl Settings for WorkspaceSettings {
|
|||
}
|
||||
|
||||
impl Settings for TabBarSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
let tab_bar = content.tab_bar.clone().unwrap();
|
||||
TabBarSettings {
|
||||
show: tab_bar.show.unwrap(),
|
||||
|
|
@ -230,7 +231,7 @@ pub struct StatusBarSettings {
|
|||
}
|
||||
|
||||
impl Settings for StatusBarSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
let status_bar = content.status_bar.clone().unwrap();
|
||||
StatusBarSettings {
|
||||
show: status_bar.show.unwrap(),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use std::path::Path;
|
||||
|
||||
use anyhow::Context as _;
|
||||
use gpui::App;
|
||||
use settings::{Settings, SettingsContent};
|
||||
use util::{
|
||||
ResultExt,
|
||||
|
|
@ -34,7 +35,7 @@ impl WorktreeSettings {
|
|||
}
|
||||
|
||||
impl Settings for WorktreeSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _cx: &mut App) -> Self {
|
||||
let worktree = content.project.worktree.clone();
|
||||
let file_scan_exclusions = worktree.file_scan_exclusions.unwrap();
|
||||
let file_scan_inclusions = worktree.file_scan_inclusions.unwrap();
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ use std::{
|
|||
sync::Arc,
|
||||
};
|
||||
use theme::{
|
||||
ActiveTheme, GlobalTheme, IconThemeNotFoundError, SystemAppearance, ThemeNotFoundError,
|
||||
ThemeRegistry, ThemeSettings,
|
||||
ActiveTheme, IconThemeNotFoundError, SystemAppearance, ThemeNotFoundError, ThemeRegistry,
|
||||
ThemeSettings,
|
||||
};
|
||||
use util::{ResultExt, TryFutureExt, maybe};
|
||||
use uuid::Uuid;
|
||||
|
|
@ -542,6 +542,7 @@ pub fn main() {
|
|||
cx,
|
||||
);
|
||||
|
||||
SystemAppearance::init(cx);
|
||||
theme::init(theme::LoadThemes::All(Box::new(Assets)), cx);
|
||||
theme_extension::init(
|
||||
extension_host_proxy.clone(),
|
||||
|
|
@ -1362,49 +1363,49 @@ fn eager_load_active_theme_and_icon_theme(fs: Arc<dyn Fs>, cx: &App) {
|
|||
let theme_settings = ThemeSettings::get_global(cx);
|
||||
let appearance = SystemAppearance::global(cx).0;
|
||||
|
||||
let theme_name = theme_settings.theme.name(appearance);
|
||||
if matches!(
|
||||
theme_registry.get(&theme_name.0),
|
||||
Err(ThemeNotFoundError(_))
|
||||
) && let Some(theme_path) = extension_store
|
||||
.read(cx)
|
||||
.path_to_extension_theme(&theme_name.0)
|
||||
{
|
||||
cx.spawn({
|
||||
let theme_registry = theme_registry.clone();
|
||||
let fs = fs.clone();
|
||||
async move |cx| {
|
||||
theme_registry.load_user_theme(&theme_path, fs).await?;
|
||||
if let Some(theme_selection) = theme_settings.theme_selection.as_ref() {
|
||||
let theme_name = theme_selection.theme(appearance);
|
||||
if matches!(theme_registry.get(theme_name), Err(ThemeNotFoundError(_)))
|
||||
&& let Some(theme_path) = extension_store.read(cx).path_to_extension_theme(theme_name)
|
||||
{
|
||||
cx.spawn({
|
||||
let theme_registry = theme_registry.clone();
|
||||
let fs = fs.clone();
|
||||
async move |cx| {
|
||||
theme_registry.load_user_theme(&theme_path, fs).await?;
|
||||
|
||||
cx.update(|cx| {
|
||||
GlobalTheme::reload_theme(cx);
|
||||
})
|
||||
}
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
cx.update(|cx| {
|
||||
ThemeSettings::reload_current_theme(cx);
|
||||
})
|
||||
}
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
}
|
||||
|
||||
let icon_theme_name = theme_settings.icon_theme.name(appearance);
|
||||
if matches!(
|
||||
theme_registry.get_icon_theme(&icon_theme_name.0),
|
||||
Err(IconThemeNotFoundError(_))
|
||||
) && let Some((icon_theme_path, icons_root_path)) = extension_store
|
||||
.read(cx)
|
||||
.path_to_extension_icon_theme(&icon_theme_name.0)
|
||||
{
|
||||
cx.spawn({
|
||||
let fs = fs.clone();
|
||||
async move |cx| {
|
||||
theme_registry
|
||||
.load_icon_theme(&icon_theme_path, &icons_root_path, fs)
|
||||
.await?;
|
||||
if let Some(icon_theme_selection) = theme_settings.icon_theme_selection.as_ref() {
|
||||
let icon_theme_name = icon_theme_selection.icon_theme(appearance);
|
||||
if matches!(
|
||||
theme_registry.get_icon_theme(icon_theme_name),
|
||||
Err(IconThemeNotFoundError(_))
|
||||
) && let Some((icon_theme_path, icons_root_path)) = extension_store
|
||||
.read(cx)
|
||||
.path_to_extension_icon_theme(icon_theme_name)
|
||||
{
|
||||
cx.spawn({
|
||||
let fs = fs.clone();
|
||||
async move |cx| {
|
||||
theme_registry
|
||||
.load_icon_theme(&icon_theme_path, &icons_root_path, fs)
|
||||
.await?;
|
||||
|
||||
cx.update(|cx| {
|
||||
GlobalTheme::reload_icon_theme(cx);
|
||||
})
|
||||
}
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
cx.update(|cx| {
|
||||
ThemeSettings::reload_current_icon_theme(cx);
|
||||
})
|
||||
}
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1432,7 +1433,7 @@ fn load_user_themes_in_background(fs: Arc<dyn fs::Fs>, cx: &mut App) {
|
|||
}
|
||||
}
|
||||
theme_registry.load_user_themes(themes_dir, fs).await?;
|
||||
cx.update(GlobalTheme::reload_theme)?;
|
||||
cx.update(ThemeSettings::reload_current_theme)?;
|
||||
}
|
||||
anyhow::Ok(())
|
||||
}
|
||||
|
|
@ -1458,7 +1459,7 @@ fn watch_themes(fs: Arc<dyn fs::Fs>, cx: &mut App) {
|
|||
.await
|
||||
.log_err()
|
||||
{
|
||||
cx.update(GlobalTheme::reload_theme).log_err();
|
||||
cx.update(ThemeSettings::reload_current_theme).log_err();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1997,11 +1997,8 @@ mod tests {
|
|||
path::{Path, PathBuf},
|
||||
time::Duration,
|
||||
};
|
||||
use theme::ThemeRegistry;
|
||||
use util::{
|
||||
path,
|
||||
rel_path::{RelPath, rel_path},
|
||||
};
|
||||
use theme::{ThemeRegistry, ThemeSettings};
|
||||
use util::{path, rel_path::rel_path};
|
||||
use workspace::{
|
||||
NewFile, OpenOptions, OpenVisible, SERIALIZATION_THROTTLE_TIME, SaveIntent, SplitDirection,
|
||||
WorkspaceHandle,
|
||||
|
|
@ -4599,7 +4596,7 @@ mod tests {
|
|||
for theme_name in themes.list().into_iter().map(|meta| meta.name) {
|
||||
let theme = themes.get(&theme_name).unwrap();
|
||||
assert_eq!(theme.name, theme_name);
|
||||
if theme.name.as_ref() == "One Dark" {
|
||||
if theme.name == ThemeSettings::get(None, cx).active_theme.name {
|
||||
has_default_theme = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ pub struct ZlogSettings {
|
|||
}
|
||||
|
||||
impl Settings for ZlogSettings {
|
||||
fn from_settings(content: &settings::SettingsContent) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, _: &mut App) -> Self {
|
||||
ZlogSettings {
|
||||
scopes: content.log.clone().unwrap(),
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue