Detailed changes
@@ -59,7 +59,7 @@ dependencies = [
"serde",
"serde_json",
"settings",
- "theme",
+ "theme_settings",
"ui",
"util",
"workspace",
@@ -406,6 +406,7 @@ dependencies = [
"terminal_view",
"text",
"theme",
+ "theme_settings",
"time",
"time_format",
"tree-sitter-md",
@@ -3258,6 +3259,7 @@ dependencies = [
"telemetry_events",
"text",
"theme",
+ "theme_settings",
"time",
"tokio",
"toml 0.8.23",
@@ -3303,6 +3305,7 @@ dependencies = [
"smallvec",
"telemetry",
"theme",
+ "theme_settings",
"time",
"time_format",
"title_bar",
@@ -3375,6 +3378,7 @@ dependencies = [
"settings",
"telemetry",
"theme",
+ "theme_settings",
"time",
"ui",
"util",
@@ -3427,6 +3431,7 @@ dependencies = [
"session",
"settings",
"theme",
+ "theme_settings",
"ui",
"ui_input",
"uuid",
@@ -3624,6 +3629,7 @@ dependencies = [
"settings",
"sum_tree",
"theme",
+ "theme_settings",
"util",
"workspace",
"zlog",
@@ -4694,6 +4700,7 @@ dependencies = [
"terminal_view",
"text",
"theme",
+ "theme_settings",
"tree-sitter",
"tree-sitter-go",
"tree-sitter-json",
@@ -4881,6 +4888,7 @@ dependencies = [
"settings",
"text",
"theme",
+ "theme_settings",
"ui",
"unindent",
"util",
@@ -5397,6 +5405,7 @@ dependencies = [
"telemetry",
"text",
"theme",
+ "theme_settings",
"time",
"ui",
"util",
@@ -5465,6 +5474,7 @@ dependencies = [
"telemetry",
"text",
"theme",
+ "theme_settings",
"time",
"tracing",
"tree-sitter-bash",
@@ -6044,7 +6054,7 @@ dependencies = [
"settings_content",
"snippet_provider",
"task",
- "theme",
+ "theme_settings",
"tokio",
"toml 0.8.23",
"tree-sitter",
@@ -6093,6 +6103,7 @@ dependencies = [
"tempfile",
"theme",
"theme_extension",
+ "theme_settings",
"toml 0.8.23",
"tracing",
"url",
@@ -6131,7 +6142,7 @@ dependencies = [
"smallvec",
"strum 0.27.2",
"telemetry",
- "theme",
+ "theme_settings",
"ui",
"util",
"vim_mode_setting",
@@ -6288,6 +6299,7 @@ dependencies = [
"serde_json",
"settings",
"theme",
+ "theme_settings",
"ui",
"util",
"workspace",
@@ -7303,6 +7315,7 @@ dependencies = [
"settings",
"smallvec",
"theme",
+ "theme_settings",
"time",
"ui",
"workspace",
@@ -7378,6 +7391,7 @@ dependencies = [
"strum 0.27.2",
"telemetry",
"theme",
+ "theme_settings",
"time",
"time_format",
"tracing",
@@ -8729,7 +8743,7 @@ dependencies = [
"project",
"serde",
"settings",
- "theme",
+ "theme_settings",
"ui",
"util",
"workspace",
@@ -8845,7 +8859,7 @@ dependencies = [
"project",
"serde_json",
"serde_json_lenient",
- "theme",
+ "theme_settings",
"ui",
"util",
"util_macros",
@@ -9288,6 +9302,7 @@ dependencies = [
"telemetry",
"tempfile",
"theme",
+ "theme_settings",
"tree-sitter-json",
"tree-sitter-rust",
"ui",
@@ -9398,6 +9413,7 @@ dependencies = [
"task",
"text",
"theme",
+ "theme_settings",
"toml 0.8.23",
"tracing",
"tree-sitter",
@@ -9611,6 +9627,7 @@ dependencies = [
"sysinfo 0.37.2",
"telemetry",
"theme",
+ "theme_settings",
"tree-sitter",
"ui",
"util",
@@ -10289,6 +10306,7 @@ dependencies = [
"stacksafe",
"sum_tree",
"theme",
+ "theme_settings",
"ui",
"util",
]
@@ -10305,7 +10323,7 @@ dependencies = [
"markdown",
"settings",
"tempfile",
- "theme",
+ "theme_settings",
"ui",
"urlencoding",
"util",
@@ -10665,7 +10683,7 @@ dependencies = [
"rpc",
"serde_json",
"smol",
- "theme",
+ "theme_settings",
"util",
"workspace",
"zed_actions",
@@ -11556,6 +11574,7 @@ dependencies = [
"settings",
"telemetry",
"theme",
+ "theme_settings",
"ui",
"util",
"vim_mode_setting",
@@ -11661,6 +11680,7 @@ dependencies = [
"serde_json",
"settings",
"theme",
+ "theme_settings",
"ui",
"util",
"workspace",
@@ -11839,6 +11859,7 @@ dependencies = [
"settings",
"smol",
"theme",
+ "theme_settings",
"ui",
"util",
"workspace",
@@ -11871,6 +11892,7 @@ dependencies = [
"smallvec",
"smol",
"theme",
+ "theme_settings",
"ui",
"util",
"workspace",
@@ -12736,6 +12758,7 @@ dependencies = [
"serde",
"settings",
"theme",
+ "theme_settings",
"ui",
"ui_input",
"workspace",
@@ -12844,6 +12867,7 @@ dependencies = [
"settings",
"smallvec",
"theme",
+ "theme_settings",
"ui",
"windows 0.61.3",
"workspace",
@@ -13342,6 +13366,7 @@ dependencies = [
"telemetry",
"tempfile",
"theme",
+ "theme_settings",
"ui",
"util",
"workspace",
@@ -13368,6 +13393,7 @@ dependencies = [
"serde_json",
"settings",
"theme",
+ "theme_settings",
"util",
"workspace",
]
@@ -14360,7 +14386,7 @@ dependencies = [
"remote",
"semver",
"settings",
- "theme",
+ "theme_settings",
"ui",
"ui_input",
"workspace",
@@ -14428,6 +14454,7 @@ dependencies = [
"sysinfo 0.37.2",
"task",
"theme",
+ "theme_settings",
"thiserror 2.0.17",
"toml 0.8.23",
"unindent",
@@ -14498,6 +14525,7 @@ dependencies = [
"terminal",
"terminal_view",
"theme",
+ "theme_settings",
"tree-sitter-md",
"tree-sitter-python",
"tree-sitter-typescript",
@@ -14837,7 +14865,7 @@ dependencies = [
"rope",
"serde",
"settings",
- "theme",
+ "theme_settings",
"ui",
"ui_input",
"util",
@@ -15251,6 +15279,7 @@ dependencies = [
"serde_json",
"settings",
"theme",
+ "theme_settings",
]
[[package]]
@@ -15474,6 +15503,7 @@ dependencies = [
"settings",
"smol",
"theme",
+ "theme_settings",
"tracing",
"ui",
"unindent",
@@ -15818,6 +15848,7 @@ dependencies = [
"serde_json",
"settings",
"theme",
+ "theme_settings",
"ui",
"workspace",
"zed_actions",
@@ -15866,6 +15897,7 @@ dependencies = [
"strum 0.27.2",
"telemetry",
"theme",
+ "theme_settings",
"title_bar",
"ui",
"util",
@@ -16001,6 +16033,7 @@ dependencies = [
"serde_json",
"settings",
"theme",
+ "theme_settings",
"ui",
"util",
"vim_mode_setting",
@@ -16656,6 +16689,7 @@ dependencies = [
"story",
"strum 0.27.2",
"theme",
+ "theme_settings",
"title_bar",
"ui",
]
@@ -17306,6 +17340,7 @@ dependencies = [
"settings",
"smol",
"theme",
+ "theme_settings",
"ui",
"util",
"workspace",
@@ -17490,6 +17525,7 @@ dependencies = [
"sysinfo 0.37.2",
"task",
"theme",
+ "theme_settings",
"thiserror 2.0.17",
"url",
"urlencoding",
@@ -17537,6 +17573,7 @@ dependencies = [
"task",
"terminal",
"theme",
+ "theme_settings",
"ui",
"util",
"workspace",
@@ -17572,8 +17609,6 @@ dependencies = [
"collections",
"derive_more",
"gpui",
- "gpui_util",
- "log",
"palette",
"parking_lot",
"refineable",
@@ -17581,7 +17616,6 @@ dependencies = [
"serde",
"serde_json",
"serde_json_lenient",
- "settings",
"strum 0.27.2",
"thiserror 2.0.17",
"uuid",
@@ -17596,6 +17630,7 @@ dependencies = [
"fs",
"gpui",
"theme",
+ "theme_settings",
]
[[package]]
@@ -17615,6 +17650,7 @@ dependencies = [
"simplelog",
"strum 0.27.2",
"theme",
+ "theme_settings",
"vscode_theme",
]
@@ -17631,12 +17667,33 @@ dependencies = [
"settings",
"telemetry",
"theme",
+ "theme_settings",
"ui",
"util",
"workspace",
"zed_actions",
]
+[[package]]
+name = "theme_settings"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "collections",
+ "gpui",
+ "gpui_util",
+ "log",
+ "palette",
+ "refineable",
+ "schemars",
+ "serde",
+ "serde_json",
+ "serde_json_lenient",
+ "settings",
+ "theme",
+ "uuid",
+]
+
[[package]]
name = "thiserror"
version = "1.0.69"
@@ -18780,6 +18837,7 @@ dependencies = [
"story",
"strum 0.27.2",
"theme",
+ "theme_settings",
"ui_macros",
"windows 0.61.3",
]
@@ -18811,7 +18869,7 @@ dependencies = [
"markdown",
"menu",
"settings",
- "theme",
+ "theme_settings",
"ui",
"workspace",
]
@@ -19210,6 +19268,7 @@ dependencies = [
"task",
"text",
"theme",
+ "theme_settings",
"tokio",
"ui",
"util",
@@ -20337,7 +20396,7 @@ dependencies = [
"gpui",
"serde",
"settings",
- "theme",
+ "theme_settings",
"ui",
"util",
"workspace",
@@ -21556,6 +21615,7 @@ dependencies = [
"telemetry",
"tempfile",
"theme",
+ "theme_settings",
"ui",
"util",
"uuid",
@@ -22117,6 +22177,7 @@ dependencies = [
"theme",
"theme_extension",
"theme_selector",
+ "theme_settings",
"time",
"time_format",
"title_bar",
@@ -198,6 +198,7 @@ members = [
"crates/text",
"crates/theme",
"crates/theme_extension",
+ "crates/theme_settings",
"crates/theme_importer",
"crates/theme_selector",
"crates/time_format",
@@ -445,6 +446,7 @@ terminal_view = { path = "crates/terminal_view" }
text = { path = "crates/text" }
theme = { path = "crates/theme" }
theme_extension = { path = "crates/theme_extension" }
+theme_settings = { path = "crates/theme_settings" }
theme_selector = { path = "crates/theme_selector" }
time_format = { path = "crates/time_format" }
platform_title_bar = { path = "crates/platform_title_bar" }
@@ -23,7 +23,7 @@ project.workspace = true
serde.workspace = true
serde_json.workspace = true
settings.workspace = true
-theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
util.workspace = true
workspace.workspace = true
@@ -16,7 +16,7 @@ use language::LanguageRegistry;
use markdown::{CodeBlockRenderer, Markdown, MarkdownElement, MarkdownStyle};
use project::{AgentId, Project};
use settings::Settings;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{CopyButton, Tooltip, WithScrollbar, prelude::*};
use util::ResultExt as _;
use workspace::{
@@ -7837,7 +7837,7 @@ impl Editor {
h_flex()
.px_0p5()
.when(is_platform_style_mac, |parent| parent.gap_0p5())
- .font(theme::ThemeSettings::get_global(cx).buffer_font.clone())
+ .font(theme_settings::ThemeSettings::get_global(cx).buffer_font.clone())
.text_size(TextSize::XSmall.rems(cx))
.child(h_flex().children(ui::render_modifiers(
&accept_keystroke.modifiers,
@@ -8149,7 +8149,7 @@ impl Editor {
.px_2()
.child(
h_flex()
- .font(theme::ThemeSettings::get_global(cx).buffer_font.clone())
+ .font(theme_settings::ThemeSettings::get_global(cx).buffer_font.clone())
.when(is_platform_style_mac, |parent| parent.gap_1())
.child(h_flex().children(ui::render_modifiers(
&accept_keystroke.modifiers,
@@ -8258,7 +8258,7 @@ impl Editor {
.gap_2()
.pr_1()
.overflow_x_hidden()
- .font(theme::ThemeSettings::get_global(cx).buffer_font.clone())
+ .font(theme_settings::ThemeSettings::get_global(cx).buffer_font.clone())
.child(left)
.child(preview),
)
@@ -7837,7 +7837,7 @@ impl Editor {
h_flex()
.px_0p5()
.when(is_platform_style_mac, |parent| parent.gap_0p5())
- .font(theme::ThemeSettings::get_global(cx).buffer_font.clone())
+ .font(theme_settings::ThemeSettings::get_global(cx).buffer_font.clone())
.text_size(TextSize::XSmall.rems(cx))
.child(h_flex().children(ui::render_modifiers(
&accept_keystroke.modifiers,
@@ -8149,7 +8149,7 @@ impl Editor {
.px_2()
.child(
h_flex()
- .font(theme::ThemeSettings::get_global(cx).buffer_font.clone())
+ .font(theme_settings::ThemeSettings::get_global(cx).buffer_font.clone())
.when(is_platform_style_mac, |parent| parent.gap_1())
.child(h_flex().children(ui::render_modifiers(
&accept_keystroke.modifiers,
@@ -8258,7 +8258,7 @@ impl Editor {
.gap_2()
.pr_1()
.overflow_x_hidden()
- .font(theme::ThemeSettings::get_global(cx).buffer_font.clone())
+ .font(theme_settings::ThemeSettings::get_global(cx).buffer_font.clone())
.child(left)
.child(preview),
)
@@ -101,6 +101,7 @@ terminal.workspace = true
terminal_view.workspace = true
text.workspace = true
theme.workspace = true
+theme_settings.workspace = true
time.workspace = true
time_format.workspace = true
ui.workspace = true
@@ -813,7 +813,7 @@ mod tests {
cx.update(|cx| {
let store = SettingsStore::test(cx);
cx.set_global(store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
language_model::init_settings(cx);
editor::init(cx);
@@ -22,7 +22,7 @@ use project::{
use serde::Deserialize;
use settings::{Settings as _, update_settings_file};
use std::sync::Arc;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{
CommonAnimationExt, KeyBinding, Modal, ModalFooter, ModalHeader, Section, Tooltip,
WithScrollbar, prelude::*,
@@ -1806,7 +1806,7 @@ mod tests {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
prompt_store::init(cx);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
language_model::init_settings(cx);
});
@@ -1963,7 +1963,7 @@ mod tests {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
prompt_store::init(cx);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
language_model::init_settings(cx);
workspace::register_project_item::<Editor>(cx);
});
@@ -76,7 +76,7 @@ use prompt_store::{PromptBuilder, PromptStore, UserPromptId};
use rules_library::{RulesLibrary, open_rules_library};
use search::{BufferSearchBar, buffer_search};
use settings::{Settings, update_settings_file};
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{
Button, Callout, CommonAnimationExt, ContextMenu, ContextMenuEntry, DocumentationSide,
KeyBinding, PopoverMenu, PopoverMenuHandle, Tab, Tooltip, prelude::*, utils::WithRemSize,
@@ -1624,17 +1624,17 @@ impl AgentPanel {
let agent_buffer_font_size =
ThemeSettings::get_global(cx).agent_buffer_font_size(cx) + delta;
- let _ = settings
- .theme
- .agent_ui_font_size
- .insert(f32::from(theme::clamp_font_size(agent_ui_font_size)).into());
+ let _ = settings.theme.agent_ui_font_size.insert(
+ f32::from(theme_settings::clamp_font_size(agent_ui_font_size)).into(),
+ );
let _ = settings.theme.agent_buffer_font_size.insert(
- f32::from(theme::clamp_font_size(agent_buffer_font_size)).into(),
+ f32::from(theme_settings::clamp_font_size(agent_buffer_font_size))
+ .into(),
);
});
} else {
- theme::adjust_agent_ui_font_size(cx, |size| size + delta);
- theme::adjust_agent_buffer_font_size(cx, |size| size + delta);
+ theme_settings::adjust_agent_ui_font_size(cx, |size| size + delta);
+ theme_settings::adjust_agent_buffer_font_size(cx, |size| size + delta);
}
}
WhichFontSize::BufferFont => {
@@ -1658,14 +1658,14 @@ impl AgentPanel {
settings.theme.agent_buffer_font_size = None;
});
} else {
- theme::reset_agent_ui_font_size(cx);
- theme::reset_agent_buffer_font_size(cx);
+ theme_settings::reset_agent_ui_font_size(cx);
+ theme_settings::reset_agent_buffer_font_size(cx);
}
}
pub fn reset_agent_zoom(&mut self, _window: &mut Window, cx: &mut Context<Self>) {
- theme::reset_agent_ui_font_size(cx);
- theme::reset_agent_buffer_font_size(cx);
+ theme_settings::reset_agent_ui_font_size(cx);
+ theme_settings::reset_agent_buffer_font_size(cx);
}
pub fn toggle_zoom(&mut self, _: &ToggleZoom, window: &mut Window, cx: &mut Context<Self>) {
@@ -12,7 +12,7 @@ use gpui::{
use project::agent_server_store::{AllAgentServersSettings, CustomAgentServerSettings};
use project::{AgentRegistryStore, RegistryAgent};
use settings::{Settings, SettingsStore, update_settings_file};
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{
ButtonStyle, ScrollableHandle, ToggleButtonGroup, ToggleButtonGroupSize,
ToggleButtonGroupStyle, ToggleButtonSimple, Tooltip, WithScrollbar, prelude::*,
@@ -2577,7 +2577,7 @@ mod tests {
let app_state = cx.update(|cx| {
let state = AppState::test(cx);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
editor::init(cx);
state
});
@@ -49,7 +49,7 @@ use std::time::Instant;
use std::{collections::BTreeMap, rc::Rc, time::Duration};
use terminal_view::terminal_panel::TerminalPanel;
use text::Anchor;
-use theme::AgentFontSize;
+use theme_settings::AgentFontSize;
use ui::{
Callout, CircularProgress, CommonAnimationExt, ContextMenu, ContextMenuEntry, CopyButton,
DecoratedIcon, DiffStat, Disclosure, Divider, DividerColor, IconDecoration, IconDecorationKind,
@@ -4257,7 +4257,7 @@ pub(crate) mod tests {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
SidebarThreadMetadataStore::init_global(cx);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
editor::init(cx);
agent_panel::init(cx);
release_channel::init(semver::Version::new(0, 0, 0), cx);
@@ -16,7 +16,7 @@ use prompt_store::PromptStore;
use rope::Point;
use settings::Settings as _;
use terminal_view::TerminalView;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{Context, TextSize};
use workspace::Workspace;
@@ -594,7 +594,7 @@ mod tests {
cx.update(|cx| {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
release_channel::init(semver::Version::new(0, 0, 0), cx);
});
}
@@ -24,7 +24,7 @@ use std::cmp;
use std::ops::Range;
use std::rc::Rc;
use std::sync::Arc;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::utils::WithRemSize;
use ui::{IconButtonShape, KeyBinding, PopoverMenuHandle, Tooltip, prelude::*};
use uuid::Uuid;
@@ -667,7 +667,7 @@ mod tests {
let settings_store = cx.update(SettingsStore::test);
cx.set_global(settings_store);
cx.update(|cx| {
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
release_channel::init(Version::new(0, 0, 0), cx);
prompt_store::init(cx);
});
@@ -33,7 +33,7 @@ use prompt_store::PromptStore;
use rope::Point;
use settings::Settings;
use std::{fmt::Write, ops::Range, rc::Rc, sync::Arc};
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{ContextMenu, Disclosure, ElevationIndex, prelude::*};
use util::paths::PathStyle;
use util::{ResultExt, debug_panic};
@@ -73,7 +73,7 @@ pub fn init_test(cx: &mut TestAppContext) {
cx.update(|cx| {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
editor::init(cx);
release_channel::init("0.0.0".parse().unwrap(), cx);
agent_panel::init(cx);
@@ -1030,7 +1030,11 @@ impl TextThreadEditor {
h_flex()
.items_center()
.gap_1()
- .font(theme::ThemeSettings::get_global(cx).buffer_font.clone())
+ .font(
+ theme_settings::ThemeSettings::get_global(cx)
+ .buffer_font
+ .clone(),
+ )
.text_size(TextSize::XSmall.rems(cx))
.text_color(colors.text_muted)
.child("Press")
@@ -3440,7 +3444,7 @@ mod tests {
LanguageModelRegistry::test(cx);
cx.set_global(settings_store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
}
#[gpui::test]
@@ -232,7 +232,7 @@ mod tests {
cx.update(|cx| {
let settings_store = settings::SettingsStore::test(cx);
cx.set_global(settings_store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
});
}
@@ -5,7 +5,6 @@ use gpui::{
};
use release_channel::ReleaseChannel;
use std::rc::Rc;
-use theme;
use ui::{Render, prelude::*};
pub struct AgentNotification {
@@ -87,7 +86,7 @@ impl AgentNotification {
impl Render for AgentNotification {
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
- let ui_font = theme::setup_ui_font(window, cx);
+ let ui_font = theme_settings::setup_ui_font(window, cx);
let line_height = window.line_height();
let bg = cx.theme().colors().elevated_surface_background;
@@ -9,7 +9,7 @@ use gpui::{
use prompt_store::PromptId;
use rope::Point;
use settings::Settings;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{ButtonLike, TintColor, Tooltip, prelude::*};
use workspace::{OpenOptions, Workspace};
@@ -130,6 +130,7 @@ settings = { workspace = true, features = ["test-support"] }
smol.workspace = true
sqlx = { version = "0.8", features = ["sqlite"] }
task.workspace = true
+theme_settings = { workspace = true, features = ["test-support"] }
theme.workspace = true
unindent.workspace = true
@@ -191,7 +191,7 @@ pub async fn run_randomized_test<T: RandomizedTest>(
let settings = cx.remove_global::<SettingsStore>();
cx.clear_globals();
cx.set_global(settings);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
drop(client);
});
executor.run_until_parked();
@@ -173,7 +173,7 @@ impl TestServer {
}
let settings = SettingsStore::test(cx);
cx.set_global(settings);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
release_channel::init(semver::Version::new(0, 0, 0), cx);
});
@@ -341,7 +341,7 @@ impl TestServer {
let os_keymap = "keymaps/default-macos.json";
cx.update(|cx| {
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
Project::init(&client, cx);
client::init(&client, cx);
editor::init(cx);
@@ -54,6 +54,7 @@ settings.workspace = true
smallvec.workspace = true
telemetry.workspace = true
theme.workspace = true
+theme_settings.workspace = true
time.workspace = true
time_format.workspace = true
title_bar.workspace = true
@@ -29,7 +29,8 @@ use serde::{Deserialize, Serialize};
use settings::Settings;
use smallvec::SmallVec;
use std::{mem, sync::Arc};
-use theme::{ActiveTheme, ThemeSettings};
+use theme::ActiveTheme;
+use theme_settings::ThemeSettings;
use ui::{
Avatar, AvatarAvailabilityIndicator, ContextMenu, CopyButton, Facepile, HighlightedLabel,
IconButtonShape, Indicator, ListHeader, ListItem, Tab, Tooltip, prelude::*, tooltip_container,
@@ -111,7 +111,7 @@ impl IncomingCallNotification {
impl Render for IncomingCallNotification {
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
- let ui_font = theme::setup_ui_font(window, cx);
+ let ui_font = theme_settings::setup_ui_font(window, cx);
div().size_full().font(ui_font).child(
CollabNotification::new(
@@ -120,7 +120,7 @@ impl ProjectSharedNotification {
impl Render for ProjectSharedNotification {
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
- let ui_font = theme::setup_ui_font(window, cx);
+ let ui_font = theme_settings::setup_ui_font(window, cx);
let no_worktree_root_names = self.worktree_root_names.is_empty();
let punctuation = if no_worktree_root_names { "" } else { ":" };
@@ -49,3 +49,4 @@ menu.workspace = true
project = { workspace = true, features = ["test-support"] }
workspace = { workspace = true, features = ["test-support"] }
+theme_settings.workspace = true
@@ -931,7 +931,7 @@ mod tests {
fn init_test(cx: &mut TestAppContext) -> Arc<AppState> {
cx.update(|cx| {
let app_state = AppState::test(cx);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
editor::init(cx);
menu::init();
go_to_line::init(cx);
@@ -33,6 +33,7 @@ reqwest_client.workspace = true
session.workspace = true
settings.workspace = true
theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
ui_input.workspace = true
uuid.workspace = true
@@ -39,7 +39,7 @@ fn main() {
<dyn fs::Fs>::set_global(fs.clone(), cx);
settings::init(cx);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
let languages = Arc::new(LanguageRegistry::new(cx.background_executor().clone()));
let client = Client::production(cx);
@@ -81,7 +81,7 @@ fn main() {
{
move |window, cx| {
let app_state = app_state;
- theme::setup_ui_font(window, cx);
+ theme_settings::setup_ui_font(window, cx);
let project = Project::local(
app_state.client.clone(),
@@ -68,3 +68,4 @@ settings = { workspace = true, features = ["test-support"] }
theme = { workspace = true, features = ["test-support"] }
util = { workspace = true, features = ["test-support"] }
zlog.workspace = true
+theme_settings.workspace = true
@@ -1120,7 +1120,7 @@ mod tests {
cx.update(|cx| {
let store = SettingsStore::test(cx);
cx.set_global(store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
SettingsStore::update_global(cx, |store: &mut SettingsStore, cx| {
store.update_user_settings(cx, |settings| f(&mut settings.project.all_languages));
});
@@ -67,6 +67,7 @@ tasks_ui.workspace = true
terminal_view.workspace = true
text.workspace = true
theme.workspace = true
+theme_settings.workspace = true
tree-sitter-json.workspace = true
tree-sitter.workspace = true
ui.workspace = true
@@ -26,7 +26,8 @@ use project::{
use settings::Settings;
use std::fmt::Write;
use std::{ops::Range, rc::Rc, usize};
-use theme::{Theme, ThemeSettings};
+use theme::Theme;
+use theme_settings::ThemeSettings;
use ui::{ContextMenu, Divider, PopoverMenu, SplitButton, Tooltip, prelude::*};
use util::ResultExt;
@@ -17,7 +17,7 @@ use gpui::{
use notifications::status_toast::{StatusToast, ToastIcon};
use project::debugger::{MemoryCell, dap_command::DataBreakpointContext, session::Session};
use settings::Settings;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{
ContextMenu, Divider, DropdownMenu, FluentBuilder, IntoElement, PopoverMenuHandle, Render,
ScrollableHandle, StatefulInteractiveElement, Tooltip, WithScrollbar, prelude::*,
@@ -41,7 +41,7 @@ pub fn init_test(cx: &mut gpui::TestAppContext) {
let settings = SettingsStore::test(cx);
cx.set_global(settings);
terminal_view::init(cx);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
command_palette_hooks::init(cx);
editor::init(cx);
crate::init(cx);
@@ -32,6 +32,7 @@ serde_json.workspace = true
settings.workspace = true
text.workspace = true
theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
util.workspace = true
workspace.workspace = true
@@ -11,7 +11,7 @@ use lsp::DiagnosticSeverity;
use markdown::{Markdown, MarkdownElement};
use settings::Settings;
use text::{AnchorRangeExt, Point};
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{CopyButton, prelude::*};
use util::maybe;
@@ -2034,7 +2034,7 @@ fn init_test(cx: &mut TestAppContext) {
zlog::init_test();
let settings = SettingsStore::test(cx);
cx.set_global(settings);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
crate::init(cx);
editor::init(cx);
});
@@ -42,7 +42,7 @@ regex.workspace = true
settings.workspace = true
telemetry.workspace = true
text.workspace = true
-theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
util.workspace = true
workspace.workspace = true
@@ -14,7 +14,7 @@ use project::{
use settings::Settings as _;
use std::rc::Rc;
use std::{fmt::Write, sync::Arc};
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{
ContextMenu, DropdownMenu, KeyBinding, List, ListItem, ListItemSpacing, PopoverMenuHandle,
Tooltip, prelude::*,
@@ -83,6 +83,7 @@ telemetry.workspace = true
text.workspace = true
time.workspace = true
theme.workspace = true
+theme_settings.workspace = true
tree-sitter-c = { workspace = true, optional = true }
tree-sitter-html = { workspace = true, optional = true }
tree-sitter-rust = { workspace = true, optional = true }
@@ -122,7 +122,7 @@ pub fn benches() {
let store = SettingsStore::test(cx);
cx.set_global(store);
assets::Assets.load_test_fonts(cx);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
// release_channel::init(semver::Version::new(0,0,0), cx);
editor::init(cx);
});
@@ -226,7 +226,7 @@ mod tests {
use serde_json::json;
use settings::{AccentContent, SettingsStore};
use text::{Bias, OffsetRangeExt, ToOffset};
- use theme::ThemeStyleContent;
+ use theme_settings::ThemeStyleContent;
use util::{path, post_inc};
@@ -4036,7 +4036,7 @@ pub mod tests {
let settings = SettingsStore::test(cx);
cx.set_global(settings);
crate::init(cx);
- theme::init(LoadThemes::JustBase, cx);
+ theme_settings::init(LoadThemes::JustBase, cx);
cx.update_global::<SettingsStore, _>(|store, cx| {
store.update_user_settings(cx, f);
});
@@ -4830,7 +4830,7 @@ mod tests {
fn init_test(cx: &mut gpui::App) {
let settings = SettingsStore::test(cx);
cx.set_global(settings);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
assets::Assets.load_test_fonts(cx);
}
@@ -57,7 +57,8 @@ impl FoldPlaceholder {
pub fn fold_element(fold_id: FoldId, cx: &App) -> Stateful<gpui::Div> {
use gpui::{InteractiveElement as _, StatefulInteractiveElement as _, Styled as _};
use settings::Settings as _;
- use theme::{ActiveTheme as _, ThemeSettings};
+ use theme::ActiveTheme as _;
+ use theme_settings::ThemeSettings;
let settings = ThemeSettings::get_global(cx);
gpui::div()
.id(fold_id)
@@ -2227,7 +2227,7 @@ mod tests {
fn init_test(cx: &mut App) {
let store = SettingsStore::test(cx);
cx.set_global(store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
}
/// Helper to create test highlights for an inlay
@@ -1664,7 +1664,7 @@ mod tests {
cx.update(|cx| {
let settings = SettingsStore::test(cx);
cx.set_global(settings);
- theme::init(LoadThemes::JustBase, cx);
+ theme_settings::init(LoadThemes::JustBase, cx);
});
}
@@ -204,8 +204,8 @@ use task::TaskVariables;
use text::{BufferId, FromAnchor, OffsetUtf16, Rope, ToOffset as _, ToPoint as _};
use theme::{
AccentColors, ActiveTheme, GlobalTheme, PlayerColor, StatusColors, SyntaxTheme, Theme,
- ThemeSettings, observe_buffer_font_size_adjustment,
};
+use theme_settings::{ThemeSettings, observe_buffer_font_size_adjustment};
use ui::{
Avatar, ButtonSize, ButtonStyle, ContextMenu, Disclosure, IconButton, IconButtonShape,
IconName, IconSize, Indicator, Key, Tooltip, h_flex, prelude::*, scrollbars::ScrollbarAutoHide,
@@ -9936,7 +9936,11 @@ impl Editor {
h_flex()
.px_0p5()
.when(is_platform_style_mac, |parent| parent.gap_0p5())
- .font(theme::ThemeSettings::get_global(cx).buffer_font.clone())
+ .font(
+ theme_settings::ThemeSettings::get_global(cx)
+ .buffer_font
+ .clone(),
+ )
.text_size(TextSize::XSmall.rems(cx))
.child(h_flex().children(ui::render_modifiers(
keystroke.modifiers(),
@@ -9967,7 +9971,11 @@ impl Editor {
if keystroke.modifiers().modified() {
h_flex()
- .font(theme::ThemeSettings::get_global(cx).buffer_font.clone())
+ .font(
+ theme_settings::ThemeSettings::get_global(cx)
+ .buffer_font
+ .clone(),
+ )
.when(is_platform_style_mac, |parent| parent.gap_1())
.child(h_flex().children(ui::render_modifiers(
keystroke.modifiers(),
@@ -10473,7 +10481,11 @@ impl Editor {
.gap_2()
.pr_1()
.overflow_x_hidden()
- .font(theme::ThemeSettings::get_global(cx).buffer_font.clone())
+ .font(
+ theme_settings::ThemeSettings::get_global(cx)
+ .buffer_font
+ .clone(),
+ )
.child(left)
.child(preview),
)
@@ -24446,7 +24458,7 @@ impl Editor {
return None;
}
- let theme_settings = theme::ThemeSettings::get_global(cx);
+ let theme_settings = theme_settings::ThemeSettings::get_global(cx);
let theme = cx.theme();
let accent_colors = theme.accents().clone();
@@ -29721,7 +29721,7 @@ pub(crate) fn init_test(cx: &mut TestAppContext, f: fn(&mut AllLanguageSettingsC
assets::Assets.load_test_fonts(cx);
let store = SettingsStore::test(cx);
cx.set_global(store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
release_channel::init(semver::Version::new(0, 0, 0), cx);
crate::init(cx);
});
@@ -83,7 +83,8 @@ use std::{
};
use sum_tree::Bias;
use text::{BufferId, SelectionGoal};
-use theme::{ActiveTheme, Appearance, BufferLineHeight, PlayerColor};
+use theme::{ActiveTheme, Appearance, PlayerColor};
+use theme_settings::BufferLineHeight;
use ui::utils::ensure_minimum_contrast;
use ui::{
ButtonLike, ContextMenu, Indicator, KeyBinding, POPOVER_Y_PADDING, Tooltip, prelude::*,
@@ -8448,7 +8449,7 @@ pub(crate) fn render_buffer_header(
el.child(Icon::new(IconName::FileLock).color(Color::Muted))
})
.when_some(breadcrumbs, |then, breadcrumbs| {
- let font = theme::ThemeSettings::get_global(cx)
+ let font = theme_settings::ThemeSettings::get_global(cx)
.buffer_font
.clone();
then.child(render_breadcrumb_text(
@@ -746,7 +746,7 @@ mod tests {
let settings = SettingsStore::test(cx);
cx.set_global(settings);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
crate::init(cx);
});
@@ -26,7 +26,7 @@ use std::{
};
use std::{ops::Range, sync::Arc, time::Duration};
use std::{path::PathBuf, rc::Rc};
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{CopyButton, Scrollbars, WithScrollbar, prelude::*, theme_is_transparent};
use url::Url;
use util::TryFutureExt;
@@ -4798,7 +4798,7 @@ let c = 3;"#
cx.update(|cx| {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
release_channel::init(semver::Version::new(0, 0, 0), cx);
crate::init(cx);
});
@@ -980,7 +980,9 @@ impl Item for Editor {
// In a non-singleton case, the breadcrumbs are actually shown on sticky file headers of the multibuffer.
fn breadcrumbs(&self, cx: &App) -> Option<(Vec<HighlightedText>, Option<Font>)> {
if self.buffer.read(cx).is_singleton() {
- let font = theme::ThemeSettings::get_global(cx).buffer_font.clone();
+ let font = theme_settings::ThemeSettings::get_global(cx)
+ .buffer_font
+ .clone();
Some((self.breadcrumbs_inner(cx)?, Some(font)))
} else {
None
@@ -1393,7 +1393,7 @@ mod tests {
fn init_test(cx: &mut gpui::App) {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
crate::init(cx);
}
}
@@ -1383,7 +1383,7 @@ mod tests {
async fn test_theme_override_changes_restyle_semantic_tokens(cx: &mut TestAppContext) {
use collections::IndexMap;
use gpui::{Hsla, Rgba, UpdateGlobal as _};
- use theme::{HighlightStyleContent, ThemeStyleContent};
+ use theme_settings::{HighlightStyleContent, ThemeStyleContent};
init_test(cx, |_| {});
@@ -1548,7 +1548,7 @@ mod tests {
async fn test_per_theme_overrides_restyle_semantic_tokens(cx: &mut TestAppContext) {
use collections::IndexMap;
use gpui::{Hsla, Rgba, UpdateGlobal as _};
- use theme::{HighlightStyleContent, ThemeStyleContent};
+ use theme_settings::{HighlightStyleContent, ThemeStyleContent};
use ui::ActiveTheme as _;
init_test(cx, |_| {});
@@ -13,7 +13,7 @@ use settings::Settings;
use std::ops::Range;
use std::time::Duration;
use text::Rope;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{
ActiveTheme, AnyElement, ButtonCommon, ButtonStyle, Clickable, FluentBuilder, IconButton,
IconButtonShape, IconName, IconSize, InteractiveElement, IntoElement, Label, LabelCommon,
@@ -2118,7 +2118,7 @@ mod tests {
cx.update(|cx| {
let store = SettingsStore::test(cx);
cx.set_global(store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
crate::init(cx);
});
let project = Project::test(FakeFs::new(cx.executor()), [], cx).await;
@@ -29,7 +29,7 @@ serde_json_lenient.workspace = true
settings_content.workspace = true
snippet_provider.workspace = true
task.workspace = true
-theme.workspace = true
+theme_settings.workspace = true
tokio = { workspace = true, features = ["full"] }
toml.workspace = true
tree-sitter.workspace = true
@@ -413,7 +413,8 @@ async fn test_themes(
) -> Result<()> {
for relative_theme_path in &manifest.themes {
let theme_path = extension_path.join(relative_theme_path);
- let theme_family = theme::deserialize_user_theme(&fs.load_bytes(&theme_path).await?)?;
+ let theme_family =
+ theme_settings::deserialize_user_theme(&fs.load_bytes(&theme_path).await?)?;
log::info!("loaded theme family {}", theme_family.name);
for theme in &theme_family.themes {
@@ -68,6 +68,7 @@ project = { workspace = true, features = ["test-support"] }
reqwest_client.workspace = true
theme = { workspace = true, features = ["test-support"] }
+theme_settings.workspace = true
theme_extension.workspace = true
zlog.workspace = true
@@ -1007,7 +1007,7 @@ fn init_test(cx: &mut TestAppContext) {
cx.set_global(store);
release_channel::init(semver::Version::new(0, 0, 0), cx);
extension::init(cx);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
gpui_tokio::init(cx);
});
}
@@ -35,7 +35,7 @@ settings.workspace = true
smallvec.workspace = true
strum.workspace = true
telemetry.workspace = true
-theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
util.workspace = true
vim_mode_setting.workspace = true
@@ -23,7 +23,7 @@ use project::DirectoryLister;
use release_channel::ReleaseChannel;
use settings::{Settings, SettingsContent};
use strum::IntoEnumIterator as _;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{
Banner, Chip, ContextMenu, Divider, PopoverMenu, ScrollableHandle, Switch, ToggleButtonGroup,
ToggleButtonGroupSize, ToggleButtonGroupStyle, ToggleButtonSimple, Tooltip, WithScrollbar,
@@ -47,3 +47,4 @@ theme = { workspace = true, features = ["test-support"] }
workspace = { workspace = true, features = ["test-support"] }
zlog.workspace = true
remote_connection = { workspace = true, features = ["test-support"] }
+theme_settings = { workspace = true, features = ["test-support"] }
@@ -3789,7 +3789,7 @@ async fn open_queried_buffer(
fn init_test(cx: &mut TestAppContext) -> Arc<AppState> {
cx.update(|cx| {
let state = AppState::test(cx);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
super::init(cx);
editor::init(cx);
state
@@ -32,6 +32,7 @@ project.workspace = true
settings.workspace = true
smallvec.workspace = true
theme.workspace = true
+theme_settings.workspace = true
time.workspace = true
ui.workspace = true
workspace.workspace = true
@@ -33,7 +33,8 @@ use std::{
sync::OnceLock,
time::{Duration, Instant},
};
-use theme::{AccentColors, ThemeSettings};
+use theme::AccentColors;
+use theme_settings::ThemeSettings;
use time::{OffsetDateTime, UtcOffset, format_description::BorrowedFormatItem};
use ui::{
ButtonLike, Chip, CommonAnimationExt as _, ContextMenu, DiffStat, Divider, ScrollableHandle,
@@ -2489,7 +2490,7 @@ mod tests {
cx.update(|cx| {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
});
}
@@ -56,6 +56,7 @@ smol.workspace = true
strum.workspace = true
telemetry.workspace = true
theme.workspace = true
+theme_settings.workspace = true
time.workspace = true
time_format.workspace = true
ui.workspace = true
@@ -11,7 +11,7 @@ use gpui::{
use markdown::{Markdown, MarkdownElement};
use project::{git_store::Repository, project_settings::ProjectSettings};
use settings::Settings as _;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use time::OffsetDateTime;
use ui::{ContextMenu, CopyButton, Divider, prelude::*, tooltip_container};
use workspace::Workspace;
@@ -1325,7 +1325,7 @@ mod tests {
cx.update(|cx| {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
editor::init(cx);
});
}
@@ -12,7 +12,7 @@ use markdown::{Markdown, MarkdownElement};
use project::git_store::Repository;
use settings::Settings;
use std::hash::Hash;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use time::{OffsetDateTime, UtcOffset};
use ui::{Avatar, CopyButton, Divider, prelude::*, tooltip_container};
use workspace::Workspace;
@@ -379,7 +379,7 @@ mod tests {
cx.update(|cx| {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
});
}
@@ -66,7 +66,7 @@ use std::ops::Range;
use std::path::Path;
use std::{sync::Arc, time::Duration, usize};
use strum::{IntoEnumIterator, VariantNames};
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use time::OffsetDateTime;
use ui::{
ButtonLike, Checkbox, CommonAnimationExt, ContextMenu, ElevationIndex, IndentGuideColors,
@@ -6491,7 +6491,7 @@ mod tests {
cx.update(|cx| {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
- theme::init(LoadThemes::JustBase, cx);
+ theme_settings::init(LoadThemes::JustBase, cx);
editor::init(cx);
crate::init(cx);
});
@@ -1777,7 +1777,7 @@ mod tests {
settings.editor.diff_view_style = Some(DiffViewStyle::Unified);
});
});
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
editor::init(cx);
crate::init(cx);
});
@@ -632,7 +632,7 @@ mod tests {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
editor::init(cx);
})
}
@@ -499,7 +499,7 @@ mod tests {
settings.editor.diff_view_style = Some(DiffViewStyle::Unified);
});
});
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
});
}
@@ -26,7 +26,7 @@ log.workspace = true
project.workspace = true
serde.workspace = true
settings.workspace = true
-theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
util.workspace = true
workspace.workspace = true
@@ -19,7 +19,7 @@ use language::File as _;
use persistence::ImageViewerDb;
use project::{ImageItem, Project, ProjectPath, image_store::ImageItemEvent};
use settings::Settings;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{Tooltip, prelude::*};
use util::paths::PathExt;
use workspace::{
@@ -21,7 +21,7 @@ language.workspace = true
project.workspace = true
serde_json.workspace = true
serde_json_lenient.workspace = true
-theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
util.workspace = true
util_macros.workspace = true
@@ -57,7 +57,7 @@ fn render_inspector(
window: &mut Window,
cx: &mut Context<Inspector>,
) -> AnyElement {
- let ui_font = theme::setup_ui_font(window, cx);
+ let ui_font = theme_settings::setup_ui_font(window, cx);
let colors = cx.theme().colors();
let inspector_id = inspector.active_element_id();
let toolbar_height = platform_title_bar_height(window);
@@ -36,6 +36,7 @@ settings.workspace = true
telemetry.workspace = true
tempfile.workspace = true
theme.workspace = true
+theme_settings.workspace = true
tree-sitter-json.workspace = true
tree-sitter-rust.workspace = true
ui_input.workspace = true
@@ -3431,7 +3431,7 @@ impl ActionArgumentsEditor {
impl Render for ActionArgumentsEditor {
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
- let settings = theme::ThemeSettings::get_global(cx);
+ let settings = theme_settings::ThemeSettings::get_global(cx);
let colors = cx.theme().colors();
let border_color = if self.is_loading {
@@ -1115,7 +1115,7 @@ mod tests {
cx.update(|cx| {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
});
let fs = FakeFs::new(cx.executor());
@@ -102,6 +102,7 @@ unindent.workspace = true
util = { workspace = true, features = ["test-support"] }
zlog.workspace = true
criterion.workspace = true
+theme_settings.workspace = true
[[bench]]
name = "highlight_map"
@@ -3247,7 +3247,7 @@ fn test_undo_after_merge_into_base(cx: &mut TestAppContext) {
async fn test_preview_edits(cx: &mut TestAppContext) {
cx.update(|cx| {
init_settings(cx, |_| {});
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
});
let insertion_style = HighlightStyle {
@@ -44,4 +44,5 @@ release_channel.workspace = true
gpui = { workspace = true, features = ["test-support"] }
semver.workspace = true
util = { workspace = true, features = ["test-support"] }
-zlog.workspace = true
+zlog.workspace = true
+theme_settings.workspace = true
@@ -109,7 +109,7 @@ fn init_test(cx: &mut gpui::TestAppContext) {
cx.update(|cx| {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
release_channel::init(semver::Version::new(0, 0, 0), cx);
});
}
@@ -35,6 +35,7 @@ settings.workspace = true
stacksafe.workspace = true
sum_tree.workspace = true
theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
util.workspace = true
@@ -41,7 +41,7 @@ pub fn main() {
cx.bind_keys([KeyBinding::new("cmd-c", markdown::Copy, None)]);
let node_runtime = NodeRuntime::unavailable();
- theme::init(LoadThemes::JustBase, cx);
+ theme_settings::init(LoadThemes::JustBase, cx);
let fs = fs::FakeFs::new(cx.background_executor().clone());
let language_registry = LanguageRegistry::new(cx.background_executor().clone());
@@ -28,7 +28,7 @@ pub fn main() {
let language_registry = Arc::new(LanguageRegistry::new(cx.background_executor().clone()));
let fs = fs::FakeFs::new(cx.background_executor().clone());
languages::init(language_registry, fs, node_runtime, cx);
- theme::init(LoadThemes::JustBase, cx);
+ theme_settings::init(LoadThemes::JustBase, cx);
Assets.load_fonts(cx).unwrap();
cx.activate(true);
@@ -505,7 +505,7 @@ mod tests {
settings::init(cx);
}
if !cx.has_global::<theme::GlobalTheme>() {
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
}
});
}
@@ -16,7 +16,7 @@ use mermaid::{
};
pub use path_range::{LineCol, PathWithRange};
use settings::Settings as _;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::Checkbox;
use ui::CopyButton;
@@ -2677,7 +2677,7 @@ mod tests {
settings::init(cx);
}
if !cx.has_global::<theme::GlobalTheme>() {
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
}
});
}
@@ -278,7 +278,7 @@ mod tests {
settings::init(cx);
}
if !cx.has_global::<theme::GlobalTheme>() {
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
}
});
}
@@ -22,7 +22,7 @@ language.workspace = true
log.workspace = true
markdown.workspace = true
settings.workspace = true
-theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
urlencoding.workspace = true
util.workspace = true
@@ -16,7 +16,7 @@ use markdown::{
CodeBlockRenderer, Markdown, MarkdownElement, MarkdownFont, MarkdownOptions, MarkdownStyle,
};
use settings::Settings;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{WithScrollbar, prelude::*};
use util::normalize_path;
use workspace::item::{Item, ItemHandle};
@@ -14,7 +14,7 @@ path = "src/miniprofiler_ui.rs"
[dependencies]
gpui.workspace = true
rpc.workspace = true
-theme.workspace = true
+theme_settings.workspace = true
zed_actions.workspace = true
workspace.workspace = true
util.workspace = true
@@ -456,7 +456,7 @@ impl Render for ProfilerWindow {
window: &mut gpui::Window,
cx: &mut gpui::Context<Self>,
) -> impl gpui::IntoElement {
- let ui_font = theme::setup_ui_font(window, cx);
+ let ui_font = theme_settings::setup_ui_font(window, cx);
if !self.paused {
self.poll_timings(cx);
window.request_animation_frame();
@@ -32,6 +32,7 @@ serde.workspace = true
settings.workspace = true
telemetry.workspace = true
theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
util.workspace = true
vim_mode_setting.workspace = true
@@ -5,10 +5,8 @@ use fs::Fs;
use gpui::{Action, App, IntoElement};
use project::project_settings::ProjectSettings;
use settings::{BaseKeymap, Settings, update_settings_file};
-use theme::{
- Appearance, SystemAppearance, ThemeAppearanceMode, ThemeName, ThemeRegistry, ThemeSelection,
- ThemeSettings,
-};
+use theme::{Appearance, SystemAppearance, ThemeRegistry};
+use theme_settings::{ThemeAppearanceMode, ThemeName, ThemeSelection, ThemeSettings};
use ui::{
Divider, StatefulInteractiveElement, SwitchField, TintColor, ToggleButtonGroup,
ToggleButtonGroupSize, ToggleButtonSimple, ToggleButtonWithIcon, Tooltip, prelude::*,
@@ -197,7 +195,7 @@ fn render_theme_section(tab_index: &mut isize, cx: &mut App) -> impl IntoElement
fn write_mode_change(mode: ThemeAppearanceMode, cx: &mut App) {
let fs = <dyn Fs>::global(cx);
update_settings_file(fs, cx, move |settings, _cx| {
- theme::set_mode(settings, mode);
+ theme_settings::set_mode(settings, mode);
});
}
@@ -219,13 +217,13 @@ fn render_theme_section(tab_index: &mut isize, cx: &mut App) -> impl IntoElement
dark: ThemeName(dark_theme.into()),
});
}
- ThemeAppearanceMode::Light => theme::set_theme(
+ ThemeAppearanceMode::Light => theme_settings::set_theme(
settings,
theme,
Appearance::Light,
*SystemAppearance::global(cx),
),
- ThemeAppearanceMode::Dark => theme::set_theme(
+ ThemeAppearanceMode::Dark => theme_settings::set_theme(
settings,
theme,
Appearance::Dark,
@@ -24,6 +24,7 @@ editor = {workspace = true, features = ["test-support"]}
gpui = {workspace = true, features = ["test-support"]}
serde_json.workspace = true
theme = {workspace = true, features = ["test-support"]}
+theme_settings.workspace = true
workspace = {workspace = true, features = ["test-support"]}
[lints]
@@ -410,7 +410,7 @@ async fn test_open_path_prompt_with_show_hidden(cx: &mut TestAppContext) {
fn init_test(cx: &mut TestAppContext) -> Arc<AppState> {
cx.update(|cx| {
let state = AppState::test(cx);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
editor::init(cx);
state
@@ -22,6 +22,7 @@ picker.workspace = true
settings.workspace = true
smol.workspace = true
theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
util.workspace = true
workspace.workspace = true
@@ -14,7 +14,8 @@ use language::{Outline, OutlineItem};
use ordered_float::OrderedFloat;
use picker::{Picker, PickerDelegate};
use settings::Settings;
-use theme::{ActiveTheme, ThemeSettings};
+use theme::ActiveTheme;
+use theme_settings::ThemeSettings;
use ui::{ListItem, ListItemSpacing, prelude::*};
use util::ResultExt;
use workspace::{DismissDecision, ModalView};
@@ -33,6 +33,7 @@ settings.workspace = true
smallvec.workspace = true
smol.workspace = true
theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
util.workspace = true
workspace.workspace = true
@@ -47,7 +47,8 @@ use search::{BufferSearchBar, ProjectSearchView};
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsStore};
use smol::channel;
-use theme::{SyntaxTheme, ThemeSettings};
+use theme::SyntaxTheme;
+use theme_settings::ThemeSettings;
use ui::{
ContextMenu, FluentBuilder, HighlightedLabel, IconButton, IconButtonShape, IndentGuideColors,
IndentGuideLayout, ListItem, ScrollAxes, Scrollbars, Tab, Tooltip, WithScrollbar, prelude::*,
@@ -6899,7 +6900,7 @@ outline: struct OutlineEntryExcerpt
let settings = SettingsStore::test(cx);
cx.set_global(settings);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
editor::init(cx);
project_search::init(cx);
@@ -22,6 +22,7 @@ menu.workspace = true
schemars.workspace = true
serde.workspace = true
theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
ui_input.workspace = true
workspace.workspace = true
@@ -16,7 +16,7 @@ use serde::Deserialize;
use std::{
cell::Cell, cell::RefCell, collections::HashMap, ops::Range, rc::Rc, sync::Arc, time::Duration,
};
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{
Color, Divider, DocumentationAside, DocumentationSide, Label, ListItem, ListItemSpacing,
ScrollAxes, Scrollbars, WithScrollbar, prelude::*, utils::WithRemSize, v_flex,
@@ -955,7 +955,7 @@ mod tests {
cx.update(|cx| {
let store = settings::SettingsStore::test(cx);
cx.set_global(store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
editor::init(cx);
});
}
@@ -19,6 +19,7 @@ project.workspace = true
settings.workspace = true
smallvec.workspace = true
theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
workspace.workspace = true
zed_actions.workspace = true
@@ -5,7 +5,7 @@ use gpui::{
Styled, SystemWindowTab, SystemWindowTabController, Window, WindowId, actions, canvas, div,
};
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{
Color, ContextMenu, DynamicSpacing, IconButton, IconButtonShape, IconName, IconSize, Label,
LabelSize, Tab, h_flex, prelude::*, right_click_menu,
@@ -36,6 +36,7 @@ serde_json.workspace = true
settings.workspace = true
smallvec.workspace = true
theme.workspace = true
+theme_settings.workspace = true
rayon.workspace = true
ui.workspace = true
util.workspace = true
@@ -58,7 +58,7 @@ use std::{
sync::Arc,
time::Duration,
};
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{
Color, ContextMenu, ContextMenuEntry, DecoratedIcon, Divider, Icon, IconDecoration,
IconDecorationKind, IndentGuideColors, IndentGuideLayout, Indicator, KeyBinding, Label,
@@ -10428,7 +10428,7 @@ pub(crate) fn init_test(cx: &mut TestAppContext) {
cx.update(|cx| {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
crate::init(cx);
cx.update_global::<SettingsStore, _>(|store, cx| {
@@ -10446,7 +10446,7 @@ pub(crate) fn init_test(cx: &mut TestAppContext) {
fn init_test_with_editor(cx: &mut TestAppContext) {
cx.update(|cx| {
let app_state = AppState::test(cx);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
editor::init(cx);
crate::init(cx);
workspace::init(app_state, cx);
@@ -23,6 +23,7 @@ project.workspace = true
serde_json.workspace = true
settings.workspace = true
theme.workspace = true
+theme_settings.workspace = true
util.workspace = true
workspace.workspace = true
@@ -9,7 +9,8 @@ use picker::{Picker, PickerDelegate};
use project::{Project, Symbol, lsp_store::SymbolLocation};
use settings::Settings;
use std::{cmp::Reverse, sync::Arc};
-use theme::{ActiveTheme, ThemeSettings};
+use theme::ActiveTheme;
+use theme_settings::ThemeSettings;
use util::ResultExt;
use workspace::{
Workspace,
@@ -477,7 +478,7 @@ mod tests {
cx.update(|cx| {
let store = SettingsStore::test(cx);
cx.set_global(store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
release_channel::init(semver::Version::new(0, 0, 0), cx);
editor::init(cx);
});
@@ -28,7 +28,7 @@ release_channel.workspace = true
remote.workspace = true
semver.workspace = true
settings.workspace = true
-theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
ui_input.workspace = true
workspace.workspace = true
@@ -13,7 +13,7 @@ use release_channel::ReleaseChannel;
use remote::{ConnectionIdentifier, RemoteClient, RemoteConnectionOptions, RemotePlatform};
use semver::Version;
use settings::Settings;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{
ActiveTheme, CommonAnimationExt, Context, InteractiveElement, KeyBinding, ListItem, Tooltip,
prelude::*,
@@ -98,6 +98,7 @@ node_runtime = { workspace = true, features = ["test-support"] }
pretty_assertions.workspace = true
project = { workspace = true, features = ["test-support"] }
remote = { workspace = true, features = ["test-support"] }
+theme_settings.workspace = true
theme = { workspace = true, features = ["test-support"] }
language_model = { workspace = true, features = ["test-support"] }
lsp = { workspace = true, features = ["test-support"] }
@@ -1661,7 +1661,7 @@ async fn test_remote_git_diffs_when_recv_update_repository_delay(
cx.update(|cx| {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
release_channel::init(semver::Version::new(0, 0, 0), cx);
editor::init(cx);
});
@@ -53,6 +53,7 @@ telemetry.workspace = true
terminal.workspace = true
terminal_view.workspace = true
theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
util.workspace = true
uuid.workspace = true
@@ -12,7 +12,7 @@ use markdown::{Markdown, MarkdownElement, MarkdownStyle};
use nbformat::v4::{CellId, CellMetadata, CellType};
use runtimelib::{JupyterMessage, JupyterMessageContent};
use settings::Settings as _;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{CommonAnimationExt, IconButtonShape, prelude::*};
use util::ResultExt;
@@ -895,7 +895,7 @@ mod tests {
cx.update(|cx| {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
});
let fs = project::FakeFs::new(cx.background_executor.clone());
let project = project::Project::test(fs, [] as [&Path; 0], cx).await;
@@ -27,7 +27,7 @@ use language::Buffer;
use settings::Settings as _;
use terminal::terminal_settings::TerminalSettings;
use terminal_view::terminal_element::TerminalElement;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{IntoElement, prelude::*};
use crate::outputs::OutputContent;
@@ -275,7 +275,7 @@ mod tests {
cx.update(|cx| {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
});
cx.add_empty_window()
}
@@ -59,7 +59,7 @@ use runtimelib::datatable::TableSchema;
use runtimelib::media::datatable::TabularDataResource;
use serde_json::Value;
use settings::Settings;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{IntoElement, Styled, div, prelude::*, v_flex};
use util::markdown::MarkdownEscaped;
@@ -28,7 +28,7 @@ release_channel.workspace = true
rope.workspace = true
serde.workspace = true
settings.workspace = true
-theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
ui_input.workspace = true
util.workspace = true
@@ -20,7 +20,7 @@ use std::rc::Rc;
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::time::Duration;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{Divider, ListItem, ListItemSpacing, ListSubHeader, Tooltip, prelude::*};
use ui_input::ErasedEditor;
use util::{ResultExt, TryFutureExt};
@@ -1392,7 +1392,7 @@ impl RulesLibrary {
impl Render for RulesLibrary {
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
- let ui_font = theme::setup_ui_font(window, cx);
+ let ui_font = theme_settings::setup_ui_font(window, cx);
let theme = cx.theme().clone();
client_side_decorations(
@@ -17,3 +17,4 @@ serde.workspace = true
serde_json.workspace = true
settings.workspace = true
theme.workspace = true
+theme_settings.workspace = true
@@ -2,7 +2,8 @@ use anyhow::Result;
use clap::{Parser, ValueEnum};
use schemars::schema_for;
use settings::ProjectSettingsContent;
-use theme::{IconThemeFamilyContent, ThemeFamilyContent};
+use theme::IconThemeFamilyContent;
+use theme_settings::ThemeFamilyContent;
#[derive(Parser, Debug)]
pub struct Args {
@@ -38,6 +38,7 @@ serde_json.workspace = true
settings.workspace = true
smol.workspace = true
theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
util.workspace = true
util_macros.workspace = true
@@ -1906,7 +1906,7 @@ mod tests {
cx.set_global(store);
editor::init(cx);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
crate::init(cx);
});
}
@@ -5143,7 +5143,7 @@ pub mod tests {
let settings = SettingsStore::test(cx);
cx.set_global(settings);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
editor::init(cx);
crate::init(cx);
@@ -1,7 +1,7 @@
use editor::{Editor, EditorElement, EditorStyle, MultiBufferOffset, ToOffset};
use gpui::{Action, App, Entity, FocusHandle, Hsla, IntoElement, TextStyle};
use settings::Settings;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{IconButton, IconButtonShape};
use ui::{Tooltip, prelude::*};
@@ -29,4 +29,5 @@ project = { workspace = true, features = ["test-support"] }
serde_json.workspace = true
settings = { workspace = true, features = ["test-support"] }
theme = { workspace = true, features = ["test-support"] }
+theme_settings.workspace = true
workspace = { workspace = true, features = ["test-support"] }
@@ -286,7 +286,7 @@ mod tests {
use project::{FakeFs, Project};
use serde_json::json;
use settings::Settings;
- use theme::{self, ThemeSettings};
+ use theme_settings::ThemeSettings;
use workspace::{self, AppState, MultiWorkspace};
use zed_actions::settings_profile_selector;
@@ -299,7 +299,7 @@ mod tests {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
settings::init(cx);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
super::init(cx);
editor::init(cx);
state
@@ -54,6 +54,7 @@ shell_command_parser.workspace = true
strum.workspace = true
telemetry.workspace = true
theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
util.workspace = true
workspace.workspace = true
@@ -3,7 +3,7 @@ use std::rc::Rc;
use editor::Editor;
use gpui::{AnyElement, ElementId, Focusable, TextStyleRefinement};
use settings::Settings as _;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{Tooltip, prelude::*, rems};
#[derive(IntoElement)]
@@ -411,9 +411,9 @@ fn appearance_page() -> SettingsPage {
settings::ThemeSelection::Static(_) => return,
settings::ThemeSelection::Dynamic { mode, light, dark } => {
match mode {
- theme::ThemeAppearanceMode::Light => light.clone(),
- theme::ThemeAppearanceMode::Dark => dark.clone(),
- theme::ThemeAppearanceMode::System => dark.clone(), // no cx, can't determine correct choice
+ theme_settings::ThemeAppearanceMode::Light => light.clone(),
+ theme_settings::ThemeAppearanceMode::Dark => dark.clone(),
+ theme_settings::ThemeAppearanceMode::System => dark.clone(), // no cx, can't determine correct choice
}
},
};
@@ -581,9 +581,9 @@ fn appearance_page() -> SettingsPage {
settings::IconThemeSelection::Static(_) => return,
settings::IconThemeSelection::Dynamic { mode, light, dark } => {
match mode {
- theme::ThemeAppearanceMode::Light => light.clone(),
- theme::ThemeAppearanceMode::Dark => dark.clone(),
- theme::ThemeAppearanceMode::System => dark.clone(), // no cx, can't determine correct choice
+ theme_settings::ThemeAppearanceMode::Light => light.clone(),
+ theme_settings::ThemeAppearanceMode::Dark => dark.clone(),
+ theme_settings::ThemeAppearanceMode::System => dark.clone(), // no cx, can't determine correct choice
}
},
};
@@ -802,7 +802,8 @@ fn appearance_page() -> SettingsPage {
}
settings::BufferLineHeightDiscriminants::Custom => {
let custom_value =
- theme::BufferLineHeight::from(*settings_value).value();
+ theme_settings::BufferLineHeight::from(*settings_value)
+ .value();
settings::BufferLineHeight::Custom(custom_value)
}
};
@@ -7,7 +7,7 @@ use gpui::{
use settings::{Settings as _, SettingsStore, ToolPermissionMode};
use shell_command_parser::extract_commands;
use std::sync::Arc;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{Banner, ContextMenu, Divider, PopoverMenu, Severity, Tooltip, prelude::*};
use util::ResultExt as _;
use util::shell::ShellKind;
@@ -33,7 +33,7 @@ use std::{
sync::{Arc, LazyLock, RwLock},
time::Duration,
};
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{
Banner, ContextMenu, Divider, DropdownMenu, DropdownStyle, IconButtonShape, KeyBinding,
KeybindingHint, PopoverMenu, Scrollbars, Switch, Tooltip, TreeViewItem, WithScrollbar,
@@ -639,7 +639,9 @@ pub fn open_settings_editor(
// We have to defer this to get the workspace off the stack.
let path = path.map(ToOwned::to_owned);
cx.defer(move |cx| {
- let current_rem_size: f32 = theme::ThemeSettings::get_global(cx).ui_font_size(cx).into();
+ let current_rem_size: f32 = theme_settings::ThemeSettings::get_global(cx)
+ .ui_font_size(cx)
+ .into();
let default_bounds = DEFAULT_ADDITIONAL_WINDOW_SIZE;
let default_rem_size = 16.0;
@@ -3650,7 +3652,7 @@ impl SettingsWindow {
impl Render for SettingsWindow {
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
- let ui_font = theme::setup_ui_font(window, cx);
+ let ui_font = theme_settings::setup_ui_font(window, cx);
client_side_decorations(
v_flex()
@@ -4410,7 +4412,7 @@ pub mod test {
pub fn register_settings(cx: &mut App) {
settings::init(cx);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
editor::init(cx);
menu::init();
}
@@ -5075,7 +5077,7 @@ mod project_settings_update_tests {
cx.update(|cx| {
let store = settings::SettingsStore::test(cx);
cx.set_global(store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
editor::init(cx);
menu::init();
let queue = ProjectSettingsUpdateQueue::new(cx);
@@ -33,6 +33,7 @@ project.workspace = true
recent_projects.workspace = true
settings.workspace = true
theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
util.workspace = true
vim_mode_setting.workspace = true
@@ -223,7 +223,7 @@ mod tests {
cx.update(|cx| {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
});
}
@@ -3069,7 +3069,7 @@ impl Focusable for Sidebar {
impl Render for Sidebar {
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let _titlebar_height = ui::utils::platform_title_bar_height(window);
- let ui_font = theme::setup_ui_font(window, cx);
+ let ui_font = theme_settings::setup_ui_font(window, cx);
let sticky_header = self.render_sticky_header(window, cx);
let color = cx.theme().colors();
@@ -3219,7 +3219,7 @@ mod tests {
cx.update(|cx| {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
editor::init(cx);
cx.update_flags(false, vec!["agent-v2".into()]);
ThreadStore::init_global(cx);
@@ -29,6 +29,7 @@ picker.workspace = true
reqwest_client.workspace = true
rust-embed.workspace = true
settings.workspace = true
+theme_settings.workspace = true
simplelog.workspace = true
story.workspace = true
strum = { workspace = true, features = ["derive"] }
@@ -15,10 +15,10 @@ use gpui::{
};
use log::LevelFilter;
use reqwest_client::ReqwestClient;
-use settings::{KeymapFile, Settings};
+use settings::{KeymapFile, Settings as _};
use simplelog::SimpleLogger;
use strum::IntoEnumIterator;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::prelude::*;
use crate::app_menus::app_menus;
@@ -76,13 +76,13 @@ fn main() {
cx.set_http_client(Arc::new(http_client));
settings::init(cx);
- theme::init(theme::LoadThemes::All(Box::new(Assets)), cx);
+ theme_settings::init(theme::LoadThemes::All(Box::new(Assets)), cx);
let selector = story_selector;
let mut theme_settings = ThemeSettings::get_global(cx).clone();
theme_settings.theme =
- theme::ThemeSelection::Static(settings::ThemeName(theme_name.into()));
+ theme_settings::ThemeSelection::Static(settings::ThemeName(theme_name.into()));
ThemeSettings::override_global(theme_settings, cx);
editor::init(cx);
@@ -98,7 +98,7 @@ fn main() {
..Default::default()
},
move |window, cx| {
- theme::setup_ui_font(window, cx);
+ theme_settings::setup_ui_font(window, cx);
cx.new(|cx| StoryWrapper::new(selector.story(window, cx)))
},
@@ -33,5 +33,6 @@ ctor.workspace = true
gpui = { workspace = true, features = ["test-support"] }
serde_json.workspace = true
theme = { workspace = true, features = ["test-support"] }
+theme_settings.workspace = true
workspace = { workspace = true, features = ["test-support"] }
zlog.workspace = true
@@ -258,7 +258,7 @@ async fn test_close_selected_item(cx: &mut gpui::TestAppContext) {
fn init_test(cx: &mut TestAppContext) -> Arc<AppState> {
cx.update(|cx| {
let state = AppState::test(cx);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
super::init(cx);
editor::init(cx);
state
@@ -37,6 +37,7 @@ sysinfo.workspace = true
smol.workspace = true
task.workspace = true
theme.workspace = true
+theme_settings.workspace = true
thiserror.workspace = true
url.workspace = true
util.workspace = true
@@ -2579,7 +2579,7 @@ mod tests {
cx.update(|cx| {
let settings_store = settings::SettingsStore::test(cx);
cx.set_global(settings_store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
});
}
@@ -14,7 +14,7 @@ use settings::{
merge_from::MergeFrom,
};
use task::Shell;
-use theme::FontFamilyName;
+use theme_settings::FontFamilyName;
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
pub struct Toolbar {
@@ -42,6 +42,7 @@ settings.workspace = true
shellexpand.workspace = true
terminal.workspace = true
theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
util.workspace = true
workspace.workspace = true
@@ -25,7 +25,8 @@ use terminal::{
},
terminal_settings::TerminalSettings,
};
-use theme::{ActiveTheme, Theme, ThemeSettings};
+use theme::{ActiveTheme, Theme};
+use theme_settings::ThemeSettings;
use ui::utils::ensure_minimum_contrast;
use ui::{ParentElement, Tooltip};
use util::ResultExt;
@@ -913,7 +914,9 @@ impl Element for TerminalElement {
}
TerminalMode::Standalone => terminal_settings
.font_size
- .map_or(buffer_font_size, |size| theme::adjusted_font_size(size, cx)),
+ .map_or(buffer_font_size, |size| {
+ theme_settings::adjusted_font_size(size, cx)
+ }),
};
let theme = cx.theme().clone();
@@ -2346,7 +2346,7 @@ mod tests {
cx.update(|cx| {
let store = SettingsStore::test(cx);
cx.set_global(store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
editor::init(cx);
crate::init(cx);
});
@@ -554,7 +554,7 @@ mod tests {
let fs = app_cx.update(AppState::test).fs.as_fake().clone();
app_cx.update(|cx| {
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
editor::init(cx);
});
@@ -2208,7 +2208,7 @@ mod tests {
) {
let params = cx.update(AppState::test);
cx.update(|cx| {
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
});
let project = Project::test(params.fs.clone(), [], cx).await;
@@ -10,7 +10,7 @@ workspace = true
[features]
default = []
-test-support = ["gpui/test-support", "settings/test-support"]
+test-support = ["gpui/test-support"]
[lib]
path = "src/theme.rs"
@@ -21,8 +21,6 @@ anyhow.workspace = true
collections.workspace = true
derive_more.workspace = true
gpui.workspace = true
-gpui_util.workspace = true
-log.workspace = true
palette = { workspace = true, default-features = false, features = ["std"] }
parking_lot.workspace = true
refineable.workspace = true
@@ -30,11 +28,9 @@ schemars = { workspace = true, features = ["indexmap2"] }
serde.workspace = true
serde_json.workspace = true
serde_json_lenient.workspace = true
-settings.workspace = true
strum.workspace = true
thiserror.workspace = true
uuid.workspace = true
[dev-dependencies]
gpui = { workspace = true, features = ["test-support"] }
-settings = { workspace = true, features = ["test-support"] }
@@ -25,7 +25,8 @@ pub fn zed_default_themes() -> ThemeFamily {
// If a theme customizes a foreground version of a status color, but does not
// customize the background color, then use a partly-transparent version of the
// foreground color for the background color.
-pub(crate) fn apply_status_color_defaults(status: &mut StatusColorsRefinement) {
+/// Applies default status color backgrounds from their foreground counterparts.
+pub fn apply_status_color_defaults(status: &mut StatusColorsRefinement) {
for (fg_color, bg_color) in [
(&status.deleted, &mut status.deleted_background),
(&status.created, &mut status.created_background),
@@ -42,7 +43,8 @@ pub(crate) fn apply_status_color_defaults(status: &mut StatusColorsRefinement) {
}
}
-pub(crate) fn apply_theme_color_defaults(
+/// Applies default theme color values derived from player colors.
+pub fn apply_theme_color_defaults(
theme_colors: &mut ThemeColorsRefinement,
player_colors: &PlayerColors,
) {
@@ -416,7 +416,7 @@ fn icon_keys_by_association(
}
/// The name of the default icon theme.
-pub(crate) const DEFAULT_ICON_THEME_NAME: &str = "Zed (Default)";
+pub const DEFAULT_ICON_THEME_NAME: &str = "Zed (Default)";
static DEFAULT_ICON_THEME: LazyLock<Arc<IconTheme>> = LazyLock::new(|| {
Arc::new(IconTheme {
@@ -1,18 +1,16 @@
use std::sync::Arc;
use std::{fmt::Debug, path::Path};
-use anyhow::{Context as _, Result};
+use anyhow::Result;
use collections::HashMap;
use derive_more::{Deref, DerefMut};
use gpui::{App, AssetSource, Global, SharedString};
-use gpui_util::ResultExt;
use parking_lot::RwLock;
use thiserror::Error;
use crate::{
Appearance, AppearanceContent, ChevronIcons, DEFAULT_ICON_THEME_NAME, DirectoryIcons,
- IconDefinition, IconTheme, IconThemeFamilyContent, Theme, ThemeFamily, ThemeFamilyContent,
- default_icon_theme, deserialize_user_theme, refine_theme_family,
+ IconDefinition, IconTheme, IconThemeFamilyContent, Theme, ThemeFamily, default_icon_theme,
};
/// The metadata for a theme.
@@ -81,6 +79,11 @@ impl ThemeRegistry {
cx.set_global(GlobalThemeRegistry(Arc::new(ThemeRegistry::new(assets))));
}
+ /// Returns the asset source used by this registry.
+ pub fn assets(&self) -> &dyn AssetSource {
+ self.assets.as_ref()
+ }
+
/// Creates a new [`ThemeRegistry`] with the given [`AssetSource`].
pub fn new(assets: Box<dyn AssetSource>) -> Self {
let registry = Self {
@@ -116,28 +119,21 @@ impl ThemeRegistry {
self.state.write().extensions_loaded = true;
}
- fn insert_theme_families(&self, families: impl IntoIterator<Item = ThemeFamily>) {
+ /// Inserts the given theme families into the registry.
+ pub fn insert_theme_families(&self, families: impl IntoIterator<Item = ThemeFamily>) {
for family in families.into_iter() {
self.insert_themes(family.themes);
}
}
- fn insert_themes(&self, themes: impl IntoIterator<Item = Theme>) {
+ /// Inserts the given themes into the registry.
+ pub fn insert_themes(&self, themes: impl IntoIterator<Item = Theme>) {
let mut state = self.state.write();
for theme in themes.into_iter() {
state.themes.insert(theme.name.clone(), Arc::new(theme));
}
}
- #[allow(unused)]
- fn insert_user_theme_families(&self, families: impl IntoIterator<Item = ThemeFamilyContent>) {
- for family in families.into_iter() {
- let refined_family = refine_theme_family(family);
-
- self.insert_themes(refined_family.themes);
- }
- }
-
/// Removes the themes with the given names from the registry.
pub fn remove_user_themes(&self, themes_to_remove: &[SharedString]) {
self.state
@@ -181,40 +177,6 @@ impl ThemeRegistry {
.cloned()
}
- /// Loads the themes bundled with the Zed binary and adds them to the registry.
- pub fn load_bundled_themes(&self) {
- let theme_paths = self
- .assets
- .list("themes/")
- .expect("failed to list theme assets")
- .into_iter()
- .filter(|path| path.ends_with(".json"));
-
- for path in theme_paths {
- let Some(theme) = self.assets.load(&path).log_err().flatten() else {
- continue;
- };
-
- let Some(theme_family) = serde_json::from_slice(&theme)
- .with_context(|| format!("failed to parse theme at path \"{path}\""))
- .log_err()
- else {
- continue;
- };
-
- self.insert_user_theme_families([theme_family]);
- }
- }
-
- /// Loads the user theme from the specified data and adds it to the registry.
- pub fn load_user_theme(&self, bytes: &[u8]) -> Result<()> {
- let theme = deserialize_user_theme(bytes)?;
-
- self.insert_user_theme_families([theme]);
-
- Ok(())
- }
-
/// Returns the default icon theme.
pub fn default_icon_theme(&self) -> Result<Arc<IconTheme>, IconThemeNotFoundError> {
self.get_icon_theme(DEFAULT_ICON_THEME_NAME)
@@ -1,30 +1,11 @@
#![allow(missing_docs)]
-use gpui::{HighlightStyle, Hsla};
+use gpui::Hsla;
use palette::FromColor;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
-use settings::IntoGpui;
-pub use settings::{FontWeightContent, WindowBackgroundContent};
-
-use crate::{StatusColorsRefinement, ThemeColorsRefinement};
-
-fn ensure_non_opaque(color: Hsla) -> Hsla {
- const MAXIMUM_OPACITY: f32 = 0.7;
- if color.a <= MAXIMUM_OPACITY {
- color
- } else {
- Hsla {
- a: MAXIMUM_OPACITY,
- ..color
- }
- }
-}
-
-fn ensure_opaque(color: Hsla) -> Hsla {
- Hsla { a: 1.0, ..color }
-}
+/// The appearance of a theme in serialized content.
#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum AppearanceContent {
@@ -32,819 +13,8 @@ pub enum AppearanceContent {
Dark,
}
-/// The content of a serialized theme family.
-#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
-pub struct ThemeFamilyContent {
- pub name: String,
- pub author: String,
- pub themes: Vec<ThemeContent>,
-}
-
-/// The content of a serialized theme.
-#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
-pub struct ThemeContent {
- pub name: String,
- pub appearance: AppearanceContent,
- pub style: settings::ThemeStyleContent,
-}
-
-/// Returns the syntax style overrides in the [`ThemeContent`].
-pub fn syntax_overrides(this: &settings::ThemeStyleContent) -> Vec<(String, HighlightStyle)> {
- this.syntax
- .iter()
- .map(|(key, style)| {
- (
- key.clone(),
- HighlightStyle {
- color: style
- .color
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- background_color: style
- .background_color
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- font_style: style.font_style.map(|s| s.into_gpui()),
- font_weight: style.font_weight.map(|w| w.into_gpui()),
- ..Default::default()
- },
- )
- })
- .collect()
-}
-
-pub fn status_colors_refinement(colors: &settings::StatusColorsContent) -> StatusColorsRefinement {
- StatusColorsRefinement {
- conflict: colors
- .conflict
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- conflict_background: colors
- .conflict_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- conflict_border: colors
- .conflict_border
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- created: colors
- .created
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- created_background: colors
- .created_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- created_border: colors
- .created_border
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- deleted: colors
- .deleted
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- deleted_background: colors
- .deleted_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- deleted_border: colors
- .deleted_border
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- error: colors
- .error
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- error_background: colors
- .error_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- error_border: colors
- .error_border
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- hidden: colors
- .hidden
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- hidden_background: colors
- .hidden_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- hidden_border: colors
- .hidden_border
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- hint: colors
- .hint
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- hint_background: colors
- .hint_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- hint_border: colors
- .hint_border
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- ignored: colors
- .ignored
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- ignored_background: colors
- .ignored_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- ignored_border: colors
- .ignored_border
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- info: colors
- .info
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- info_background: colors
- .info_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- info_border: colors
- .info_border
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- modified: colors
- .modified
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- modified_background: colors
- .modified_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- modified_border: colors
- .modified_border
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- predictive: colors
- .predictive
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- predictive_background: colors
- .predictive_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- predictive_border: colors
- .predictive_border
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- renamed: colors
- .renamed
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- renamed_background: colors
- .renamed_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- renamed_border: colors
- .renamed_border
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- success: colors
- .success
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- success_background: colors
- .success_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- success_border: colors
- .success_border
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- unreachable: colors
- .unreachable
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- unreachable_background: colors
- .unreachable_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- unreachable_border: colors
- .unreachable_border
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- warning: colors
- .warning
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- warning_background: colors
- .warning_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- warning_border: colors
- .warning_border
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- }
-}
-
-pub fn theme_colors_refinement(
- this: &settings::ThemeColorsContent,
- status_colors: &StatusColorsRefinement,
-) -> ThemeColorsRefinement {
- let border = this
- .border
- .as_ref()
- .and_then(|color| try_parse_color(color).ok());
- let editor_document_highlight_read_background = this
- .editor_document_highlight_read_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok());
- let scrollbar_thumb_background = this
- .scrollbar_thumb_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok())
- .or_else(|| {
- this.deprecated_scrollbar_thumb_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok())
- });
- let scrollbar_thumb_hover_background = this
- .scrollbar_thumb_hover_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok());
- let scrollbar_thumb_active_background = this
- .scrollbar_thumb_active_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok())
- .or(scrollbar_thumb_background);
- let scrollbar_thumb_border = this
- .scrollbar_thumb_border
- .as_ref()
- .and_then(|color| try_parse_color(color).ok());
- let element_hover = this
- .element_hover
- .as_ref()
- .and_then(|color| try_parse_color(color).ok());
- let panel_background = this
- .panel_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok());
- let search_match_background = this
- .search_match_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok());
- let search_active_match_background = this
- .search_active_match_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok())
- .or(search_match_background);
- ThemeColorsRefinement {
- border,
- border_variant: this
- .border_variant
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- border_focused: this
- .border_focused
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- border_selected: this
- .border_selected
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- border_transparent: this
- .border_transparent
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- border_disabled: this
- .border_disabled
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- elevated_surface_background: this
- .elevated_surface_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- surface_background: this
- .surface_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- background: this
- .background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- element_background: this
- .element_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- element_hover,
- element_active: this
- .element_active
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- element_selected: this
- .element_selected
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- element_disabled: this
- .element_disabled
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- element_selection_background: this
- .element_selection_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- drop_target_background: this
- .drop_target_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- drop_target_border: this
- .drop_target_border
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- ghost_element_background: this
- .ghost_element_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- ghost_element_hover: this
- .ghost_element_hover
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- ghost_element_active: this
- .ghost_element_active
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- ghost_element_selected: this
- .ghost_element_selected
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- ghost_element_disabled: this
- .ghost_element_disabled
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- text: this
- .text
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- text_muted: this
- .text_muted
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- text_placeholder: this
- .text_placeholder
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- text_disabled: this
- .text_disabled
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- text_accent: this
- .text_accent
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- icon: this
- .icon
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- icon_muted: this
- .icon_muted
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- icon_disabled: this
- .icon_disabled
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- icon_placeholder: this
- .icon_placeholder
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- icon_accent: this
- .icon_accent
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- debugger_accent: this
- .debugger_accent
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- status_bar_background: this
- .status_bar_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- title_bar_background: this
- .title_bar_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- title_bar_inactive_background: this
- .title_bar_inactive_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- toolbar_background: this
- .toolbar_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- tab_bar_background: this
- .tab_bar_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- tab_inactive_background: this
- .tab_inactive_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- tab_active_background: this
- .tab_active_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- search_match_background: search_match_background,
- search_active_match_background: search_active_match_background,
- panel_background,
- panel_focused_border: this
- .panel_focused_border
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- panel_indent_guide: this
- .panel_indent_guide
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- panel_indent_guide_hover: this
- .panel_indent_guide_hover
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- panel_indent_guide_active: this
- .panel_indent_guide_active
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- panel_overlay_background: this
- .panel_overlay_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok())
- .or(panel_background.map(ensure_opaque)),
- panel_overlay_hover: this
- .panel_overlay_hover
- .as_ref()
- .and_then(|color| try_parse_color(color).ok())
- .or(panel_background
- .zip(element_hover)
- .map(|(panel_bg, hover_bg)| panel_bg.blend(hover_bg))
- .map(ensure_opaque)),
- pane_focused_border: this
- .pane_focused_border
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- pane_group_border: this
- .pane_group_border
- .as_ref()
- .and_then(|color| try_parse_color(color).ok())
- .or(border),
- scrollbar_thumb_background,
- scrollbar_thumb_hover_background,
- scrollbar_thumb_active_background,
- scrollbar_thumb_border,
- scrollbar_track_background: this
- .scrollbar_track_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- scrollbar_track_border: this
- .scrollbar_track_border
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- minimap_thumb_background: this
- .minimap_thumb_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok())
- .or(scrollbar_thumb_background.map(ensure_non_opaque)),
- minimap_thumb_hover_background: this
- .minimap_thumb_hover_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok())
- .or(scrollbar_thumb_hover_background.map(ensure_non_opaque)),
- minimap_thumb_active_background: this
- .minimap_thumb_active_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok())
- .or(scrollbar_thumb_active_background.map(ensure_non_opaque)),
- minimap_thumb_border: this
- .minimap_thumb_border
- .as_ref()
- .and_then(|color| try_parse_color(color).ok())
- .or(scrollbar_thumb_border),
- editor_foreground: this
- .editor_foreground
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- editor_background: this
- .editor_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- editor_gutter_background: this
- .editor_gutter_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- editor_subheader_background: this
- .editor_subheader_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- editor_active_line_background: this
- .editor_active_line_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- editor_highlighted_line_background: this
- .editor_highlighted_line_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- editor_debugger_active_line_background: this
- .editor_debugger_active_line_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- editor_line_number: this
- .editor_line_number
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- editor_hover_line_number: this
- .editor_hover_line_number
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- editor_active_line_number: this
- .editor_active_line_number
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- editor_invisible: this
- .editor_invisible
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- editor_wrap_guide: this
- .editor_wrap_guide
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- editor_active_wrap_guide: this
- .editor_active_wrap_guide
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- editor_indent_guide: this
- .editor_indent_guide
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- editor_indent_guide_active: this
- .editor_indent_guide_active
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- editor_document_highlight_read_background,
- editor_document_highlight_write_background: this
- .editor_document_highlight_write_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- editor_document_highlight_bracket_background: this
- .editor_document_highlight_bracket_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok())
- // Fall back to `editor.document_highlight.read_background`, for backwards compatibility.
- .or(editor_document_highlight_read_background),
- terminal_background: this
- .terminal_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_background: this
- .terminal_ansi_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_foreground: this
- .terminal_foreground
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_bright_foreground: this
- .terminal_bright_foreground
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_dim_foreground: this
- .terminal_dim_foreground
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_black: this
- .terminal_ansi_black
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_bright_black: this
- .terminal_ansi_bright_black
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_dim_black: this
- .terminal_ansi_dim_black
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_red: this
- .terminal_ansi_red
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_bright_red: this
- .terminal_ansi_bright_red
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_dim_red: this
- .terminal_ansi_dim_red
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_green: this
- .terminal_ansi_green
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_bright_green: this
- .terminal_ansi_bright_green
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_dim_green: this
- .terminal_ansi_dim_green
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_yellow: this
- .terminal_ansi_yellow
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_bright_yellow: this
- .terminal_ansi_bright_yellow
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_dim_yellow: this
- .terminal_ansi_dim_yellow
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_blue: this
- .terminal_ansi_blue
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_bright_blue: this
- .terminal_ansi_bright_blue
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_dim_blue: this
- .terminal_ansi_dim_blue
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_magenta: this
- .terminal_ansi_magenta
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_bright_magenta: this
- .terminal_ansi_bright_magenta
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_dim_magenta: this
- .terminal_ansi_dim_magenta
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_cyan: this
- .terminal_ansi_cyan
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_bright_cyan: this
- .terminal_ansi_bright_cyan
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_dim_cyan: this
- .terminal_ansi_dim_cyan
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_white: this
- .terminal_ansi_white
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_bright_white: this
- .terminal_ansi_bright_white
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- terminal_ansi_dim_white: this
- .terminal_ansi_dim_white
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- link_text_hover: this
- .link_text_hover
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- version_control_added: this
- .version_control_added
- .as_ref()
- .and_then(|color| try_parse_color(color).ok())
- // Fall back to `created`, for backwards compatibility.
- .or(status_colors.created),
- version_control_deleted: this
- .version_control_deleted
- .as_ref()
- .and_then(|color| try_parse_color(color).ok())
- // Fall back to `deleted`, for backwards compatibility.
- .or(status_colors.deleted),
- version_control_modified: this
- .version_control_modified
- .as_ref()
- .and_then(|color| try_parse_color(color).ok())
- // Fall back to `modified`, for backwards compatibility.
- .or(status_colors.modified),
- version_control_renamed: this
- .version_control_renamed
- .as_ref()
- .and_then(|color| try_parse_color(color).ok())
- // Fall back to `modified`, for backwards compatibility.
- .or(status_colors.modified),
- version_control_conflict: this
- .version_control_conflict
- .as_ref()
- .and_then(|color| try_parse_color(color).ok())
- // Fall back to `ignored`, for backwards compatibility.
- .or(status_colors.ignored),
- version_control_ignored: this
- .version_control_ignored
- .as_ref()
- .and_then(|color| try_parse_color(color).ok())
- // Fall back to `conflict`, for backwards compatibility.
- .or(status_colors.ignored),
- version_control_word_added: this
- .version_control_word_added
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- version_control_word_deleted: this
- .version_control_word_deleted
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- #[allow(deprecated)]
- version_control_conflict_marker_ours: this
- .version_control_conflict_marker_ours
- .as_ref()
- .or(this.version_control_conflict_ours_background.as_ref())
- .and_then(|color| try_parse_color(color).ok()),
- #[allow(deprecated)]
- version_control_conflict_marker_theirs: this
- .version_control_conflict_marker_theirs
- .as_ref()
- .or(this.version_control_conflict_theirs_background.as_ref())
- .and_then(|color| try_parse_color(color).ok()),
- vim_normal_background: this
- .vim_normal_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- vim_insert_background: this
- .vim_insert_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- vim_replace_background: this
- .vim_replace_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- vim_visual_background: this
- .vim_visual_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- vim_visual_line_background: this
- .vim_visual_line_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- vim_visual_block_background: this
- .vim_visual_block_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- vim_yank_background: this
- .vim_yank_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok())
- .or(editor_document_highlight_read_background),
- vim_helix_normal_background: this
- .vim_helix_normal_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- vim_helix_select_background: this
- .vim_helix_select_background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- vim_normal_foreground: this
- .vim_normal_foreground
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- vim_insert_foreground: this
- .vim_insert_foreground
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- vim_replace_foreground: this
- .vim_replace_foreground
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- vim_visual_foreground: this
- .vim_visual_foreground
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- vim_visual_line_foreground: this
- .vim_visual_line_foreground
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- vim_visual_block_foreground: this
- .vim_visual_block_foreground
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- vim_helix_normal_foreground: this
- .vim_helix_normal_foreground
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- vim_helix_select_foreground: this
- .vim_helix_select_foreground
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- }
-}
-
-pub(crate) fn try_parse_color(color: &str) -> anyhow::Result<Hsla> {
+/// Parses a color string into an [`Hsla`] value.
+pub fn try_parse_color(color: &str) -> anyhow::Result<Hsla> {
let rgba = gpui::Rgba::try_from(color)?;
let rgba = palette::rgb::Srgba::from_components((rgba.r, rgba.g, rgba.b, rgba.a));
let hsla = palette::Hsla::from_color(rgba);
@@ -5,7 +5,6 @@ use serde::Deserialize;
use crate::{
amber, blue, cyan, gold, grass, indigo, iris, jade, lime, orange, pink, purple, tomato,
- try_parse_color,
};
/// A collection of colors that are used to color indent aware lines in the editor.
@@ -66,25 +65,4 @@ impl AccentColors {
pub fn color_for_index(&self, index: u32) -> Hsla {
self.0[index as usize % self.0.len()]
}
-
- /// Merges the given accent colors into this [`AccentColors`] instance.
- pub fn merge(&mut self, accent_colors: &[settings::AccentContent]) {
- if accent_colors.is_empty() {
- return;
- }
-
- let colors = accent_colors
- .iter()
- .filter_map(|accent_color| {
- accent_color
- .0
- .as_ref()
- .and_then(|color| try_parse_color(color).ok())
- })
- .collect::<Vec<_>>();
-
- if !colors.is_empty() {
- self.0 = Arc::from(colors);
- }
- }
}
@@ -3,7 +3,7 @@
use gpui::Hsla;
use serde::Deserialize;
-use crate::{amber, blue, jade, lime, orange, pink, purple, red, try_parse_color};
+use crate::{amber, blue, jade, lime, orange, pink, purple, red};
#[derive(Debug, Clone, Copy, Deserialize, Default, PartialEq)]
pub struct PlayerColor {
@@ -148,40 +148,4 @@ impl PlayerColors {
let len = self.0.len() - 1;
self.0[(participant_index as usize % len) + 1]
}
-
- /// Merges the given player colors into this [`PlayerColors`] instance.
- pub fn merge(&mut self, user_player_colors: &[settings::PlayerColorContent]) {
- if user_player_colors.is_empty() {
- return;
- }
-
- for (idx, player) in user_player_colors.iter().enumerate() {
- let cursor = player
- .cursor
- .as_ref()
- .and_then(|color| try_parse_color(color).ok());
- let background = player
- .background
- .as_ref()
- .and_then(|color| try_parse_color(color).ok());
- let selection = player
- .selection
- .as_ref()
- .and_then(|color| try_parse_color(color).ok());
-
- if let Some(player_color) = self.0.get_mut(idx) {
- *player_color = PlayerColor {
- cursor: cursor.unwrap_or(player_color.cursor),
- background: background.unwrap_or(player_color.background),
- selection: selection.unwrap_or(player_color.selection),
- };
- } else {
- self.0.push(PlayerColor {
- cursor: cursor.unwrap_or_default(),
- background: background.unwrap_or_default(),
- selection: selection.unwrap_or_default(),
- });
- }
- }
- }
}
@@ -16,40 +16,30 @@ mod icon_theme_schema;
mod registry;
mod scale;
mod schema;
-mod settings;
mod styles;
use std::sync::Arc;
-use ::settings::DEFAULT_DARK_THEME;
-use ::settings::IntoGpui;
-use ::settings::Settings;
-use ::settings::SettingsStore;
-use anyhow::Result;
-use fallback_themes::apply_status_color_defaults;
+use derive_more::{Deref, DerefMut};
use gpui::BorrowAppContext;
use gpui::Global;
use gpui::{
- App, AssetSource, HighlightStyle, Hsla, Pixels, Refineable, SharedString, WindowAppearance,
- WindowBackgroundAppearance, px,
+ App, AssetSource, Hsla, Pixels, SharedString, WindowAppearance, WindowBackgroundAppearance, px,
};
use serde::Deserialize;
-use uuid::Uuid;
pub use crate::default_colors::*;
-use crate::fallback_themes::apply_theme_color_defaults;
+pub use crate::fallback_themes::{apply_status_color_defaults, apply_theme_color_defaults};
pub use crate::font_family_cache::*;
pub use crate::icon_theme::*;
pub use crate::icon_theme_schema::*;
pub use crate::registry::*;
pub use crate::scale::*;
pub use crate::schema::*;
-pub use crate::settings::*;
pub use crate::styles::*;
-pub use ::settings::{
- FontStyleContent, HighlightStyleContent, StatusColorsContent, ThemeColorsContent,
- ThemeStyleContent,
-};
+
+/// The name of the default dark theme.
+pub const DEFAULT_DARK_THEME: &str = "One Dark";
/// Defines window border radius for platforms that use client side decorations.
pub const CLIENT_SIDE_DECORATION_ROUNDING: Pixels = px(10.0);
@@ -84,15 +74,6 @@ impl From<WindowAppearance> for Appearance {
}
}
-impl From<Appearance> for ThemeAppearanceMode {
- fn from(value: Appearance) -> Self {
- match value {
- Appearance::Light => Self::Light,
- Appearance::Dark => Self::Dark,
- }
- }
-}
-
/// Which themes should be loaded. This is used primarily for testing.
pub enum LoadThemes {
/// Only load the base theme.
@@ -104,84 +85,31 @@ pub enum LoadThemes {
All(Box<dyn AssetSource>),
}
-/// Initialize the theme system.
+/// Initialize the theme system with default themes.
+///
+/// This sets up the [`ThemeRegistry`], [`FontFamilyCache`], [`SystemAppearance`],
+/// and [`GlobalTheme`] with the default dark theme. It does NOT load bundled
+/// themes from JSON or integrate with settings — use `theme_settings::init` for that.
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),
+ let assets = match themes_to_load {
+ LoadThemes::JustBase => Box::new(()) as Box<dyn AssetSource>,
+ LoadThemes::All(assets) => assets,
};
ThemeRegistry::set_global(assets, cx);
-
- if load_user_themes {
- ThemeRegistry::global(cx).load_bundled_themes();
- }
-
FontFamilyCache::init_global(cx);
- let theme = GlobalTheme::configured_theme(cx);
- let icon_theme = GlobalTheme::configured_icon_theme(cx);
+ let themes = ThemeRegistry::default_global(cx);
+ let theme = themes.get(DEFAULT_DARK_THEME).unwrap_or_else(|_| {
+ themes
+ .list()
+ .into_iter()
+ .next()
+ .map(|m| themes.get(&m.name).unwrap())
+ .unwrap()
+ });
+ let icon_theme = themes.default_icon_theme().unwrap();
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(),
- );
-
- 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(),
- );
-
- if buffer_font_size_settings != prev_buffer_font_size_settings {
- prev_buffer_font_size_settings = buffer_font_size_settings;
- reset_buffer_font_size(cx);
- }
-
- if ui_font_size_settings != prev_ui_font_size_settings {
- prev_ui_font_size_settings = ui_font_size_settings;
- reset_ui_font_size(cx);
- }
-
- 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);
- }
-
- 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();
}
/// Implementing this trait allows accessing the active theme.
@@ -196,6 +124,39 @@ impl ActiveTheme for App {
}
}
+/// The appearance of the system.
+#[derive(Debug, Clone, Copy, Deref)]
+pub struct SystemAppearance(pub Appearance);
+
+impl Default for SystemAppearance {
+ fn default() -> Self {
+ Self(Appearance::Dark)
+ }
+}
+
+#[derive(Deref, DerefMut, Default)]
+struct GlobalSystemAppearance(SystemAppearance);
+
+impl Global for GlobalSystemAppearance {}
+
+impl SystemAppearance {
+ /// Initializes the [`SystemAppearance`] for the application.
+ pub fn init(cx: &mut App) {
+ *cx.default_global::<GlobalSystemAppearance>() =
+ GlobalSystemAppearance(SystemAppearance(cx.window_appearance().into()));
+ }
+
+ /// Returns the global [`SystemAppearance`].
+ pub fn global(cx: &App) -> Self {
+ cx.global::<GlobalSystemAppearance>().0
+ }
+
+ /// Returns a mutable reference to the global [`SystemAppearance`].
+ pub fn global_mut(cx: &mut App) -> &mut Self {
+ cx.global_mut::<GlobalSystemAppearance>()
+ }
+}
+
/// A theme family is a grouping of themes under a single name.
///
/// For example, the "One" theme family contains the "One Light" and "One Dark" themes.
@@ -217,113 +178,6 @@ pub struct ThemeFamily {
pub scales: ColorScales,
}
-impl ThemeFamily {
- // This is on ThemeFamily because we will have variables here we will need
- // in the future to resolve @references.
- /// Refines ThemeContent into a theme, merging it's contents with the base theme.
- pub fn refine_theme(&self, theme: &ThemeContent) -> Theme {
- let appearance = match theme.appearance {
- AppearanceContent::Light => Appearance::Light,
- AppearanceContent::Dark => Appearance::Dark,
- };
-
- let mut refined_status_colors = match theme.appearance {
- AppearanceContent::Light => StatusColors::light(),
- AppearanceContent::Dark => StatusColors::dark(),
- };
- let mut status_colors_refinement = status_colors_refinement(&theme.style.status);
- apply_status_color_defaults(&mut status_colors_refinement);
- refined_status_colors.refine(&status_colors_refinement);
-
- let mut refined_player_colors = match theme.appearance {
- AppearanceContent::Light => PlayerColors::light(),
- AppearanceContent::Dark => PlayerColors::dark(),
- };
- refined_player_colors.merge(&theme.style.players);
-
- let mut refined_theme_colors = match theme.appearance {
- AppearanceContent::Light => ThemeColors::light(),
- AppearanceContent::Dark => ThemeColors::dark(),
- };
- let mut theme_colors_refinement =
- theme_colors_refinement(&theme.style.colors, &status_colors_refinement);
- apply_theme_color_defaults(&mut theme_colors_refinement, &refined_player_colors);
- refined_theme_colors.refine(&theme_colors_refinement);
-
- let mut refined_accent_colors = match theme.appearance {
- AppearanceContent::Light => AccentColors::light(),
- AppearanceContent::Dark => AccentColors::dark(),
- };
- refined_accent_colors.merge(&theme.style.accents);
-
- let syntax_highlights = theme.style.syntax.iter().map(|(syntax_token, highlight)| {
- (
- syntax_token.clone(),
- HighlightStyle {
- color: highlight
- .color
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- background_color: highlight
- .background_color
- .as_ref()
- .and_then(|color| try_parse_color(color).ok()),
- font_style: highlight.font_style.map(|s| s.into_gpui()),
- font_weight: highlight.font_weight.map(|w| w.into_gpui()),
- ..Default::default()
- },
- )
- });
- let syntax_theme = Arc::new(SyntaxTheme::new(syntax_highlights));
-
- let window_background_appearance = theme
- .style
- .window_background_appearance
- .map(|w| w.into_gpui())
- .unwrap_or_default();
-
- Theme {
- id: uuid::Uuid::new_v4().to_string(),
- name: theme.name.clone().into(),
- appearance,
- styles: ThemeStyles {
- system: SystemColors::default(),
- window_background_appearance,
- accents: refined_accent_colors,
- colors: refined_theme_colors,
- status: refined_status_colors,
- player: refined_player_colors,
- syntax: syntax_theme,
- },
- }
- }
-}
-
-/// Refines a [ThemeFamilyContent] and it's [ThemeContent]s into a [ThemeFamily].
-pub fn refine_theme_family(theme_family_content: ThemeFamilyContent) -> ThemeFamily {
- let id = Uuid::new_v4().to_string();
- let name = theme_family_content.name.clone();
- let author = theme_family_content.author.clone();
-
- let mut theme_family = ThemeFamily {
- id,
- name: name.into(),
- author: author.into(),
- themes: vec![],
- scales: default_color_scales(),
- };
-
- let refined_themes = theme_family_content
- .themes
- .iter()
- .map(|theme_content| theme_family.refine_theme(theme_content))
- .collect();
-
- theme_family.themes = refined_themes;
-
- theme_family
-}
-
/// A theme is the primary mechanism for defining the appearance of the UI.
#[derive(Clone, Debug, PartialEq)]
pub struct Theme {
@@ -403,35 +257,14 @@ impl Theme {
}
}
-/// Deserializes a user theme from the given bytes.
-pub fn deserialize_user_theme(bytes: &[u8]) -> Result<ThemeFamilyContent> {
- let theme_family: ThemeFamilyContent = serde_json_lenient::from_slice(bytes)?;
-
- for theme in &theme_family.themes {
- if theme
- .style
- .colors
- .deprecated_scrollbar_thumb_background
- .is_some()
- {
- log::warn!(
- r#"Theme "{theme_name}" is using a deprecated style property: scrollbar_thumb.background. Use `scrollbar.thumb.background` instead."#,
- theme_name = theme.name
- )
- }
- }
-
- Ok(theme_family)
-}
-
-/// Deserializes a icon theme from the given bytes.
-pub fn deserialize_icon_theme(bytes: &[u8]) -> Result<IconThemeFamilyContent> {
+/// Deserializes an icon theme from the given bytes.
+pub fn deserialize_icon_theme(bytes: &[u8]) -> anyhow::Result<IconThemeFamilyContent> {
let icon_theme_family: IconThemeFamilyContent = serde_json_lenient::from_slice(bytes)?;
Ok(icon_theme_family)
}
-/// The active theme
+/// The active theme.
pub struct GlobalTheme {
theme: Arc<Theme>,
icon_theme: Arc<IconTheme>,
@@ -439,72 +272,27 @@ pub struct GlobalTheme {
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)
+ /// Creates a new [`GlobalTheme`] with the given theme and icon theme.
+ pub fn new(theme: Arc<Theme>, icon_theme: Arc<IconTheme>) -> Self {
+ Self { theme, icon_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);
+ /// Updates the active theme.
+ pub fn update_theme(cx: &mut App, theme: Arc<Theme>) {
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);
+ /// Updates the active icon theme.
+ pub fn update_icon_theme(cx: &mut App, icon_theme: Arc<IconTheme>) {
cx.update_global::<Self, _>(|this, _| this.icon_theme = icon_theme);
- cx.refresh_windows();
}
- /// the active theme
+ /// Returns the active theme.
pub fn theme(cx: &App) -> &Arc<Theme> {
&cx.global::<Self>().theme
}
- /// the active icon theme
+ /// Returns the active icon theme.
pub fn icon_theme(cx: &App) -> &Arc<IconTheme> {
&cx.global::<Self>().icon_theme
}
@@ -17,3 +17,4 @@ extension.workspace = true
fs.workspace = true
gpui.workspace = true
theme.workspace = true
+theme_settings.workspace = true
@@ -5,7 +5,8 @@ use anyhow::Result;
use extension::{ExtensionHostProxy, ExtensionThemeProxy};
use fs::Fs;
use gpui::{App, BackgroundExecutor, SharedString, Task};
-use theme::{GlobalTheme, ThemeRegistry, deserialize_icon_theme};
+use theme::{ThemeRegistry, deserialize_icon_theme};
+use theme_settings;
pub fn init(
extension_host_proxy: Arc<ExtensionHostProxy>,
@@ -30,7 +31,8 @@ impl ExtensionThemeProxy for ThemeRegistryProxy {
fn list_theme_names(&self, theme_path: PathBuf, fs: Arc<dyn Fs>) -> Task<Result<Vec<String>>> {
self.executor.spawn(async move {
- let themes = theme::deserialize_user_theme(&fs.load_bytes(&theme_path).await?)?;
+ let themes =
+ theme_settings::deserialize_user_theme(&fs.load_bytes(&theme_path).await?)?;
Ok(themes.themes.into_iter().map(|theme| theme.name).collect())
})
}
@@ -42,12 +44,12 @@ impl ExtensionThemeProxy for ThemeRegistryProxy {
fn load_user_theme(&self, theme_path: PathBuf, fs: Arc<dyn Fs>) -> Task<Result<()>> {
let theme_registry = self.theme_registry.clone();
self.executor.spawn(async move {
- theme_registry.load_user_theme(&fs.load_bytes(&theme_path).await?)
+ theme_settings::load_user_theme(&theme_registry, &fs.load_bytes(&theme_path).await?)
})
}
fn reload_current_theme(&self, cx: &mut App) {
- GlobalTheme::reload_theme(cx)
+ theme_settings::reload_theme(cx)
}
fn list_icon_theme_names(
@@ -85,6 +87,6 @@ impl ExtensionThemeProxy for ThemeRegistryProxy {
}
fn reload_current_icon_theme(&self, cx: &mut App) {
- GlobalTheme::reload_icon_theme(cx)
+ theme_settings::reload_icon_theme(cx)
}
}
@@ -22,4 +22,5 @@ serde_json_lenient.workspace = true
simplelog.workspace= true
strum = { workspace = true, features = ["derive"] }
theme.workspace = true
+theme_settings.workspace = true
vscode_theme = "0.2.0"
@@ -1,7 +1,7 @@
use anyhow::Result;
use collections::IndexMap;
use strum::IntoEnumIterator;
-use theme::{
+use theme_settings::{
FontStyleContent, FontWeightContent, HighlightStyleContent, StatusColorsContent,
ThemeColorsContent, ThemeContent, ThemeStyleContent, WindowBackgroundContent,
};
@@ -22,6 +22,7 @@ serde.workspace = true
settings.workspace = true
telemetry.workspace = true
theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
util.workspace = true
workspace.workspace = true
@@ -7,10 +7,8 @@ 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, SystemAppearance, ThemeMeta, ThemeRegistry};
+use theme_settings::{IconThemeName, IconThemeSelection, ThemeSettings};
use ui::{ListItem, ListItemSpacing, prelude::*, v_flex};
use util::ResultExt;
use workspace::{ModalView, ui::HighlightedLabel};
@@ -176,7 +174,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_settings::set_icon_theme(settings, theme_name, appearance);
});
self.selector
@@ -9,9 +9,9 @@ use gpui::{
use picker::{Picker, PickerDelegate};
use settings::{Settings, SettingsStore, update_settings_file};
use std::sync::Arc;
-use theme::{
- Appearance, SystemAppearance, Theme, ThemeAppearanceMode, ThemeMeta, ThemeName, ThemeRegistry,
- ThemeSelection, ThemeSettings,
+use theme::{Appearance, SystemAppearance, Theme, ThemeMeta, ThemeRegistry};
+use theme_settings::{
+ ThemeAppearanceMode, ThemeName, ThemeSelection, ThemeSettings, appearance_to_mode,
};
use ui::{ListItem, ListItemSpacing, prelude::*, v_flex};
use util::ResultExt;
@@ -233,7 +233,7 @@ impl ThemeSelectorDelegate {
/// Overrides the global (in-memory) theme settings.
///
/// Note that this does **not** update the user's `settings.json` file (see the
-/// [`ThemeSelectorDelegate::confirm`] method and [`theme::set_theme`] function).
+/// [`ThemeSelectorDelegate::confirm`] method and [`theme_settings::set_theme`] function).
fn override_global_theme(
store: &mut SettingsStore,
new_theme: &Theme,
@@ -303,7 +303,7 @@ fn update_mode_if_new_appearance_is_different_from_system(
if original_mode == &ThemeAppearanceMode::System && system_appearance == new_appearance {
ThemeAppearanceMode::System
} else {
- ThemeAppearanceMode::from(new_appearance)
+ appearance_to_mode(new_appearance)
}
}
@@ -360,7 +360,7 @@ impl PickerDelegate for ThemeSelectorDelegate {
telemetry::event!("Settings Changed", setting = "theme", value = theme_name);
update_settings_file(self.fs.clone(), cx, move |settings, _| {
- theme::set_theme(settings, theme_name, theme_appearance, system_appearance);
+ theme_settings::set_theme(settings, theme_name, theme_appearance, system_appearance);
});
self.selector
@@ -0,0 +1,37 @@
+[package]
+name = "theme_settings"
+version = "0.1.0"
+edition.workspace = true
+publish.workspace = true
+license = "GPL-3.0-or-later"
+
+[lints]
+workspace = true
+
+[features]
+default = []
+test-support = ["gpui/test-support", "settings/test-support", "theme/test-support"]
+
+[lib]
+path = "src/theme_settings.rs"
+doctest = false
+
+[dependencies]
+anyhow.workspace = true
+collections.workspace = true
+gpui.workspace = true
+gpui_util.workspace = true
+log.workspace = true
+palette = { workspace = true, default-features = false, features = ["std"] }
+refineable.workspace = true
+schemars.workspace = true
+serde.workspace = true
+serde_json.workspace = true
+serde_json_lenient.workspace = true
+settings.workspace = true
+theme.workspace = true
+uuid.workspace = true
+
+[dev-dependencies]
+gpui = { workspace = true, features = ["test-support"] }
+settings = { workspace = true, features = ["test-support"] }
@@ -0,0 +1 @@
+../../LICENSE-GPL
@@ -0,0 +1,850 @@
+#![allow(missing_docs)]
+
+use gpui::{HighlightStyle, Hsla};
+use palette::FromColor;
+use schemars::JsonSchema;
+use serde::{Deserialize, Serialize};
+use settings::IntoGpui;
+pub use settings::{
+ FontStyleContent, HighlightStyleContent, StatusColorsContent, ThemeColorsContent,
+ ThemeStyleContent,
+};
+pub use settings::{FontWeightContent, WindowBackgroundContent};
+
+use theme::{StatusColorsRefinement, ThemeColorsRefinement};
+
+/// The content of a serialized theme family.
+#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
+pub struct ThemeFamilyContent {
+ pub name: String,
+ pub author: String,
+ pub themes: Vec<ThemeContent>,
+}
+
+/// The content of a serialized theme.
+#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
+pub struct ThemeContent {
+ pub name: String,
+ pub appearance: theme::AppearanceContent,
+ pub style: settings::ThemeStyleContent,
+}
+
+/// Returns the syntax style overrides in the [`ThemeContent`].
+pub fn syntax_overrides(this: &settings::ThemeStyleContent) -> Vec<(String, HighlightStyle)> {
+ this.syntax
+ .iter()
+ .map(|(key, style)| {
+ (
+ key.clone(),
+ HighlightStyle {
+ color: style
+ .color
+ .as_ref()
+ .and_then(|color| theme::try_parse_color(color).ok()),
+ background_color: style
+ .background_color
+ .as_ref()
+ .and_then(|color| theme::try_parse_color(color).ok()),
+ font_style: style.font_style.map(|s| s.into_gpui()),
+ font_weight: style.font_weight.map(|w| w.into_gpui()),
+ ..Default::default()
+ },
+ )
+ })
+ .collect()
+}
+
+pub fn status_colors_refinement(colors: &settings::StatusColorsContent) -> StatusColorsRefinement {
+ StatusColorsRefinement {
+ conflict: colors
+ .conflict
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ conflict_background: colors
+ .conflict_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ conflict_border: colors
+ .conflict_border
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ created: colors
+ .created
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ created_background: colors
+ .created_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ created_border: colors
+ .created_border
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ deleted: colors
+ .deleted
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ deleted_background: colors
+ .deleted_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ deleted_border: colors
+ .deleted_border
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ error: colors
+ .error
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ error_background: colors
+ .error_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ error_border: colors
+ .error_border
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ hidden: colors
+ .hidden
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ hidden_background: colors
+ .hidden_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ hidden_border: colors
+ .hidden_border
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ hint: colors
+ .hint
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ hint_background: colors
+ .hint_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ hint_border: colors
+ .hint_border
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ ignored: colors
+ .ignored
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ ignored_background: colors
+ .ignored_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ ignored_border: colors
+ .ignored_border
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ info: colors
+ .info
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ info_background: colors
+ .info_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ info_border: colors
+ .info_border
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ modified: colors
+ .modified
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ modified_background: colors
+ .modified_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ modified_border: colors
+ .modified_border
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ predictive: colors
+ .predictive
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ predictive_background: colors
+ .predictive_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ predictive_border: colors
+ .predictive_border
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ renamed: colors
+ .renamed
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ renamed_background: colors
+ .renamed_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ renamed_border: colors
+ .renamed_border
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ success: colors
+ .success
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ success_background: colors
+ .success_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ success_border: colors
+ .success_border
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ unreachable: colors
+ .unreachable
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ unreachable_background: colors
+ .unreachable_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ unreachable_border: colors
+ .unreachable_border
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ warning: colors
+ .warning
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ warning_background: colors
+ .warning_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ warning_border: colors
+ .warning_border
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ }
+}
+
+pub fn theme_colors_refinement(
+ this: &settings::ThemeColorsContent,
+ status_colors: &StatusColorsRefinement,
+) -> ThemeColorsRefinement {
+ let border = this
+ .border
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok());
+ let editor_document_highlight_read_background = this
+ .editor_document_highlight_read_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok());
+ let scrollbar_thumb_background = this
+ .scrollbar_thumb_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok())
+ .or_else(|| {
+ this.deprecated_scrollbar_thumb_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok())
+ });
+ let scrollbar_thumb_hover_background = this
+ .scrollbar_thumb_hover_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok());
+ let scrollbar_thumb_active_background = this
+ .scrollbar_thumb_active_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok())
+ .or(scrollbar_thumb_background);
+ let scrollbar_thumb_border = this
+ .scrollbar_thumb_border
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok());
+ let element_hover = this
+ .element_hover
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok());
+ let panel_background = this
+ .panel_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok());
+ let search_match_background = this
+ .search_match_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok());
+ let search_active_match_background = this
+ .search_active_match_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok())
+ .or(search_match_background);
+ ThemeColorsRefinement {
+ border,
+ border_variant: this
+ .border_variant
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ border_focused: this
+ .border_focused
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ border_selected: this
+ .border_selected
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ border_transparent: this
+ .border_transparent
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ border_disabled: this
+ .border_disabled
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ elevated_surface_background: this
+ .elevated_surface_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ surface_background: this
+ .surface_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ background: this
+ .background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ element_background: this
+ .element_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ element_hover,
+ element_active: this
+ .element_active
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ element_selected: this
+ .element_selected
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ element_disabled: this
+ .element_disabled
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ element_selection_background: this
+ .element_selection_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ drop_target_background: this
+ .drop_target_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ drop_target_border: this
+ .drop_target_border
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ ghost_element_background: this
+ .ghost_element_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ ghost_element_hover: this
+ .ghost_element_hover
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ ghost_element_active: this
+ .ghost_element_active
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ ghost_element_selected: this
+ .ghost_element_selected
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ ghost_element_disabled: this
+ .ghost_element_disabled
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ text: this
+ .text
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ text_muted: this
+ .text_muted
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ text_placeholder: this
+ .text_placeholder
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ text_disabled: this
+ .text_disabled
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ text_accent: this
+ .text_accent
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ icon: this
+ .icon
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ icon_muted: this
+ .icon_muted
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ icon_disabled: this
+ .icon_disabled
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ icon_placeholder: this
+ .icon_placeholder
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ icon_accent: this
+ .icon_accent
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ debugger_accent: this
+ .debugger_accent
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ status_bar_background: this
+ .status_bar_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ title_bar_background: this
+ .title_bar_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ title_bar_inactive_background: this
+ .title_bar_inactive_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ toolbar_background: this
+ .toolbar_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ tab_bar_background: this
+ .tab_bar_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ tab_inactive_background: this
+ .tab_inactive_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ tab_active_background: this
+ .tab_active_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ search_match_background,
+ search_active_match_background,
+ panel_background,
+ panel_focused_border: this
+ .panel_focused_border
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ panel_indent_guide: this
+ .panel_indent_guide
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ panel_indent_guide_hover: this
+ .panel_indent_guide_hover
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ panel_indent_guide_active: this
+ .panel_indent_guide_active
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ panel_overlay_background: this
+ .panel_overlay_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok())
+ .or(panel_background.map(ensure_opaque)),
+ panel_overlay_hover: this
+ .panel_overlay_hover
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok())
+ .or(panel_background
+ .zip(element_hover)
+ .map(|(panel_bg, hover_bg)| panel_bg.blend(hover_bg))
+ .map(ensure_opaque)),
+ pane_focused_border: this
+ .pane_focused_border
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ pane_group_border: this
+ .pane_group_border
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok())
+ .or(border),
+ scrollbar_thumb_background,
+ scrollbar_thumb_hover_background,
+ scrollbar_thumb_active_background,
+ scrollbar_thumb_border,
+ scrollbar_track_background: this
+ .scrollbar_track_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ scrollbar_track_border: this
+ .scrollbar_track_border
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ minimap_thumb_background: this
+ .minimap_thumb_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok())
+ .or(scrollbar_thumb_background.map(ensure_non_opaque)),
+ minimap_thumb_hover_background: this
+ .minimap_thumb_hover_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok())
+ .or(scrollbar_thumb_hover_background.map(ensure_non_opaque)),
+ minimap_thumb_active_background: this
+ .minimap_thumb_active_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok())
+ .or(scrollbar_thumb_active_background.map(ensure_non_opaque)),
+ minimap_thumb_border: this
+ .minimap_thumb_border
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok())
+ .or(scrollbar_thumb_border),
+ editor_foreground: this
+ .editor_foreground
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ editor_background: this
+ .editor_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ editor_gutter_background: this
+ .editor_gutter_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ editor_subheader_background: this
+ .editor_subheader_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ editor_active_line_background: this
+ .editor_active_line_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ editor_highlighted_line_background: this
+ .editor_highlighted_line_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ editor_debugger_active_line_background: this
+ .editor_debugger_active_line_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ editor_line_number: this
+ .editor_line_number
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ editor_hover_line_number: this
+ .editor_hover_line_number
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ editor_active_line_number: this
+ .editor_active_line_number
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ editor_invisible: this
+ .editor_invisible
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ editor_wrap_guide: this
+ .editor_wrap_guide
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ editor_active_wrap_guide: this
+ .editor_active_wrap_guide
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ editor_indent_guide: this
+ .editor_indent_guide
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ editor_indent_guide_active: this
+ .editor_indent_guide_active
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ editor_document_highlight_read_background,
+ editor_document_highlight_write_background: this
+ .editor_document_highlight_write_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ editor_document_highlight_bracket_background: this
+ .editor_document_highlight_bracket_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok())
+ .or(editor_document_highlight_read_background),
+ terminal_background: this
+ .terminal_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_background: this
+ .terminal_ansi_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_foreground: this
+ .terminal_foreground
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_bright_foreground: this
+ .terminal_bright_foreground
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_dim_foreground: this
+ .terminal_dim_foreground
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_black: this
+ .terminal_ansi_black
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_bright_black: this
+ .terminal_ansi_bright_black
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_dim_black: this
+ .terminal_ansi_dim_black
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_red: this
+ .terminal_ansi_red
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_bright_red: this
+ .terminal_ansi_bright_red
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_dim_red: this
+ .terminal_ansi_dim_red
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_green: this
+ .terminal_ansi_green
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_bright_green: this
+ .terminal_ansi_bright_green
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_dim_green: this
+ .terminal_ansi_dim_green
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_yellow: this
+ .terminal_ansi_yellow
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_bright_yellow: this
+ .terminal_ansi_bright_yellow
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_dim_yellow: this
+ .terminal_ansi_dim_yellow
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_blue: this
+ .terminal_ansi_blue
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_bright_blue: this
+ .terminal_ansi_bright_blue
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_dim_blue: this
+ .terminal_ansi_dim_blue
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_magenta: this
+ .terminal_ansi_magenta
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_bright_magenta: this
+ .terminal_ansi_bright_magenta
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_dim_magenta: this
+ .terminal_ansi_dim_magenta
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_cyan: this
+ .terminal_ansi_cyan
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_bright_cyan: this
+ .terminal_ansi_bright_cyan
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_dim_cyan: this
+ .terminal_ansi_dim_cyan
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_white: this
+ .terminal_ansi_white
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_bright_white: this
+ .terminal_ansi_bright_white
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ terminal_ansi_dim_white: this
+ .terminal_ansi_dim_white
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ link_text_hover: this
+ .link_text_hover
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ version_control_added: this
+ .version_control_added
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok())
+ .or(status_colors.created),
+ version_control_deleted: this
+ .version_control_deleted
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok())
+ .or(status_colors.deleted),
+ version_control_modified: this
+ .version_control_modified
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok())
+ .or(status_colors.modified),
+ version_control_renamed: this
+ .version_control_renamed
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok())
+ .or(status_colors.modified),
+ version_control_conflict: this
+ .version_control_conflict
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok())
+ .or(status_colors.ignored),
+ version_control_ignored: this
+ .version_control_ignored
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok())
+ .or(status_colors.ignored),
+ version_control_word_added: this
+ .version_control_word_added
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ version_control_word_deleted: this
+ .version_control_word_deleted
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ #[allow(deprecated)]
+ version_control_conflict_marker_ours: this
+ .version_control_conflict_marker_ours
+ .as_ref()
+ .or(this.version_control_conflict_ours_background.as_ref())
+ .and_then(|color| try_parse_color(color).ok()),
+ #[allow(deprecated)]
+ version_control_conflict_marker_theirs: this
+ .version_control_conflict_marker_theirs
+ .as_ref()
+ .or(this.version_control_conflict_theirs_background.as_ref())
+ .and_then(|color| try_parse_color(color).ok()),
+ vim_normal_background: this
+ .vim_normal_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ vim_insert_background: this
+ .vim_insert_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ vim_replace_background: this
+ .vim_replace_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ vim_visual_background: this
+ .vim_visual_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ vim_visual_line_background: this
+ .vim_visual_line_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ vim_visual_block_background: this
+ .vim_visual_block_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ vim_yank_background: this
+ .vim_yank_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok())
+ .or(editor_document_highlight_read_background),
+ vim_helix_normal_background: this
+ .vim_helix_normal_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ vim_helix_select_background: this
+ .vim_helix_select_background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ vim_normal_foreground: this
+ .vim_normal_foreground
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ vim_insert_foreground: this
+ .vim_insert_foreground
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ vim_replace_foreground: this
+ .vim_replace_foreground
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ vim_visual_foreground: this
+ .vim_visual_foreground
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ vim_visual_line_foreground: this
+ .vim_visual_line_foreground
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ vim_visual_block_foreground: this
+ .vim_visual_block_foreground
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ vim_helix_normal_foreground: this
+ .vim_helix_normal_foreground
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ vim_helix_select_foreground: this
+ .vim_helix_select_foreground
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ }
+}
+
+fn ensure_non_opaque(color: Hsla) -> Hsla {
+ const MAXIMUM_OPACITY: f32 = 0.7;
+ if color.a <= MAXIMUM_OPACITY {
+ color
+ } else {
+ Hsla {
+ a: MAXIMUM_OPACITY,
+ ..color
+ }
+ }
+}
+
+fn ensure_opaque(color: Hsla) -> Hsla {
+ Hsla { a: 1.0, ..color }
+}
+
+fn try_parse_color(color: &str) -> anyhow::Result<Hsla> {
+ let rgba = gpui::Rgba::try_from(color)?;
+ let rgba = palette::rgb::Srgba::from_components((rgba.r, rgba.g, rgba.b, rgba.a));
+ let hsla = palette::Hsla::from_color(rgba);
+
+ let hsla = gpui::hsla(
+ hsla.hue.into_positive_degrees() / 360.,
+ hsla.saturation,
+ hsla.lightness,
+ hsla.alpha,
+ );
+
+ Ok(hsla)
+}
@@ -1,9 +1,8 @@
-use crate::{
- Appearance, DEFAULT_ICON_THEME_NAME, SyntaxTheme, Theme, status_colors_refinement,
- syntax_overrides, theme_colors_refinement,
-};
+#![allow(missing_docs)]
+
+use crate::schema::{status_colors_refinement, syntax_overrides, theme_colors_refinement};
+use crate::{merge_accent_colors, merge_player_colors};
use collections::HashMap;
-use derive_more::{Deref, DerefMut};
use gpui::{
App, Context, Font, FontFallbacks, FontStyle, Global, Pixels, Subscription, Window, px,
};
@@ -13,6 +12,7 @@ use serde::{Deserialize, Serialize};
pub use settings::{FontFamilyName, IconThemeName, ThemeAppearanceMode, ThemeName};
use settings::{IntoGpui, RegisterSetting, Settings, SettingsContent};
use std::sync::Arc;
+use theme::{Appearance, DEFAULT_ICON_THEME_NAME, SyntaxTheme, Theme};
const MIN_FONT_SIZE: Pixels = px(6.0);
const MAX_FONT_SIZE: Pixels = px(100.0);
@@ -92,6 +92,13 @@ impl From<settings::UiDensity> for UiDensity {
}
}
+pub fn appearance_to_mode(appearance: Appearance) -> ThemeAppearanceMode {
+ match appearance {
+ Appearance::Light => ThemeAppearanceMode::Light,
+ Appearance::Dark => ThemeAppearanceMode::Dark,
+ }
+}
+
/// Customizable settings for the UI and theme system.
#[derive(Clone, PartialEq, RegisterSetting)]
pub struct ThemeSettings {
@@ -145,39 +152,6 @@ pub fn default_theme(appearance: Appearance) -> &'static str {
}
}
-/// The appearance of the system.
-#[derive(Debug, Clone, Copy, Deref)]
-pub struct SystemAppearance(pub Appearance);
-
-impl Default for SystemAppearance {
- fn default() -> Self {
- Self(Appearance::Dark)
- }
-}
-
-#[derive(Deref, DerefMut, Default)]
-struct GlobalSystemAppearance(SystemAppearance);
-
-impl Global for GlobalSystemAppearance {}
-
-impl SystemAppearance {
- /// Initializes the [`SystemAppearance`] for the application.
- pub fn init(cx: &mut App) {
- *cx.default_global::<GlobalSystemAppearance>() =
- GlobalSystemAppearance(SystemAppearance(cx.window_appearance().into()));
- }
-
- /// Returns the global [`SystemAppearance`].
- pub fn global(cx: &App) -> Self {
- cx.global::<GlobalSystemAppearance>().0
- }
-
- /// Returns a mutable reference to the global [`SystemAppearance`].
- pub fn global_mut(cx: &mut App) -> &mut Self {
- cx.global_mut::<GlobalSystemAppearance>()
- }
-}
-
#[derive(Default)]
struct BufferFontSize(Pixels);
@@ -327,21 +301,16 @@ pub fn set_theme(
*theme = theme_name;
}
settings::ThemeSelection::Dynamic { mode, light, dark } => {
- // Update the appropriate theme slot based on appearance.
match theme_appearance {
Appearance::Light => *light = theme_name,
Appearance::Dark => *dark = theme_name,
}
- // Don't update the theme mode if it is set to system and the new theme has the same
- // appearance.
let should_update_mode =
!(mode == &ThemeAppearanceMode::System && theme_appearance == system_appearance);
if should_update_mode {
- // Update the mode to the specified appearance (otherwise we might set the theme and
- // nothing gets updated because the system specified the other mode appearance).
- *mode = ThemeAppearanceMode::from(theme_appearance);
+ *mode = appearance_to_mode(theme_appearance);
}
}
}
@@ -379,9 +348,6 @@ pub fn set_mode(content: &mut SettingsContent, mode: ThemeAppearanceMode) {
if let Some(selection) = theme.theme.as_mut() {
match selection {
settings::ThemeSelection::Static(_) => {
- // If the theme was previously set to a single static theme,
- // reset to the default dynamic light/dark pair and let users
- // customize light/dark themes explicitly afterward.
*selection = settings::ThemeSelection::Dynamic {
mode: ThemeAppearanceMode::System,
light: ThemeName(settings::DEFAULT_LIGHT_THEME.into()),
@@ -404,9 +370,6 @@ pub fn set_mode(content: &mut SettingsContent, mode: ThemeAppearanceMode) {
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(),
@@ -424,7 +387,6 @@ pub fn set_mode(content: &mut SettingsContent, mode: ThemeAppearanceMode) {
)));
}
}
-// }
/// The buffer's line height.
#[derive(Clone, Copy, Debug, PartialEq, Default)]
@@ -530,7 +492,6 @@ impl ThemeSettings {
self.agent_buffer_font_size
}
- // TODO: Rename: `line_height` -> `buffer_line_height`
/// Returns the buffer's line height.
pub fn line_height(&self) -> f32 {
f32::max(self.buffer_line_height.value(), MIN_LINE_HEIGHT)
@@ -538,7 +499,6 @@ impl ThemeSettings {
/// 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> {
- // 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();
ThemeSettings::modify_theme(&mut theme, experimental_theme_overrides);
@@ -566,11 +526,11 @@ impl ThemeSettings {
&status_color_refinement,
));
base_theme.styles.status.refine(&status_color_refinement);
- base_theme.styles.player.merge(&theme_overrides.players);
- base_theme.styles.accents.merge(&theme_overrides.accents);
+ merge_player_colors(&mut base_theme.styles.player, &theme_overrides.players);
+ merge_accent_colors(&mut base_theme.styles.accents, &theme_overrides.accents);
base_theme.styles.syntax = SyntaxTheme::merge(
base_theme.styles.syntax.clone(),
- syntax_overrides(&theme_overrides),
+ syntax_overrides(theme_overrides),
);
}
}
@@ -614,7 +574,6 @@ pub fn reset_buffer_font_size(cx: &mut App) {
}
}
-// TODO: Make private, change usages to use `get_ui_font_size` instead.
#[allow(missing_docs)]
pub fn setup_ui_font(window: &mut Window, cx: &mut App) -> gpui::Font {
let (ui_font, ui_font_size) = {
@@ -0,0 +1,386 @@
+#![deny(missing_docs)]
+
+//! # Theme Settings
+//!
+//! This crate provides theme settings integration for Zed,
+//! bridging the theme system with the settings infrastructure.
+
+mod schema;
+mod settings;
+
+use std::sync::Arc;
+
+use ::settings::{IntoGpui, Settings, SettingsStore};
+use anyhow::{Context as _, Result};
+use gpui::{App, HighlightStyle, Refineable};
+use gpui_util::ResultExt;
+use theme::{
+ AccentColors, Appearance, AppearanceContent, DEFAULT_DARK_THEME, DEFAULT_ICON_THEME_NAME,
+ GlobalTheme, LoadThemes, PlayerColor, PlayerColors, StatusColors, SyntaxTheme,
+ SystemAppearance, SystemColors, Theme, ThemeColors, ThemeFamily, ThemeRegistry, ThemeStyles,
+ default_color_scales, try_parse_color,
+};
+
+pub use crate::schema::{
+ FontStyleContent, FontWeightContent, HighlightStyleContent, StatusColorsContent,
+ ThemeColorsContent, ThemeContent, ThemeFamilyContent, ThemeStyleContent,
+ WindowBackgroundContent, status_colors_refinement, syntax_overrides, theme_colors_refinement,
+};
+pub use crate::settings::{
+ AgentFontSize, BufferLineHeight, FontFamilyName, IconThemeName, IconThemeSelection,
+ ThemeAppearanceMode, ThemeName, ThemeSelection, ThemeSettings, UiDensity,
+ adjust_agent_buffer_font_size, adjust_agent_ui_font_size, adjust_buffer_font_size,
+ adjust_ui_font_size, adjusted_font_size, appearance_to_mode, clamp_font_size, default_theme,
+ observe_buffer_font_size_adjustment, reset_agent_buffer_font_size, reset_agent_ui_font_size,
+ reset_buffer_font_size, reset_ui_font_size, set_icon_theme, set_mode, set_theme, setup_ui_font,
+};
+
+/// Initialize the theme system with settings integration.
+///
+/// This is the full initialization for the application. It calls [`theme::init`]
+/// and then wires up settings observation for theme/font changes.
+pub fn init(themes_to_load: LoadThemes, cx: &mut App) {
+ let load_user_themes = matches!(&themes_to_load, LoadThemes::All(_));
+
+ theme::init(themes_to_load, cx);
+
+ if load_user_themes {
+ let registry = ThemeRegistry::global(cx);
+ load_bundled_themes(®istry);
+ }
+
+ let theme = configured_theme(cx);
+ let icon_theme = configured_icon_theme(cx);
+ GlobalTheme::update_theme(cx, theme);
+ GlobalTheme::update_icon_theme(cx, 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(),
+ );
+
+ 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(),
+ );
+
+ if buffer_font_size_settings != prev_buffer_font_size_settings {
+ prev_buffer_font_size_settings = buffer_font_size_settings;
+ reset_buffer_font_size(cx);
+ }
+
+ if ui_font_size_settings != prev_ui_font_size_settings {
+ prev_ui_font_size_settings = ui_font_size_settings;
+ reset_ui_font_size(cx);
+ }
+
+ 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);
+ }
+
+ 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;
+ reload_theme(cx);
+ }
+
+ if icon_theme_name != prev_icon_theme_name {
+ prev_icon_theme_name = icon_theme_name;
+ reload_icon_theme(cx);
+ }
+ })
+ .detach();
+}
+
+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))
+ .unwrap_or_else(|_| themes.get(DEFAULT_DARK_THEME).unwrap())
+ }
+ };
+ theme_settings.apply_theme_overrides(theme)
+}
+
+fn configured_icon_theme(cx: &mut App) -> Arc<theme::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 theme from settings.
+pub fn reload_theme(cx: &mut App) {
+ let theme = configured_theme(cx);
+ GlobalTheme::update_theme(cx, theme);
+ cx.refresh_windows();
+}
+
+/// Reloads the current icon theme from settings.
+pub fn reload_icon_theme(cx: &mut App) {
+ let icon_theme = configured_icon_theme(cx);
+ GlobalTheme::update_icon_theme(cx, icon_theme);
+ cx.refresh_windows();
+}
+
+/// Loads the themes bundled with the Zed binary into the registry.
+pub fn load_bundled_themes(registry: &ThemeRegistry) {
+ let theme_paths = registry
+ .assets()
+ .list("themes/")
+ .expect("failed to list theme assets")
+ .into_iter()
+ .filter(|path| path.ends_with(".json"));
+
+ for path in theme_paths {
+ let Some(theme) = registry.assets().load(&path).log_err().flatten() else {
+ continue;
+ };
+
+ let Some(theme_family) = serde_json::from_slice(&theme)
+ .with_context(|| format!("failed to parse theme at path \"{path}\""))
+ .log_err()
+ else {
+ continue;
+ };
+
+ let refined = refine_theme_family(theme_family);
+ registry.insert_theme_families([refined]);
+ }
+}
+
+/// Loads a user theme from the given bytes into the registry.
+pub fn load_user_theme(registry: &ThemeRegistry, bytes: &[u8]) -> Result<()> {
+ let theme = deserialize_user_theme(bytes)?;
+ let refined = refine_theme_family(theme);
+ registry.insert_theme_families([refined]);
+ Ok(())
+}
+
+/// Deserializes a user theme from the given bytes.
+pub fn deserialize_user_theme(bytes: &[u8]) -> Result<ThemeFamilyContent> {
+ let theme_family: ThemeFamilyContent = serde_json_lenient::from_slice(bytes)?;
+
+ for theme in &theme_family.themes {
+ if theme
+ .style
+ .colors
+ .deprecated_scrollbar_thumb_background
+ .is_some()
+ {
+ log::warn!(
+ r#"Theme "{theme_name}" is using a deprecated style property: scrollbar_thumb.background. Use `scrollbar.thumb.background` instead."#,
+ theme_name = theme.name
+ )
+ }
+ }
+
+ Ok(theme_family)
+}
+
+/// Refines a [`ThemeFamilyContent`] and its [`ThemeContent`]s into a [`ThemeFamily`].
+pub fn refine_theme_family(theme_family_content: ThemeFamilyContent) -> ThemeFamily {
+ let id = uuid::Uuid::new_v4().to_string();
+ let name = theme_family_content.name.clone();
+ let author = theme_family_content.author.clone();
+
+ let themes: Vec<Theme> = theme_family_content
+ .themes
+ .iter()
+ .map(|theme_content| refine_theme(theme_content))
+ .collect();
+
+ ThemeFamily {
+ id,
+ name: name.into(),
+ author: author.into(),
+ themes,
+ scales: default_color_scales(),
+ }
+}
+
+/// Refines a [`ThemeContent`] into a [`Theme`].
+pub fn refine_theme(theme: &ThemeContent) -> Theme {
+ let appearance = match theme.appearance {
+ AppearanceContent::Light => Appearance::Light,
+ AppearanceContent::Dark => Appearance::Dark,
+ };
+
+ let mut refined_status_colors = match theme.appearance {
+ AppearanceContent::Light => StatusColors::light(),
+ AppearanceContent::Dark => StatusColors::dark(),
+ };
+ let mut status_colors_refinement = status_colors_refinement(&theme.style.status);
+ theme::apply_status_color_defaults(&mut status_colors_refinement);
+ refined_status_colors.refine(&status_colors_refinement);
+
+ let mut refined_player_colors = match theme.appearance {
+ AppearanceContent::Light => PlayerColors::light(),
+ AppearanceContent::Dark => PlayerColors::dark(),
+ };
+ merge_player_colors(&mut refined_player_colors, &theme.style.players);
+
+ let mut refined_theme_colors = match theme.appearance {
+ AppearanceContent::Light => ThemeColors::light(),
+ AppearanceContent::Dark => ThemeColors::dark(),
+ };
+ let mut theme_colors_refinement =
+ theme_colors_refinement(&theme.style.colors, &status_colors_refinement);
+ theme::apply_theme_color_defaults(&mut theme_colors_refinement, &refined_player_colors);
+ refined_theme_colors.refine(&theme_colors_refinement);
+
+ let mut refined_accent_colors = match theme.appearance {
+ AppearanceContent::Light => AccentColors::light(),
+ AppearanceContent::Dark => AccentColors::dark(),
+ };
+ merge_accent_colors(&mut refined_accent_colors, &theme.style.accents);
+
+ let syntax_highlights = theme.style.syntax.iter().map(|(syntax_token, highlight)| {
+ (
+ syntax_token.clone(),
+ HighlightStyle {
+ color: highlight
+ .color
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ background_color: highlight
+ .background_color
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok()),
+ font_style: highlight.font_style.map(|s| s.into_gpui()),
+ font_weight: highlight.font_weight.map(|w| w.into_gpui()),
+ ..Default::default()
+ },
+ )
+ });
+ let syntax_theme = Arc::new(SyntaxTheme::new(syntax_highlights));
+
+ let window_background_appearance = theme
+ .style
+ .window_background_appearance
+ .map(|w| w.into_gpui())
+ .unwrap_or_default();
+
+ Theme {
+ id: uuid::Uuid::new_v4().to_string(),
+ name: theme.name.clone().into(),
+ appearance,
+ styles: ThemeStyles {
+ system: SystemColors::default(),
+ window_background_appearance,
+ accents: refined_accent_colors,
+ colors: refined_theme_colors,
+ status: refined_status_colors,
+ player: refined_player_colors,
+ syntax: syntax_theme,
+ },
+ }
+}
+
+/// Merges player color overrides into the given [`PlayerColors`].
+pub fn merge_player_colors(
+ player_colors: &mut PlayerColors,
+ user_player_colors: &[::settings::PlayerColorContent],
+) {
+ if user_player_colors.is_empty() {
+ return;
+ }
+
+ for (idx, player) in user_player_colors.iter().enumerate() {
+ let cursor = player
+ .cursor
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok());
+ let background = player
+ .background
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok());
+ let selection = player
+ .selection
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok());
+
+ if let Some(player_color) = player_colors.0.get_mut(idx) {
+ *player_color = PlayerColor {
+ cursor: cursor.unwrap_or(player_color.cursor),
+ background: background.unwrap_or(player_color.background),
+ selection: selection.unwrap_or(player_color.selection),
+ };
+ } else {
+ player_colors.0.push(PlayerColor {
+ cursor: cursor.unwrap_or_default(),
+ background: background.unwrap_or_default(),
+ selection: selection.unwrap_or_default(),
+ });
+ }
+ }
+}
+
+/// Merges accent color overrides into the given [`AccentColors`].
+pub fn merge_accent_colors(
+ accent_colors: &mut AccentColors,
+ user_accent_colors: &[::settings::AccentContent],
+) {
+ if user_accent_colors.is_empty() {
+ return;
+ }
+
+ let colors = user_accent_colors
+ .iter()
+ .filter_map(|accent_color| {
+ accent_color
+ .0
+ .as_ref()
+ .and_then(|color| try_parse_color(color).ok())
+ })
+ .collect::<Vec<_>>();
+
+ if !colors.is_empty() {
+ accent_colors.0 = Arc::from(colors);
+ }
+}
@@ -28,6 +28,7 @@ smallvec.workspace = true
story = { workspace = true, optional = true }
strum.workspace = true
theme.workspace = true
+theme_settings.workspace = true
ui_macros.workspace = true
gpui_util.workspace = true
@@ -15,7 +15,7 @@ use std::{
rc::Rc,
time::{Duration, Instant},
};
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum SubmenuOpenTrigger {
@@ -2,7 +2,7 @@ use crate::prelude::*;
use gpui::{FontWeight, Rems, StyleRefinement, UnderlineStyle};
use settings::Settings;
use smallvec::SmallVec;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
/// Sets the size of a label
#[derive(Debug, PartialEq, Clone, Copy, Default)]
@@ -191,7 +191,9 @@ impl LabelCommon for LabelLike {
}
fn buffer_font(mut self, cx: &App) -> Self {
- let font = theme::ThemeSettings::get_global(cx).buffer_font.clone();
+ let font = theme_settings::ThemeSettings::get_global(cx)
+ .buffer_font
+ .clone();
self.weight = Some(font.weight);
self.base = self.base.font(font);
self
@@ -200,7 +202,11 @@ impl LabelCommon for LabelLike {
fn inline_code(mut self, cx: &App) -> Self {
self.base = self
.base
- .font(theme::ThemeSettings::get_global(cx).buffer_font.clone())
+ .font(
+ theme_settings::ThemeSettings::get_global(cx)
+ .buffer_font
+ .clone(),
+ )
.bg(cx.theme().colors().element_background)
.rounded_sm()
.px_0p5();
@@ -4,7 +4,7 @@ use crate::{Disclosure, prelude::*};
use component::{Component, ComponentScope, example_group_with_title, single_example};
use gpui::{AnyElement, ClickEvent};
use settings::Settings;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
#[derive(IntoElement, RegisterComponent)]
pub struct ListHeader {
@@ -91,7 +91,7 @@ impl RenderOnce for ListHeader {
.child(
div()
.map(|this| match ui_density {
- theme::UiDensity::Comfortable => this.h_5(),
+ theme_settings::UiDensity::Comfortable => this.h_5(),
_ => this.h_7(),
})
.when(self.inset, |this| this.px_2())
@@ -3,7 +3,7 @@ use std::rc::Rc;
use gpui::{Action, AnyElement, AnyView, AppContext, FocusHandle, IntoElement, Render};
use settings::Settings;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use crate::prelude::*;
use crate::{Color, KeyBinding, Label, LabelSize, StyledExt, h_flex, v_flex};
@@ -1,6 +1,6 @@
use gpui::{App, Pixels, Rems, px, rems};
use settings::Settings;
-use theme::{ThemeSettings, UiDensity};
+use theme_settings::{ThemeSettings, UiDensity};
use ui_macros::derive_dynamic_spacing;
// Derives [DynamicSpacing]. See [ui_macros::derive_dynamic_spacing].
@@ -4,7 +4,8 @@ use gpui::{
div, rems,
};
use settings::Settings;
-use theme::{ActiveTheme, ThemeSettings};
+use theme::ActiveTheme;
+use theme_settings::ThemeSettings;
use crate::{Color, rems_from_px};
@@ -66,9 +66,9 @@ pub fn derive_spacing(input: TokenStream) -> TokenStream {
let n = n.base10_parse::<f32>().unwrap();
quote! {
DynamicSpacing::#variant => match ThemeSettings::get_global(cx).ui_density {
- ::theme::UiDensity::Compact => (#n - 4.0).max(0.0) / BASE_REM_SIZE_IN_PX,
- ::theme::UiDensity::Default => #n / BASE_REM_SIZE_IN_PX,
- ::theme::UiDensity::Comfortable => (#n + 4.0) / BASE_REM_SIZE_IN_PX,
+ ::theme_settings::UiDensity::Compact => (#n - 4.0).max(0.0) / BASE_REM_SIZE_IN_PX,
+ ::theme_settings::UiDensity::Default => #n / BASE_REM_SIZE_IN_PX,
+ ::theme_settings::UiDensity::Comfortable => (#n + 4.0) / BASE_REM_SIZE_IN_PX,
}
}
}
@@ -78,9 +78,9 @@ pub fn derive_spacing(input: TokenStream) -> TokenStream {
let c = c.base10_parse::<f32>().unwrap();
quote! {
DynamicSpacing::#variant => match ThemeSettings::get_global(cx).ui_density {
- ::theme::UiDensity::Compact => #a / BASE_REM_SIZE_IN_PX,
- ::theme::UiDensity::Default => #b / BASE_REM_SIZE_IN_PX,
- ::theme::UiDensity::Comfortable => #c / BASE_REM_SIZE_IN_PX,
+ ::theme_settings::UiDensity::Compact => #a / BASE_REM_SIZE_IN_PX,
+ ::theme_settings::UiDensity::Default => #b / BASE_REM_SIZE_IN_PX,
+ ::theme_settings::UiDensity::Comfortable => #c / BASE_REM_SIZE_IN_PX,
}
}
}
@@ -19,6 +19,6 @@ gpui.workspace = true
markdown.workspace = true
menu.workspace = true
settings.workspace = true
-theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
workspace.workspace = true
@@ -5,7 +5,7 @@ use gpui::{
};
use markdown::{Markdown, MarkdownElement, MarkdownStyle};
use settings::{Settings, SettingsStore};
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{FluentBuilder, TintColor, prelude::*};
use workspace::WorkspaceSettings;
@@ -44,6 +44,7 @@ settings.workspace = true
task.workspace = true
text.workspace = true
theme.workspace = true
+theme_settings.workspace = true
menu.workspace = true
tokio = { version = "1.15", features = ["full"], optional = true }
ui.workspace = true
@@ -29,7 +29,7 @@ use std::collections::HashSet;
use std::path::Path;
use std::{fmt::Display, ops::Range, sync::Arc};
use text::{Bias, ToPoint};
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{
ActiveTheme, Context, Div, FluentBuilder, KeyBinding, ParentElement, SharedString, Styled,
StyledTypography, Window, h_flex, rems,
@@ -27,7 +27,7 @@ impl VimTestContext {
git_ui::init(cx);
crate::init(cx);
search::init(cx);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
settings_ui::init(cx);
markdown_preview::init(cx);
zed_actions::init();
@@ -51,7 +51,7 @@ pub use settings::{
use state::{Mode, Operator, RecordedSelection, SearchState, VimGlobals};
use std::{mem, ops::Range, sync::Arc};
use surrounds::SurroundsType;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{IntoElement, SharedString, px};
use vim_mode_setting::HelixModeSetting;
use vim_mode_setting::VimModeSetting;
@@ -17,7 +17,7 @@ command_palette.workspace = true
gpui.workspace = true
serde.workspace = true
settings.workspace = true
-theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
util.workspace = true
workspace.workspace = true
@@ -7,7 +7,7 @@ use gpui::{
};
use settings::Settings;
use std::collections::HashMap;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{
Divider, DividerColor, DynamicSpacing, LabelSize, WithScrollbar, prelude::*,
text_for_keystrokes,
@@ -63,6 +63,7 @@ strum.workspace = true
task.workspace = true
telemetry.workspace = true
theme.workspace = true
+theme_settings.workspace = true
ui.workspace = true
util.workspace = true
uuid.workspace = true
@@ -883,7 +883,7 @@ impl Render for MultiWorkspace {
(sidebar, None)
};
- let ui_font = theme::setup_ui_font(window, cx);
+ let ui_font = theme_settings::setup_ui_font(window, cx);
let text_color = cx.theme().colors().text;
let workspace = self.workspace().clone();
@@ -970,7 +970,7 @@ mod tests {
cx.update(|cx| {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
DisableAiSettings::register(cx);
cx.update_flags(false, vec!["agent-v2".into()]);
});
@@ -9,7 +9,7 @@ use markdown::{Markdown, MarkdownElement, MarkdownStyle};
use parking_lot::Mutex;
use project::project_settings::ProjectSettings;
use settings::Settings;
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use std::ops::Deref;
use std::sync::{Arc, LazyLock};
@@ -42,7 +42,7 @@ use std::{
},
time::Duration,
};
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{
ContextMenu, ContextMenuEntry, ContextMenuItem, DecoratedIcon, IconButtonShape, IconDecoration,
IconDecorationKind, Indicator, PopoverMenu, PopoverMenuHandle, Tab, TabBar, TabPosition,
@@ -8515,7 +8515,7 @@ mod tests {
cx.update(|cx| {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
- theme::init(LoadThemes::JustBase, cx);
+ theme_settings::init(LoadThemes::JustBase, cx);
});
}
@@ -254,7 +254,7 @@ mod tests {
cx.update(|cx| {
let settings_store = settings::SettingsStore::test(cx);
cx.set_global(settings_store);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
register_serializable_item::<TestItem>(cx);
});
let fs = FakeFs::new(cx.executor());
@@ -130,7 +130,8 @@ use std::{
time::Duration,
};
use task::{DebugScenario, SharedTaskContext, SpawnInTerminal};
-use theme::{ActiveTheme, GlobalTheme, SystemAppearance, ThemeSettings};
+use theme::{ActiveTheme, SystemAppearance};
+use theme_settings::ThemeSettings;
pub use toolbar::{
PaneSearchBarCallbacks, Toolbar, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView,
};
@@ -1142,7 +1143,7 @@ impl AppState {
let user_store = cx.new(|cx| UserStore::new(client.clone(), cx));
let workspace_store = cx.new(|cx| WorkspaceStore::new(client.clone(), cx));
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
client::init(&client, cx);
Arc::new(Self {
@@ -1682,8 +1683,8 @@ impl Workspace {
*SystemAppearance::global_mut(cx) = SystemAppearance(window_appearance.into());
- GlobalTheme::reload_theme(cx);
- GlobalTheme::reload_icon_theme(cx);
+ theme_settings::reload_theme(cx);
+ theme_settings::reload_icon_theme(cx);
}),
cx.on_release({
let weak_handle = weak_handle.clone();
@@ -7473,17 +7474,23 @@ impl Workspace {
fn toggle_theme_mode(&mut self, _: &ToggleMode, _window: &mut Window, cx: &mut Context<Self>) {
let current_mode = ThemeSettings::get_global(cx).theme.mode();
let next_mode = match current_mode {
- Some(theme::ThemeAppearanceMode::Light) => theme::ThemeAppearanceMode::Dark,
- Some(theme::ThemeAppearanceMode::Dark) => theme::ThemeAppearanceMode::Light,
- Some(theme::ThemeAppearanceMode::System) | None => match cx.theme().appearance() {
- theme::Appearance::Light => theme::ThemeAppearanceMode::Dark,
- theme::Appearance::Dark => theme::ThemeAppearanceMode::Light,
- },
+ Some(theme_settings::ThemeAppearanceMode::Light) => {
+ theme_settings::ThemeAppearanceMode::Dark
+ }
+ Some(theme_settings::ThemeAppearanceMode::Dark) => {
+ theme_settings::ThemeAppearanceMode::Light
+ }
+ Some(theme_settings::ThemeAppearanceMode::System) | None => {
+ match cx.theme().appearance() {
+ theme::Appearance::Light => theme_settings::ThemeAppearanceMode::Dark,
+ theme::Appearance::Dark => theme_settings::ThemeAppearanceMode::Light,
+ }
+ }
};
let fs = self.project().read(cx).fs().clone();
settings::update_settings_file(fs, cx, move |settings, _cx| {
- theme::set_mode(settings, next_mode);
+ theme_settings::set_mode(settings, next_mode);
});
}
@@ -7912,7 +7919,7 @@ impl Render for Workspace {
} else {
(None, None)
};
- let ui_font = theme::setup_ui_font(window, cx);
+ let ui_font = theme_settings::setup_ui_font(window, cx);
let theme = cx.theme().clone();
let colors = theme.colors();
@@ -14409,7 +14416,7 @@ mod tests {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
cx.set_global(db::AppDatabase::test_new());
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
});
}
@@ -197,6 +197,7 @@ telemetry.workspace = true
telemetry_events.workspace = true
terminal_view.workspace = true
theme.workspace = true
+theme_settings.workspace = true
theme_extension.workspace = true
theme_selector.workspace = true
time.workspace = true
@@ -52,6 +52,7 @@ use std::{
time::Instant,
};
use theme::{ActiveTheme, GlobalTheme, ThemeRegistry};
+use theme_settings::load_user_theme;
use util::{ResultExt, TryFutureExt, maybe};
use uuid::Uuid;
use workspace::{
@@ -639,7 +640,7 @@ fn main() {
cx,
);
- theme::init(theme::LoadThemes::All(Box::new(Assets)), cx);
+ theme_settings::init(theme::LoadThemes::All(Box::new(Assets)), cx);
eager_load_active_theme_and_icon_theme(fs.clone(), cx);
theme_extension::init(
extension_host_proxy,
@@ -1796,10 +1797,10 @@ fn load_user_themes_in_background(fs: Arc<dyn fs::Fs>, cx: &mut App) {
continue;
};
- theme_registry.load_user_theme(&bytes).log_err();
+ load_user_theme(&theme_registry, &bytes).log_err();
}
- cx.update(GlobalTheme::reload_theme);
+ cx.update(theme_settings::reload_theme);
anyhow::Ok(())
}
})
@@ -1819,9 +1820,9 @@ fn watch_themes(fs: Arc<dyn fs::Fs>, cx: &mut App) {
if fs.metadata(&event.path).await.ok().flatten().is_some() {
let theme_registry = cx.update(|cx| ThemeRegistry::global(cx));
if let Some(bytes) = fs.load_bytes(&event.path).await.log_err()
- && theme_registry.load_user_theme(&bytes).log_err().is_some()
+ && load_user_theme(&theme_registry, &bytes).log_err().is_some()
{
- cx.update(GlobalTheme::reload_theme);
+ cx.update(theme_settings::reload_theme);
}
}
}
@@ -176,7 +176,7 @@ fn run_visual_tests(project_path: PathBuf, update_baseline: bool) -> Result<()>
// Initialize all Zed subsystems
cx.update(|cx| {
gpui_tokio::init(cx);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
client::init(&app_state.client, cx);
audio::init(cx);
workspace::init(app_state.clone(), cx);
@@ -965,7 +965,7 @@ fn init_app_state(cx: &mut App) -> Arc<AppState> {
let user_store = cx.new(|cx| client::UserStore::new(client.clone(), cx));
let workspace_store = cx.new(|cx| workspace::WorkspaceStore::new(client.clone(), cx));
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
client::init(&client, cx);
let app_state = Arc::new(AppState {
@@ -77,10 +77,8 @@ use std::{
sync::atomic::{self, AtomicBool},
};
use terminal_view::terminal_panel::{self, TerminalPanel};
-use theme::{
- ActiveTheme, GlobalTheme, SystemAppearance, ThemeRegistry, ThemeSettings,
- deserialize_icon_theme,
-};
+use theme::{ActiveTheme, SystemAppearance, ThemeRegistry, deserialize_icon_theme};
+use theme_settings::{ThemeSettings, load_user_theme};
use ui::{PopoverMenuHandle, prelude::*};
use util::markdown::MarkdownString;
use util::rel_path::RelPath;
@@ -903,10 +901,10 @@ fn register_actions(
let _ = settings
.theme
.ui_font_size
- .insert(f32::from(theme::clamp_font_size(ui_font_size)).into());
+ .insert(f32::from(theme_settings::clamp_font_size(ui_font_size)).into());
});
} else {
- theme::adjust_ui_font_size(cx, |size| size + px(1.0));
+ theme_settings::adjust_ui_font_size(cx, |size| size + px(1.0));
}
}
})
@@ -919,10 +917,10 @@ fn register_actions(
let _ = settings
.theme
.ui_font_size
- .insert(f32::from(theme::clamp_font_size(ui_font_size)).into());
+ .insert(f32::from(theme_settings::clamp_font_size(ui_font_size)).into());
});
} else {
- theme::adjust_ui_font_size(cx, |size| size - px(1.0));
+ theme_settings::adjust_ui_font_size(cx, |size| size - px(1.0));
}
}
})
@@ -934,7 +932,7 @@ fn register_actions(
settings.theme.ui_font_size = None;
});
} else {
- theme::reset_ui_font_size(cx);
+ theme_settings::reset_ui_font_size(cx);
}
}
})
@@ -948,10 +946,10 @@ fn register_actions(
let _ = settings
.theme
.buffer_font_size
- .insert(f32::from(theme::clamp_font_size(buffer_font_size)).into());
+ .insert(f32::from(theme_settings::clamp_font_size(buffer_font_size)).into());
});
} else {
- theme::adjust_buffer_font_size(cx, |size| size + px(1.0));
+ theme_settings::adjust_buffer_font_size(cx, |size| size + px(1.0));
}
}
})
@@ -965,10 +963,10 @@ fn register_actions(
let _ = settings
.theme
.buffer_font_size
- .insert(f32::from(theme::clamp_font_size(buffer_font_size)).into());
+ .insert(f32::from(theme_settings::clamp_font_size(buffer_font_size)).into());
});
} else {
- theme::adjust_buffer_font_size(cx, |size| size - px(1.0));
+ theme_settings::adjust_buffer_font_size(cx, |size| size - px(1.0));
}
}
})
@@ -980,7 +978,7 @@ fn register_actions(
settings.theme.buffer_font_size = None;
});
} else {
- theme::reset_buffer_font_size(cx);
+ theme_settings::reset_buffer_font_size(cx);
}
}
})
@@ -995,10 +993,10 @@ fn register_actions(
settings.theme.agent_buffer_font_size = None;
});
} else {
- theme::reset_ui_font_size(cx);
- theme::reset_buffer_font_size(cx);
- theme::reset_agent_ui_font_size(cx);
- theme::reset_agent_buffer_font_size(cx);
+ theme_settings::reset_ui_font_size(cx);
+ theme_settings::reset_buffer_font_size(cx);
+ theme_settings::reset_agent_ui_font_size(cx);
+ theme_settings::reset_agent_buffer_font_size(cx);
}
}
})
@@ -2228,7 +2226,7 @@ pub(crate) fn eager_load_active_theme_and_icon_theme(fs: Arc<dyn Fs>, cx: &mut A
match load_target {
LoadTarget::Theme(theme_path) => {
if let Some(bytes) = fs.load_bytes(&theme_path).await.log_err()
- && theme_registry.load_user_theme(&bytes).log_err().is_some()
+ && load_user_theme(theme_registry, &bytes).log_err().is_some()
{
reload_tasks.lock().push(ReloadTarget::Theme);
}
@@ -2252,8 +2250,8 @@ pub(crate) fn eager_load_active_theme_and_icon_theme(fs: Arc<dyn Fs>, cx: &mut A
for reload_target in reload_tasks.into_inner() {
match reload_target {
- ReloadTarget::Theme => GlobalTheme::reload_theme(cx),
- ReloadTarget::IconTheme => GlobalTheme::reload_icon_theme(cx),
+ ReloadTarget::Theme => theme_settings::reload_theme(cx),
+ ReloadTarget::IconTheme => theme_settings::reload_icon_theme(cx),
};
}
}
@@ -4457,7 +4455,7 @@ mod tests {
cx.update(|cx| {
let app_state = AppState::test(cx);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
client::init(&app_state.client, cx);
workspace::init(app_state.clone(), cx);
onboarding::init(cx);
@@ -4875,7 +4873,7 @@ mod tests {
.unwrap();
let themes = ThemeRegistry::default();
settings::init(cx);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
let mut has_default_theme = false;
for theme_name in themes.list().into_iter().map(|meta| meta.name) {
@@ -5013,7 +5011,7 @@ mod tests {
app_state.languages.add(markdown_lang());
gpui_tokio::init(cx);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
audio::init(cx);
channel::init(&app_state.client, app_state.user_store.clone(), cx);
call::init(app_state.client.clone(), app_state.user_store.clone(), cx);
@@ -11,7 +11,7 @@ use std::sync::Arc;
use gpui::{Entity, EventEmitter, Global, Task, TextStyle, TextStyleRefinement};
use markdown::{Markdown, MarkdownElement, MarkdownStyle};
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::prelude::*;
use workspace::item::ItemHandle;
use workspace::{ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace};
@@ -16,7 +16,7 @@ use markdown::{CodeBlockRenderer, Markdown, MarkdownElement, MarkdownStyle};
use project::Project;
use settings::Settings;
use telemetry_events::{Event, EventWrapper};
-use theme::ThemeSettings;
+use theme_settings::ThemeSettings;
use ui::{
Icon, IconButton, IconName, IconSize, Label, TextSize, Tooltip, WithScrollbar, prelude::*,
};
@@ -51,7 +51,7 @@ pub fn init_visual_test(cx: &mut VisualTestAppContext) -> Arc<AppState> {
let app_state = AppState::test(cx);
gpui_tokio::init(cx);
- theme::init(theme::LoadThemes::JustBase, cx);
+ theme_settings::init(theme::LoadThemes::JustBase, cx);
audio::init(cx);
workspace::init(app_state.clone(), cx);
release_channel::init(semver::Version::new(0, 0, 0), cx);