settings: Use a derive macro for refine (#38451)
When we refactored settings to not pass JSON blobs around, we ended up needing to write *a lot* of code that just merged things (like json merge used to do). Use a derive macro to prevent typos in this logic. Release Notes: - N/A
This commit is contained in:
+16
-156
@@ -7,17 +7,16 @@ use crate::{
|
||||
use collections::HashMap;
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use gpui::{
|
||||
App, Context, Font, FontFallbacks, FontStyle, FontWeight, Global, Pixels, SharedString,
|
||||
Subscription, Window, px,
|
||||
App, Context, Font, FontFallbacks, FontStyle, FontWeight, Global, Pixels, Subscription, Window,
|
||||
px,
|
||||
};
|
||||
use refineable::Refineable;
|
||||
use schemars::{JsonSchema, json_schema};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
pub use settings::{FontFamilyName, IconThemeName, ThemeMode, ThemeName};
|
||||
use settings::{ParameterizedJsonSchema, Settings, SettingsContent};
|
||||
use settings::{Settings, SettingsContent};
|
||||
use std::sync::Arc;
|
||||
use util::schemars::replace_subschema;
|
||||
use util::{MergeFrom, ResultExt as _};
|
||||
use util::ResultExt as _;
|
||||
|
||||
const MIN_FONT_SIZE: Pixels = px(6.0);
|
||||
const MAX_FONT_SIZE: Pixels = px(100.0);
|
||||
@@ -270,45 +269,6 @@ pub struct AgentFontSize(Pixels);
|
||||
|
||||
impl Global for AgentFontSize {}
|
||||
|
||||
inventory::submit! {
|
||||
ParameterizedJsonSchema {
|
||||
add_and_get_ref: |generator, _params, cx| {
|
||||
replace_subschema::<settings::ThemeName>(generator, || json_schema!({
|
||||
"type": "string",
|
||||
"enum": ThemeRegistry::global(cx).list_names(),
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inventory::submit! {
|
||||
ParameterizedJsonSchema {
|
||||
add_and_get_ref: |generator, _params, cx| {
|
||||
replace_subschema::<settings::IconThemeName>(generator, || json_schema!({
|
||||
"type": "string",
|
||||
"enum": ThemeRegistry::global(cx)
|
||||
.list_icon_themes()
|
||||
.into_iter()
|
||||
.map(|icon_theme| icon_theme.name)
|
||||
.collect::<Vec<SharedString>>(),
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inventory::submit! {
|
||||
ParameterizedJsonSchema {
|
||||
add_and_get_ref: |generator, params, _cx| {
|
||||
replace_subschema::<settings::FontFamilyName>(generator, || {
|
||||
json_schema!({
|
||||
"type": "string",
|
||||
"enum": params.font_names,
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents the selection of a theme, which can be either static or dynamic.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[serde(untagged)]
|
||||
@@ -807,20 +767,20 @@ pub fn font_fallbacks_from_settings(
|
||||
}
|
||||
|
||||
impl settings::Settings for ThemeSettings {
|
||||
fn from_defaults(content: &settings::SettingsContent, cx: &mut App) -> Self {
|
||||
fn from_settings(content: &settings::SettingsContent, cx: &mut App) -> Self {
|
||||
let content = &content.theme;
|
||||
// todo(settings_refactor). This should *not* require cx...
|
||||
let themes = ThemeRegistry::default_global(cx);
|
||||
let system_appearance = SystemAppearance::default_global(cx);
|
||||
let theme_selection: ThemeSelection = content.theme.clone().unwrap().into();
|
||||
let icon_theme_selection: IconThemeSelection = content.icon_theme.clone().unwrap().into();
|
||||
Self {
|
||||
ui_font_size: content.ui_font_size.unwrap().into(),
|
||||
let mut this = Self {
|
||||
ui_font_size: clamp_font_size(content.ui_font_size.unwrap().into()),
|
||||
ui_font: Font {
|
||||
family: content.ui_font_family.as_ref().unwrap().0.clone().into(),
|
||||
features: content.ui_font_features.clone().unwrap(),
|
||||
fallbacks: font_fallbacks_from_settings(content.ui_font_fallbacks.clone()),
|
||||
weight: content.ui_font_weight.map(FontWeight).unwrap(),
|
||||
weight: clamp_font_weight(content.ui_font_weight.unwrap()),
|
||||
style: Default::default(),
|
||||
},
|
||||
buffer_font: Font {
|
||||
@@ -833,12 +793,12 @@ impl settings::Settings for ThemeSettings {
|
||||
.into(),
|
||||
features: content.buffer_font_features.clone().unwrap(),
|
||||
fallbacks: font_fallbacks_from_settings(content.buffer_font_fallbacks.clone()),
|
||||
weight: content.buffer_font_weight.map(FontWeight).unwrap(),
|
||||
weight: clamp_font_weight(content.buffer_font_weight.unwrap()),
|
||||
style: FontStyle::default(),
|
||||
},
|
||||
buffer_font_size: content.buffer_font_size.unwrap().into(),
|
||||
buffer_font_size: clamp_font_size(content.buffer_font_size.unwrap().into()),
|
||||
buffer_line_height: content.buffer_line_height.unwrap().into(),
|
||||
agent_font_size: content.agent_font_size.flatten().map(Into::into),
|
||||
agent_font_size: content.agent_font_size.map(Into::into),
|
||||
active_theme: themes
|
||||
.get(theme_selection.theme(*system_appearance))
|
||||
.or(themes.get(&zed_default_dark().name))
|
||||
@@ -852,110 +812,10 @@ impl settings::Settings for ThemeSettings {
|
||||
.unwrap(),
|
||||
icon_theme_selection: Some(icon_theme_selection),
|
||||
ui_density: content.ui_density.unwrap_or_default().into(),
|
||||
unnecessary_code_fade: content.unnecessary_code_fade.unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
fn refine(&mut self, content: &SettingsContent, cx: &mut App) {
|
||||
let value = &content.theme;
|
||||
|
||||
let themes = ThemeRegistry::default_global(cx);
|
||||
let system_appearance = SystemAppearance::default_global(cx);
|
||||
|
||||
self.ui_density
|
||||
.merge_from(&value.ui_density.map(Into::into));
|
||||
|
||||
if let Some(value) = value.buffer_font_family.clone() {
|
||||
self.buffer_font.family = value.0.into();
|
||||
}
|
||||
if let Some(value) = value.buffer_font_features.clone() {
|
||||
self.buffer_font.features = value;
|
||||
}
|
||||
if let Some(value) = value.buffer_font_fallbacks.clone() {
|
||||
self.buffer_font.fallbacks = font_fallbacks_from_settings(Some(value));
|
||||
}
|
||||
if let Some(value) = value.buffer_font_weight {
|
||||
self.buffer_font.weight = clamp_font_weight(value);
|
||||
}
|
||||
|
||||
if let Some(value) = value.ui_font_family.clone() {
|
||||
self.ui_font.family = value.0.into();
|
||||
}
|
||||
if let Some(value) = value.ui_font_features.clone() {
|
||||
self.ui_font.features = value;
|
||||
}
|
||||
if let Some(value) = value.ui_font_fallbacks.clone() {
|
||||
self.ui_font.fallbacks = font_fallbacks_from_settings(Some(value));
|
||||
}
|
||||
if let Some(value) = value.ui_font_weight {
|
||||
self.ui_font.weight = clamp_font_weight(value);
|
||||
}
|
||||
|
||||
if let Some(value) = &value.theme {
|
||||
self.theme_selection = Some(value.clone().into());
|
||||
|
||||
let theme_name = self
|
||||
.theme_selection
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.theme(*system_appearance);
|
||||
|
||||
match themes.get(theme_name) {
|
||||
Ok(theme) => {
|
||||
self.active_theme = theme;
|
||||
}
|
||||
Err(err @ ThemeNotFoundError(_)) => {
|
||||
if themes.extensions_loaded() {
|
||||
log::error!("{err}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.experimental_theme_overrides
|
||||
.clone_from(&value.experimental_theme_overrides);
|
||||
self.theme_overrides.clone_from(&value.theme_overrides);
|
||||
|
||||
self.apply_theme_overrides();
|
||||
|
||||
if let Some(value) = &value.icon_theme {
|
||||
self.icon_theme_selection = Some(value.clone().into());
|
||||
|
||||
let icon_theme_name = self
|
||||
.icon_theme_selection
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.icon_theme(*system_appearance);
|
||||
|
||||
match themes.get_icon_theme(icon_theme_name) {
|
||||
Ok(icon_theme) => {
|
||||
self.active_icon_theme = icon_theme;
|
||||
}
|
||||
Err(err @ IconThemeNotFoundError(_)) => {
|
||||
if themes.extensions_loaded() {
|
||||
log::error!("{err}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.ui_font_size
|
||||
.merge_from(&value.ui_font_size.map(Into::into).map(clamp_font_size));
|
||||
self.buffer_font_size
|
||||
.merge_from(&value.buffer_font_size.map(Into::into).map(clamp_font_size));
|
||||
self.agent_font_size.merge_from(
|
||||
&value
|
||||
.agent_font_size
|
||||
.map(|value| value.map(Into::into).map(clamp_font_size)),
|
||||
);
|
||||
|
||||
self.buffer_line_height
|
||||
.merge_from(&value.buffer_line_height.map(Into::into));
|
||||
|
||||
// Clamp the `unnecessary_code_fade` to ensure text can't disappear entirely.
|
||||
self.unnecessary_code_fade
|
||||
.merge_from(&value.unnecessary_code_fade);
|
||||
self.unnecessary_code_fade = self.unnecessary_code_fade.clamp(0.0, 0.9);
|
||||
unnecessary_code_fade: content.unnecessary_code_fade.unwrap().clamp(0.0, 0.9),
|
||||
};
|
||||
this.apply_theme_overrides();
|
||||
this
|
||||
}
|
||||
|
||||
fn import_from_vscode(vscode: &settings::VsCodeSettings, current: &mut SettingsContent) {
|
||||
|
||||
Reference in New Issue
Block a user