settings_ui: Refactor item renderers to render entire field (#39959)

Closes #ISSUE

Release Notes:

- N/A *or* Added/Fixed/Improved ...
This commit is contained in:
Ben Kunkle
2025-10-10 12:35:40 -04:00
committed by GitHub
parent 63032f6c66
commit 5e78fb0f94
+223 -292
View File
@@ -8,7 +8,7 @@ use feature_flags::FeatureFlag;
use fuzzy::StringMatchCandidate;
use gpui::{
Action, App, Div, Entity, FocusHandle, Focusable, FontWeight, Global, ReadGlobal as _,
ScrollHandle, Subscription, Task, TitlebarOptions, UniformListScrollHandle, Window,
ScrollHandle, Stateful, Subscription, Task, TitlebarOptions, UniformListScrollHandle, Window,
WindowBounds, WindowHandle, WindowOptions, actions, div, point, prelude::*, px, size,
uniform_list,
};
@@ -83,12 +83,20 @@ actions!(
#[action(namespace = settings_editor)]
struct FocusFile(pub u32);
#[derive(Clone, Copy)]
struct SettingField<T: 'static> {
pick: fn(&SettingsContent) -> &Option<T>,
pick_mut: fn(&mut SettingsContent) -> &mut Option<T>,
}
impl<T: 'static> Clone for SettingField<T> {
fn clone(&self) -> Self {
*self
}
}
// manual impl because derive puts a Copy bound on T, which is inaccurate in our case
impl<T: 'static> Copy for SettingField<T> {}
/// Helper for unimplemented settings, used in combination with `SettingField::unimplemented`
/// to keep the setting around in the UI with valid pick and pick_mut implementations, but don't actually try to render it.
/// TODO(settings_ui): In non-dev builds (`#[cfg(not(debug_assertions))]`) make this render as edit-in-json
@@ -99,7 +107,7 @@ impl<T: 'static> SettingField<T> {
#[allow(unused)]
fn unimplemented(self) -> SettingField<UnimplementedSettingField> {
SettingField {
pick: |_| &None,
pick: |_| &Some(UnimplementedSettingField),
pick_mut: |_| unreachable!(),
}
}
@@ -127,10 +135,6 @@ impl<T> AnySettingField for SettingField<T> {
}
fn file_set_in(&self, file: SettingsUiFile, cx: &App) -> (settings::SettingsFile, bool) {
if AnySettingField::type_id(self) == TypeId::of::<UnimplementedSettingField>() {
return (file.to_settings(), true);
}
let (file, value) = cx
.global::<SettingsStore>()
.get_value_from_file(file.to_settings(), self.pick);
@@ -146,12 +150,13 @@ struct SettingFieldRenderer {
TypeId,
Box<
dyn Fn(
&dyn AnySettingField,
&SettingsWindow,
&SettingItem,
SettingsUiFile,
Option<&SettingsFieldMetadata>,
&mut Window,
&mut App,
) -> AnyElement,
&mut Context<SettingsWindow>,
) -> Stateful<Div>,
>,
>,
>,
@@ -161,10 +166,10 @@ struct SettingFieldRenderer {
impl Global for SettingFieldRenderer {}
impl SettingFieldRenderer {
fn add_renderer<T: 'static>(
fn add_basic_renderer<T: 'static>(
&mut self,
renderer: impl Fn(
&SettingField<T>,
render_control: impl Fn(
SettingField<T>,
SettingsUiFile,
Option<&SettingsFieldMetadata>,
&mut Window,
@@ -172,51 +177,67 @@ impl SettingFieldRenderer {
) -> AnyElement
+ 'static,
) -> &mut Self {
let key = TypeId::of::<T>();
let renderer = Box::new(
move |any_setting_field: &dyn AnySettingField,
self.add_renderer(
move |settings_window: &SettingsWindow,
item: &SettingItem,
field: SettingField<T>,
settings_file: SettingsUiFile,
metadata: Option<&SettingsFieldMetadata>,
window: &mut Window,
cx: &mut App| {
let field = any_setting_field
cx: &mut Context<SettingsWindow>| {
render_settings_item(
settings_window,
item,
settings_file.clone(),
render_control(field, settings_file, metadata, window, cx),
window,
cx,
)
},
)
}
fn add_renderer<T: 'static>(
&mut self,
renderer: impl Fn(
&SettingsWindow,
&SettingItem,
SettingField<T>,
SettingsUiFile,
Option<&SettingsFieldMetadata>,
&mut Window,
&mut Context<SettingsWindow>,
) -> Stateful<Div>
+ 'static,
) -> &mut Self {
let key = TypeId::of::<T>();
let renderer = Box::new(
move |settings_window: &SettingsWindow,
item: &SettingItem,
settings_file: SettingsUiFile,
metadata: Option<&SettingsFieldMetadata>,
window: &mut Window,
cx: &mut Context<SettingsWindow>| {
let field = *item
.field
.as_ref()
.as_any()
.downcast_ref::<SettingField<T>>()
.unwrap();
renderer(field, settings_file, metadata, window, cx)
renderer(
settings_window,
item,
field,
settings_file,
metadata,
window,
cx,
)
},
);
self.renderers.borrow_mut().insert(key, renderer);
self
}
fn render(
&self,
any_setting_field: &dyn AnySettingField,
settings_file: SettingsUiFile,
metadata: Option<&SettingsFieldMetadata>,
window: &mut Window,
cx: &mut App,
) -> AnyElement {
let key = any_setting_field.type_id();
if let Some(renderer) = self.renderers.borrow().get(&key) {
renderer(any_setting_field, settings_file, metadata, window, cx)
} else {
Button::new("no-renderer", "NO RENDERER")
.style(ButtonStyle::Outlined)
.size(ButtonSize::Medium)
.icon(Some(IconName::XCircle))
.icon_position(IconPosition::Start)
.icon_color(Color::Error)
.tab_index(0_isize)
.tooltip(Tooltip::text(any_setting_field.type_name()))
.into_any_element()
// panic!(
// "No renderer found for type: {}",
// any_setting_field.type_name()
// )
}
}
}
struct NonFocusableHandle {
@@ -278,7 +299,7 @@ pub fn init(cx: &mut App) {
fn init_renderers(cx: &mut App) {
cx.default_global::<SettingFieldRenderer>()
.add_renderer::<UnimplementedSettingField>(|_, _, _, _, _| {
.add_basic_renderer::<UnimplementedSettingField>(|_, _, _, _, _| {
Button::new("open-in-settings-file", "Edit in settings.json")
.style(ButtonStyle::Outlined)
.size(ButtonSize::Medium)
@@ -288,197 +309,70 @@ fn init_renderers(cx: &mut App) {
})
.into_any_element()
})
.add_renderer::<bool>(|settings_field, file, _, _, cx| {
render_toggle_button(*settings_field, file, cx).into_any_element()
})
.add_renderer::<String>(|settings_field, file, metadata, _, cx| {
render_text_field(settings_field.clone(), file, metadata, cx)
})
.add_renderer::<SaturatingBool>(|settings_field, file, _, _, cx| {
render_toggle_button(*settings_field, file, cx)
})
.add_renderer::<CursorShape>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<RestoreOnStartupBehavior>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<BottomDockLayout>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<OnLastWindowClosed>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<CloseWindowWhenNoItems>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::FontFamilyName>(|settings_field, file, _, window, cx| {
// todo(settings_ui): We need to pass in a validator for this to ensure that users that type in invalid font names
render_font_picker(settings_field.clone(), file, window, cx)
})
.add_basic_renderer::<bool>(render_toggle_button)
.add_basic_renderer::<String>(render_text_field)
.add_basic_renderer::<SaturatingBool>(render_toggle_button)
.add_basic_renderer::<CursorShape>(render_dropdown)
.add_basic_renderer::<RestoreOnStartupBehavior>(render_dropdown)
.add_basic_renderer::<BottomDockLayout>(render_dropdown)
.add_basic_renderer::<OnLastWindowClosed>(render_dropdown)
.add_basic_renderer::<CloseWindowWhenNoItems>(render_dropdown)
.add_basic_renderer::<settings::FontFamilyName>(render_font_picker)
// todo(settings_ui): This needs custom ui
// .add_renderer::<settings::BufferLineHeight>(|settings_field, file, _, window, cx| {
// // todo(settings_ui): Do we want to expose the custom variant of buffer line height?
// // right now there's a manual impl of strum::VariantArray
// render_dropdown(*settings_field, file, window, cx)
// })
.add_renderer::<settings::BaseKeymapContent>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::MultiCursorModifier>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::HideMouseMode>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::CurrentLineHighlight>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::ShowWhitespaceSetting>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::SoftWrap>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::ScrollBeyondLastLine>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::SnippetSortOrder>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::ClosePosition>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::DockSide>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::TerminalDockPosition>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::DockPosition>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::GitGutterSetting>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::GitHunkStyleSetting>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::DiagnosticSeverityContent>(
|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
},
)
.add_renderer::<settings::SeedQuerySetting>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::DoubleClickInMultibuffer>(
|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
},
)
.add_renderer::<settings::GoToDefinitionFallback>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::ActivateOnClose>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::ShowDiagnostics>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::ShowCloseButton>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::ProjectPanelEntrySpacing>(
|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
},
)
.add_renderer::<settings::RewrapBehavior>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::FormatOnSave>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::IndentGuideColoring>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::IndentGuideBackgroundColoring>(
|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
},
)
.add_renderer::<settings::FileFinderWidthContent>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::ShowDiagnostics>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::WordsCompletionMode>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::LspInsertMode>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::AlternateScroll>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::TerminalBlink>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::CursorShapeContent>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<f32>(|settings_field, file, _, window, cx| {
render_number_field(*settings_field, file, window, cx)
})
.add_renderer::<u32>(|settings_field, file, _, window, cx| {
render_number_field(*settings_field, file, window, cx)
})
.add_renderer::<u64>(|settings_field, file, _, window, cx| {
render_number_field(*settings_field, file, window, cx)
})
.add_renderer::<usize>(|settings_field, file, _, window, cx| {
render_number_field(*settings_field, file, window, cx)
})
.add_renderer::<NonZero<usize>>(|settings_field, file, _, window, cx| {
render_number_field(*settings_field, file, window, cx)
})
.add_renderer::<NonZeroU32>(|settings_field, file, _, window, cx| {
render_number_field(*settings_field, file, window, cx)
})
.add_renderer::<CodeFade>(|settings_field, file, _, window, cx| {
render_number_field(*settings_field, file, window, cx)
})
.add_renderer::<FontWeight>(|settings_field, file, _, window, cx| {
render_number_field(*settings_field, file, window, cx)
})
.add_renderer::<settings::MinimumContrast>(|settings_field, file, _, window, cx| {
render_number_field(*settings_field, file, window, cx)
})
.add_renderer::<settings::ShowScrollbar>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::ScrollbarDiagnostics>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::ShowMinimap>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::DisplayIn>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::MinimapThumb>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::MinimapThumbBorder>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
})
.add_renderer::<settings::SteppingGranularity>(|settings_field, file, _, window, cx| {
render_dropdown(*settings_field, file, window, cx)
});
// todo(settings_ui): Figure out how we want to handle discriminant unions
.add_basic_renderer::<settings::BaseKeymapContent>(render_dropdown)
.add_basic_renderer::<settings::MultiCursorModifier>(render_dropdown)
.add_basic_renderer::<settings::HideMouseMode>(render_dropdown)
.add_basic_renderer::<settings::CurrentLineHighlight>(render_dropdown)
.add_basic_renderer::<settings::ShowWhitespaceSetting>(render_dropdown)
.add_basic_renderer::<settings::SoftWrap>(render_dropdown)
.add_basic_renderer::<settings::ScrollBeyondLastLine>(render_dropdown)
.add_basic_renderer::<settings::SnippetSortOrder>(render_dropdown)
.add_basic_renderer::<settings::ClosePosition>(render_dropdown)
.add_basic_renderer::<settings::DockSide>(render_dropdown)
.add_basic_renderer::<settings::TerminalDockPosition>(render_dropdown)
.add_basic_renderer::<settings::DockPosition>(render_dropdown)
.add_basic_renderer::<settings::GitGutterSetting>(render_dropdown)
.add_basic_renderer::<settings::GitHunkStyleSetting>(render_dropdown)
.add_basic_renderer::<settings::DiagnosticSeverityContent>(render_dropdown)
.add_basic_renderer::<settings::SeedQuerySetting>(render_dropdown)
.add_basic_renderer::<settings::DoubleClickInMultibuffer>(render_dropdown)
.add_basic_renderer::<settings::GoToDefinitionFallback>(render_dropdown)
.add_basic_renderer::<settings::ActivateOnClose>(render_dropdown)
.add_basic_renderer::<settings::ShowDiagnostics>(render_dropdown)
.add_basic_renderer::<settings::ShowCloseButton>(render_dropdown)
.add_basic_renderer::<settings::ProjectPanelEntrySpacing>(render_dropdown)
.add_basic_renderer::<settings::RewrapBehavior>(render_dropdown)
.add_basic_renderer::<settings::FormatOnSave>(render_dropdown)
.add_basic_renderer::<settings::IndentGuideColoring>(render_dropdown)
.add_basic_renderer::<settings::IndentGuideBackgroundColoring>(render_dropdown)
.add_basic_renderer::<settings::FileFinderWidthContent>(render_dropdown)
.add_basic_renderer::<settings::ShowDiagnostics>(render_dropdown)
.add_basic_renderer::<settings::WordsCompletionMode>(render_dropdown)
.add_basic_renderer::<settings::LspInsertMode>(render_dropdown)
.add_basic_renderer::<settings::AlternateScroll>(render_dropdown)
.add_basic_renderer::<settings::TerminalBlink>(render_dropdown)
.add_basic_renderer::<settings::CursorShapeContent>(render_dropdown)
.add_basic_renderer::<f32>(render_number_field)
.add_basic_renderer::<u32>(render_number_field)
.add_basic_renderer::<u64>(render_number_field)
.add_basic_renderer::<usize>(render_number_field)
.add_basic_renderer::<NonZero<usize>>(render_number_field)
.add_basic_renderer::<NonZeroU32>(render_number_field)
.add_basic_renderer::<CodeFade>(render_number_field)
.add_basic_renderer::<FontWeight>(render_number_field)
.add_basic_renderer::<settings::MinimumContrast>(render_number_field)
.add_basic_renderer::<settings::ShowScrollbar>(render_dropdown)
.add_basic_renderer::<settings::ScrollbarDiagnostics>(render_dropdown)
.add_basic_renderer::<settings::ShowMinimap>(render_dropdown)
.add_basic_renderer::<settings::DisplayIn>(render_dropdown)
.add_basic_renderer::<settings::MinimapThumb>(render_dropdown)
.add_basic_renderer::<settings::MinimapThumbBorder>(render_dropdown)
.add_basic_renderer::<settings::SteppingGranularity>(render_dropdown);
// .add_renderer::<ThemeSelection>(|settings_field, file, _, window, cx| {
// render_dropdown(*settings_field, file, window, cx)
// });
@@ -636,14 +530,48 @@ impl SettingsPageItem {
.into_any_element(),
SettingsPageItem::SettingItem(setting_item) => {
let renderer = cx.default_global::<SettingFieldRenderer>().clone();
let (found_in_file, found) = setting_item.field.file_set_in(file.clone(), cx);
let file_set_in = SettingsUiFile::from_settings(found_in_file);
let (_, found) = setting_item.field.file_set_in(file.clone(), cx);
h_flex()
.id(setting_item.title)
.min_w_0()
.gap_2()
.justify_between()
let renderers = renderer.renderers.borrow();
let field_renderer =
renderers.get(&AnySettingField::type_id(setting_item.field.as_ref()));
let field_renderer_or_warning =
field_renderer.ok_or("NO RENDERER").and_then(|renderer| {
if cfg!(debug_assertions) && !found {
Err("NO DEFAULT")
} else {
Ok(renderer)
}
});
let field = match field_renderer_or_warning {
Ok(field_renderer) => field_renderer(
settings_window,
setting_item,
file,
setting_item.metadata.as_deref(),
window,
cx,
),
Err(warning) => render_settings_item(
settings_window,
setting_item,
file,
Button::new("error-warning", warning)
.style(ButtonStyle::Outlined)
.size(ButtonSize::Medium)
.icon(Some(IconName::Debug))
.icon_position(IconPosition::Start)
.icon_color(Color::Error)
.tab_index(0_isize)
.tooltip(Tooltip::text(setting_item.field.type_name()))
.into_any_element(),
window,
cx,
),
};
field
.pt_4()
.map(|this| {
if is_last {
@@ -654,58 +582,6 @@ impl SettingsPageItem {
.border_color(cx.theme().colors().border_variant)
}
})
.child(
v_flex()
.w_full()
.max_w_1_2()
.child(
h_flex()
.w_full()
.gap_1()
.child(Label::new(SharedString::new_static(setting_item.title)))
.when_some(
file_set_in.filter(|file_set_in| file_set_in != &file),
|this, file_set_in| {
this.child(
Label::new(format!(
"— set in {}",
settings_window
.display_name(&file_set_in)
.expect("File name should exist")
))
.color(Color::Muted)
.size(LabelSize::Small),
)
},
),
)
.child(
Label::new(SharedString::new_static(setting_item.description))
.size(LabelSize::Small)
.color(Color::Muted),
),
)
.child(if cfg!(debug_assertions) && !found {
Button::new("no-default-field", "NO DEFAULT")
.size(ButtonSize::Medium)
.icon(IconName::XCircle)
.icon_position(IconPosition::Start)
.icon_color(Color::Error)
.icon_size(IconSize::Small)
.style(ButtonStyle::Outlined)
.tooltip(Tooltip::text(
"This warning is only displayed in dev builds.",
))
.into_any_element()
} else {
renderer.render(
setting_item.field.as_ref(),
file,
setting_item.metadata.as_deref(),
window,
cx,
)
})
.into_any_element()
}
SettingsPageItem::SubPageLink(sub_page_link) => h_flex()
@@ -747,6 +623,55 @@ impl SettingsPageItem {
}
}
fn render_settings_item(
settings_window: &SettingsWindow,
setting_item: &SettingItem,
file: SettingsUiFile,
control: AnyElement,
_window: &mut Window,
cx: &mut Context<'_, SettingsWindow>,
) -> Stateful<Div> {
let (found_in_file, _) = setting_item.field.file_set_in(file.clone(), cx);
let file_set_in = SettingsUiFile::from_settings(found_in_file);
h_flex()
.id(setting_item.title)
.min_w_0()
.gap_2()
.justify_between()
.child(
v_flex()
.w_1_2()
.child(
h_flex()
.w_full()
.gap_1()
.child(Label::new(SharedString::new_static(setting_item.title)))
.when_some(
file_set_in.filter(|file_set_in| file_set_in != &file),
|this, file_set_in| {
this.child(
Label::new(format!(
"— set in {}",
settings_window
.display_name(&file_set_in)
.expect("File name should exist")
))
.color(Color::Muted)
.size(LabelSize::Small),
)
},
),
)
.child(
Label::new(SharedString::new_static(setting_item.description))
.size(LabelSize::Small)
.color(Color::Muted),
),
)
.child(control)
}
struct SettingItem {
title: &'static str,
description: &'static str,
@@ -2157,6 +2082,7 @@ fn render_text_field<T: From<String> + Into<String> + AsRef<str> + Clone>(
field: SettingField<T>,
file: SettingsUiFile,
metadata: Option<&SettingsFieldMetadata>,
_window: &mut Window,
cx: &mut App,
) -> AnyElement {
let (_, initial_text) =
@@ -2186,6 +2112,8 @@ fn render_text_field<T: From<String> + Into<String> + AsRef<str> + Clone>(
fn render_toggle_button<B: Into<bool> + From<bool> + Copy>(
field: SettingField<B>,
file: SettingsUiFile,
_metadata: Option<&SettingsFieldMetadata>,
_window: &mut Window,
cx: &mut App,
) -> AnyElement {
let (_, value) = SettingsStore::global(cx).get_value_from_file(file.to_settings(), field.pick);
@@ -2215,6 +2143,7 @@ fn render_toggle_button<B: Into<bool> + From<bool> + Copy>(
fn render_font_picker(
field: SettingField<settings::FontFamilyName>,
file: SettingsUiFile,
_metadata: Option<&SettingsFieldMetadata>,
window: &mut Window,
cx: &mut App,
) -> AnyElement {
@@ -2262,6 +2191,7 @@ fn render_font_picker(
fn render_number_field<T: NumberFieldType + Send + Sync>(
field: SettingField<T>,
file: SettingsUiFile,
_metadata: Option<&SettingsFieldMetadata>,
window: &mut Window,
cx: &mut App,
) -> AnyElement {
@@ -2283,6 +2213,7 @@ fn render_number_field<T: NumberFieldType + Send + Sync>(
fn render_dropdown<T>(
field: SettingField<T>,
file: SettingsUiFile,
_metadata: Option<&SettingsFieldMetadata>,
window: &mut Window,
cx: &mut App,
) -> AnyElement