settings_ui: Add dynamic setting fields (#40443)

Closes #ISSUE

Includes the start of how we can get rid of most of the `.unimplemented`
"Edit in JSON" buttons in the settings UI. For now only Theme selection
is implemented, follow ups will add more settings

Release Notes:

- N/A *or* Added/Fixed/Improved ...
This commit is contained in:
Ben Kunkle
2025-10-17 09:13:34 -04:00
committed by GitHub
parent b7112320bb
commit 9056d77604
6 changed files with 2392 additions and 2367 deletions
+24 -2
View File
@@ -125,7 +125,18 @@ fn default_buffer_font_weight() -> Option<FontWeight> {
}
/// Represents the selection of a theme, which can be either static or dynamic.
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
#[derive(
Clone,
Debug,
Serialize,
Deserialize,
JsonSchema,
MergeFrom,
PartialEq,
Eq,
strum::EnumDiscriminants,
)]
#[strum_discriminants(derive(strum::VariantArray, strum::VariantNames, strum::FromRepr))]
#[serde(untagged)]
pub enum ThemeSelection {
/// A static theme selection, represented by a single theme name.
@@ -167,7 +178,18 @@ pub enum IconThemeSelection {
///
/// `System` will select the theme based on the system's appearance.
#[derive(
Debug, PartialEq, Eq, Clone, Copy, Default, Serialize, Deserialize, JsonSchema, MergeFrom,
Debug,
PartialEq,
Eq,
Clone,
Copy,
Default,
Serialize,
Deserialize,
JsonSchema,
MergeFrom,
strum::VariantArray,
strum::VariantNames,
)]
#[serde(rename_all = "snake_case")]
pub enum ThemeMode {
+28 -18
View File
@@ -535,30 +535,30 @@ impl SettingsStore {
/// Returns the first file found that contains the value.
/// The value will only be None if no file contains the value.
/// I.e. if no file contains the value, returns `(File::Default, None)`
pub fn get_value_from_file<T>(
&self,
pub fn get_value_from_file<'a, T: 'a>(
&'a self,
target_file: SettingsFile,
pick: fn(&SettingsContent) -> &Option<T>,
) -> (SettingsFile, Option<&T>) {
pick: fn(&'a SettingsContent) -> Option<T>,
) -> (SettingsFile, Option<T>) {
self.get_value_from_file_inner(target_file, pick, true)
}
/// Same as `Self::get_value_from_file` except that it does not include the current file.
/// Therefore it returns the value that was potentially overloaded by the target file.
pub fn get_value_up_to_file<T>(
&self,
pub fn get_value_up_to_file<'a, T: 'a>(
&'a self,
target_file: SettingsFile,
pick: fn(&SettingsContent) -> &Option<T>,
) -> (SettingsFile, Option<&T>) {
pick: fn(&'a SettingsContent) -> Option<T>,
) -> (SettingsFile, Option<T>) {
self.get_value_from_file_inner(target_file, pick, false)
}
fn get_value_from_file_inner<T>(
&self,
fn get_value_from_file_inner<'a, T: 'a>(
&'a self,
target_file: SettingsFile,
pick: fn(&SettingsContent) -> &Option<T>,
pick: fn(&'a SettingsContent) -> Option<T>,
include_target_file: bool,
) -> (SettingsFile, Option<&T>) {
) -> (SettingsFile, Option<T>) {
// todo(settings_ui): Add a metadata field for overriding the "overrides" tag, for contextually different settings
// e.g. disable AI isn't overridden, or a vec that gets extended instead or some such
@@ -588,7 +588,7 @@ impl SettingsStore {
let Some(content) = self.get_content_for_file(file.clone()) else {
continue;
};
if let Some(value) = pick(content).as_ref() {
if let Some(value) = pick(content) {
return (file, Some(value));
}
}
@@ -1774,11 +1774,16 @@ mod tests {
)
.unwrap();
fn get(content: &SettingsContent) -> &Option<u32> {
&content.project.all_languages.defaults.preferred_line_length
fn get(content: &SettingsContent) -> Option<&u32> {
content
.project
.all_languages
.defaults
.preferred_line_length
.as_ref()
}
let default_value = get(&store.default_settings).unwrap();
let default_value = *get(&store.default_settings).unwrap();
assert_eq!(
store.get_value_from_file(SettingsFile::Project(local.clone()), get),
@@ -1841,8 +1846,13 @@ mod tests {
.into_arc(),
);
fn get(content: &SettingsContent) -> &Option<u32> {
&content.project.all_languages.defaults.preferred_line_length
fn get(content: &SettingsContent) -> Option<&u32> {
content
.project
.all_languages
.defaults
.preferred_line_length
.as_ref()
}
store