settings_ui: Get editor settings working (#37330)
Closes #ISSUE This PR includes the necessary work to get `EditorSettings` showing up in the settings UI. Including making the `path` field on `SettingsUiItem`'s optional so that top level items such as `EditorSettings` which have `Settings::KEY = None` (i.e. are treated like `serde(flatten)`) have their paths computed correctly for JSON reading/updating. It includes the first examples of a pattern I expect to continue with the `SettingsUi` work with respect to settings reorganization, that being adding missing defaults, and adding explicit values (or aliases) to settings which previously relied on `null` being a value for optional fields. Release Notes: - N/A *or* Added/Fixed/Improved ...
This commit is contained in:
@@ -4,7 +4,7 @@ mod keymap_file;
|
||||
mod settings_file;
|
||||
mod settings_json;
|
||||
mod settings_store;
|
||||
mod settings_ui;
|
||||
mod settings_ui_core;
|
||||
mod vscode_import;
|
||||
|
||||
use gpui::{App, Global};
|
||||
@@ -24,7 +24,7 @@ pub use settings_store::{
|
||||
InvalidSettingsError, LocalSettingsKind, Settings, SettingsLocation, SettingsSources,
|
||||
SettingsStore,
|
||||
};
|
||||
pub use settings_ui::*;
|
||||
pub use settings_ui_core::*;
|
||||
// Re-export the derive macro
|
||||
pub use settings_ui_macros::SettingsUi;
|
||||
pub use vscode_import::{VsCodeSettings, VsCodeSettingsSource};
|
||||
|
||||
@@ -33,7 +33,7 @@ pub type EditorconfigProperties = ec4rs::Properties;
|
||||
use crate::{
|
||||
ActiveSettingsProfileName, ParameterizedJsonSchema, SettingsJsonSchemaParams, SettingsUiEntry,
|
||||
VsCodeSettings, WorktreeId, parse_json_with_comments, replace_value_in_json_text,
|
||||
settings_ui::SettingsUi, update_value_in_json_text,
|
||||
settings_ui_core::SettingsUi, update_value_in_json_text,
|
||||
};
|
||||
|
||||
/// A value that can be defined as a user setting.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::any::TypeId;
|
||||
|
||||
use anyhow::Context as _;
|
||||
use fs::Fs;
|
||||
use gpui::{AnyElement, App, AppContext as _, ReadGlobal as _, Window};
|
||||
@@ -14,40 +16,26 @@ pub trait SettingsUi {
|
||||
|
||||
fn settings_ui_entry() -> SettingsUiEntry {
|
||||
SettingsUiEntry {
|
||||
item: SettingsUiEntryVariant::None,
|
||||
path: None,
|
||||
title: "None entry",
|
||||
item: SettingsUiItem::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SettingsUiEntry {
|
||||
// todo(settings_ui): move this back here once there isn't a None variant
|
||||
// pub path: &'static str,
|
||||
// pub title: &'static str,
|
||||
pub item: SettingsUiEntryVariant,
|
||||
}
|
||||
|
||||
pub enum SettingsUiEntryVariant {
|
||||
Group {
|
||||
path: &'static str,
|
||||
title: &'static str,
|
||||
items: Vec<SettingsUiEntry>,
|
||||
},
|
||||
Item {
|
||||
path: &'static str,
|
||||
item: SettingsUiItemSingle,
|
||||
},
|
||||
Dynamic {
|
||||
path: &'static str,
|
||||
options: Vec<SettingsUiEntry>,
|
||||
determine_option: fn(&serde_json::Value, &mut App) -> usize,
|
||||
},
|
||||
// todo(settings_ui): remove
|
||||
None,
|
||||
/// The path in the settings JSON file for this setting. Relative to parent
|
||||
/// None implies `#[serde(flatten)]` or `Settings::KEY.is_none()` for top level settings
|
||||
pub path: Option<&'static str>,
|
||||
pub title: &'static str,
|
||||
pub item: SettingsUiItem,
|
||||
}
|
||||
|
||||
pub enum SettingsUiItemSingle {
|
||||
SwitchField,
|
||||
NumericStepper,
|
||||
/// A numeric stepper for a specific type of number
|
||||
NumericStepper(NumType),
|
||||
ToggleGroup(&'static [&'static str]),
|
||||
/// This should be used when toggle group size > 6
|
||||
DropDown(&'static [&'static str]),
|
||||
@@ -96,16 +84,19 @@ impl<T: serde::Serialize> SettingsValue<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SettingsUiItemDynamic {
|
||||
pub options: Vec<SettingsUiEntry>,
|
||||
pub determine_option: fn(&serde_json::Value, &mut App) -> usize,
|
||||
}
|
||||
|
||||
pub struct SettingsUiItemGroup {
|
||||
pub items: Vec<SettingsUiEntry>,
|
||||
}
|
||||
|
||||
pub enum SettingsUiItem {
|
||||
Group {
|
||||
title: &'static str,
|
||||
items: Vec<SettingsUiEntry>,
|
||||
},
|
||||
Group(SettingsUiItemGroup),
|
||||
Single(SettingsUiItemSingle),
|
||||
Dynamic {
|
||||
options: Vec<SettingsUiEntry>,
|
||||
determine_option: fn(&serde_json::Value, &mut App) -> usize,
|
||||
},
|
||||
Dynamic(SettingsUiItemDynamic),
|
||||
None,
|
||||
}
|
||||
|
||||
@@ -121,8 +112,56 @@ impl SettingsUi for Option<bool> {
|
||||
}
|
||||
}
|
||||
|
||||
impl SettingsUi for u64 {
|
||||
fn settings_ui_item() -> SettingsUiItem {
|
||||
SettingsUiItem::Single(SettingsUiItemSingle::NumericStepper)
|
||||
#[repr(u8)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum NumType {
|
||||
U64 = 0,
|
||||
U32 = 1,
|
||||
F32 = 2,
|
||||
}
|
||||
pub static NUM_TYPE_NAMES: std::sync::LazyLock<[&'static str; NumType::COUNT]> =
|
||||
std::sync::LazyLock::new(|| NumType::ALL.map(NumType::type_name));
|
||||
pub static NUM_TYPE_IDS: std::sync::LazyLock<[TypeId; NumType::COUNT]> =
|
||||
std::sync::LazyLock::new(|| NumType::ALL.map(NumType::type_id));
|
||||
|
||||
impl NumType {
|
||||
const COUNT: usize = 3;
|
||||
const ALL: [NumType; Self::COUNT] = [NumType::U64, NumType::U32, NumType::F32];
|
||||
|
||||
pub fn type_id(self) -> TypeId {
|
||||
match self {
|
||||
NumType::U64 => TypeId::of::<u64>(),
|
||||
NumType::U32 => TypeId::of::<u32>(),
|
||||
NumType::F32 => TypeId::of::<f32>(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_name(self) -> &'static str {
|
||||
match self {
|
||||
NumType::U64 => std::any::type_name::<u64>(),
|
||||
NumType::U32 => std::any::type_name::<u32>(),
|
||||
NumType::F32 => std::any::type_name::<f32>(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! numeric_stepper_for_num_type {
|
||||
($type:ty, $num_type:ident) => {
|
||||
impl SettingsUi for $type {
|
||||
fn settings_ui_item() -> SettingsUiItem {
|
||||
SettingsUiItem::Single(SettingsUiItemSingle::NumericStepper(NumType::$num_type))
|
||||
}
|
||||
}
|
||||
|
||||
impl SettingsUi for Option<$type> {
|
||||
fn settings_ui_item() -> SettingsUiItem {
|
||||
SettingsUiItem::Single(SettingsUiItemSingle::NumericStepper(NumType::$num_type))
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
numeric_stepper_for_num_type!(u64, U64);
|
||||
numeric_stepper_for_num_type!(u32, U32);
|
||||
// todo(settings_ui) is there a better ui for f32?
|
||||
numeric_stepper_for_num_type!(f32, F32);
|
||||
Reference in New Issue
Block a user