settings ui: Add missing setting elements (#39644)
Added the following settings to the UI Editor Page - Scrollbar Section (9 settings) - Show - Cursors - Git Diff - Search Results - Selected Text - Selected Symbol - Diagnostics - Horizontal Scrollbar - Vertical Scrollbar Editor Page - Minimap Section (6 settings) - Show - Display In - Thumb - Thumb Border - Current Line Highlight - Max Width Columns Editor Page - Editor Behavior Section (3 settings) - Expand Excerpt Lines - Excerpt Context Lines - Minimum Contrast For Highlights Debugger Page (7 settings) - Stepping Granularity - Save Breakpoints - Timeout - Dock - Log DAP Communications - Format DAP Log Messages - Button Panels Page - Git Panel Section (3 settings) - Button - Dock - Default Width Collaboration Page - Experimental Section (4 settings) - Auto Microphone Volume - Auto Speaker Volume - Denoise - Legacy Audio Compatible Release Notes: - N/A
This commit is contained in:
@@ -1233,8 +1233,8 @@
|
||||
"git_gutter": "tracked_files",
|
||||
/// Sets the debounce threshold (in milliseconds) after which changes are reflected in the git gutter.
|
||||
///
|
||||
/// Default: null
|
||||
"gutter_debounce": null,
|
||||
/// Default: 0
|
||||
"gutter_debounce": 0,
|
||||
// Control whether the git blame information is shown inline,
|
||||
// in the currently focused line.
|
||||
"inline_blame": {
|
||||
|
||||
@@ -267,7 +267,7 @@ impl Settings for EditorSettings {
|
||||
delay: drag_and_drop_selection.delay.unwrap(),
|
||||
},
|
||||
lsp_document_colors: editor.lsp_document_colors.unwrap(),
|
||||
minimum_contrast_for_highlights: editor.minimum_contrast_for_highlights.unwrap(),
|
||||
minimum_contrast_for_highlights: editor.minimum_contrast_for_highlights.unwrap().0,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3252,9 +3252,9 @@ impl Project {
|
||||
self.buffers_needing_diff.insert(buffer.downgrade());
|
||||
let first_insertion = self.buffers_needing_diff.len() == 1;
|
||||
let settings = ProjectSettings::get_global(cx);
|
||||
let delay = if let Some(delay) = settings.git.gutter_debounce {
|
||||
delay
|
||||
} else {
|
||||
let delay = settings.git.gutter_debounce;
|
||||
|
||||
if delay == 0 {
|
||||
if first_insertion {
|
||||
let this = cx.weak_entity();
|
||||
cx.defer(move |cx| {
|
||||
@@ -3266,7 +3266,7 @@ impl Project {
|
||||
});
|
||||
}
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
const MIN_DELAY: u64 = 50;
|
||||
let delay = delay.max(MIN_DELAY);
|
||||
|
||||
@@ -300,8 +300,8 @@ pub struct GitSettings {
|
||||
pub git_gutter: settings::GitGutterSetting,
|
||||
/// Sets the debounce threshold (in milliseconds) after which changes are reflected in the git gutter.
|
||||
///
|
||||
/// Default: null
|
||||
pub gutter_debounce: Option<u64>,
|
||||
/// Default: 0
|
||||
pub gutter_debounce: u64,
|
||||
/// Whether or not to show git blame data inline in
|
||||
/// the currently focused line.
|
||||
///
|
||||
@@ -446,7 +446,7 @@ impl Settings for ProjectSettings {
|
||||
let git = content.git.as_ref().unwrap();
|
||||
let git_settings = GitSettings {
|
||||
git_gutter: git.git_gutter.unwrap(),
|
||||
gutter_debounce: git.gutter_debounce,
|
||||
gutter_debounce: git.gutter_debounce.unwrap_or_default(),
|
||||
inline_blame: {
|
||||
let inline = git.inline_blame.unwrap();
|
||||
InlineBlameSettings {
|
||||
|
||||
@@ -383,7 +383,18 @@ pub struct DebuggerSettingsContent {
|
||||
|
||||
/// The granularity of one 'step' in the stepping requests `next`, `stepIn`, `stepOut`, and `stepBack`.
|
||||
#[derive(
|
||||
PartialEq, Eq, Debug, Hash, Clone, Copy, Deserialize, Serialize, JsonSchema, MergeFrom,
|
||||
PartialEq,
|
||||
Eq,
|
||||
Debug,
|
||||
Hash,
|
||||
Clone,
|
||||
Copy,
|
||||
Deserialize,
|
||||
Serialize,
|
||||
JsonSchema,
|
||||
MergeFrom,
|
||||
strum::VariantArray,
|
||||
strum::VariantNames,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum SteppingGranularity {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::fmt::Display;
|
||||
use std::num;
|
||||
|
||||
use collections::HashMap;
|
||||
@@ -153,7 +154,8 @@ pub struct EditorSettingsContent {
|
||||
///
|
||||
/// Values range from 0 to 106. Set to 0 to disable adjustments.
|
||||
/// Default: 45
|
||||
pub minimum_contrast_for_highlights: Option<f32>,
|
||||
#[schemars(range(min = 0, max = 106))]
|
||||
pub minimum_contrast_for_highlights: Option<MinimumContrast>,
|
||||
|
||||
/// Whether to follow-up empty go to definition responses from the language server or not.
|
||||
/// `FindAllReferences` allows to look up references of the same symbol instead.
|
||||
@@ -425,7 +427,18 @@ pub enum DoubleClickInMultibuffer {
|
||||
///
|
||||
/// Default: always
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq,
|
||||
Copy,
|
||||
Clone,
|
||||
Debug,
|
||||
Default,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
JsonSchema,
|
||||
MergeFrom,
|
||||
PartialEq,
|
||||
Eq,
|
||||
strum::VariantArray,
|
||||
strum::VariantNames,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum MinimapThumb {
|
||||
@@ -440,7 +453,18 @@ pub enum MinimapThumb {
|
||||
///
|
||||
/// Default: left_open
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq,
|
||||
Copy,
|
||||
Clone,
|
||||
Debug,
|
||||
Default,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
JsonSchema,
|
||||
MergeFrom,
|
||||
PartialEq,
|
||||
Eq,
|
||||
strum::VariantArray,
|
||||
strum::VariantNames,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum MinimapThumbBorder {
|
||||
@@ -460,7 +484,19 @@ pub enum MinimapThumbBorder {
|
||||
/// Which diagnostic indicators to show in the scrollbar.
|
||||
///
|
||||
/// Default: all
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
#[derive(
|
||||
Copy,
|
||||
Clone,
|
||||
Debug,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
JsonSchema,
|
||||
MergeFrom,
|
||||
PartialEq,
|
||||
Eq,
|
||||
strum::VariantArray,
|
||||
strum::VariantNames,
|
||||
)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum ScrollbarDiagnostics {
|
||||
/// Show all diagnostic levels: hint, information, warnings, error.
|
||||
@@ -682,7 +718,18 @@ pub struct DragAndDropSelectionContent {
|
||||
///
|
||||
/// Default: never
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq,
|
||||
Copy,
|
||||
Clone,
|
||||
Debug,
|
||||
Default,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
JsonSchema,
|
||||
MergeFrom,
|
||||
PartialEq,
|
||||
Eq,
|
||||
strum::VariantArray,
|
||||
strum::VariantNames,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ShowMinimap {
|
||||
@@ -699,7 +746,18 @@ pub enum ShowMinimap {
|
||||
///
|
||||
/// Default: all_editors
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq,
|
||||
Copy,
|
||||
Clone,
|
||||
Debug,
|
||||
Default,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
JsonSchema,
|
||||
MergeFrom,
|
||||
PartialEq,
|
||||
Eq,
|
||||
strum::VariantArray,
|
||||
strum::VariantNames,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum DisplayIn {
|
||||
@@ -709,3 +767,28 @@ pub enum DisplayIn {
|
||||
#[default]
|
||||
ActiveEditor,
|
||||
}
|
||||
|
||||
/// Minimum APCA perceptual contrast for text over highlight backgrounds.
|
||||
///
|
||||
/// Valid range: 0.0 to 106.0
|
||||
/// Default: 45.0
|
||||
#[derive(
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
JsonSchema,
|
||||
MergeFrom,
|
||||
PartialEq,
|
||||
PartialOrd,
|
||||
derive_more::FromStr,
|
||||
)]
|
||||
#[serde(transparent)]
|
||||
pub struct MinimumContrast(pub f32);
|
||||
|
||||
impl Display for MinimumContrast {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{:.1}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ pub struct GitSettings {
|
||||
pub git_gutter: Option<GitGutterSetting>,
|
||||
/// Sets the debounce threshold (in milliseconds) after which changes are reflected in the git gutter.
|
||||
///
|
||||
/// Default: null
|
||||
/// Default: 0
|
||||
pub gutter_debounce: Option<u64>,
|
||||
/// Whether or not to show git blame data inline in
|
||||
/// the currently focused line.
|
||||
|
||||
@@ -199,7 +199,19 @@ impl TerminalLineHeight {
|
||||
/// When to show the scrollbar.
|
||||
///
|
||||
/// Default: auto
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
#[derive(
|
||||
Copy,
|
||||
Clone,
|
||||
Debug,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
JsonSchema,
|
||||
MergeFrom,
|
||||
PartialEq,
|
||||
Eq,
|
||||
strum::VariantArray,
|
||||
strum::VariantNames,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ShowScrollbar {
|
||||
/// Show the scrollbar if there's important information or
|
||||
|
||||
@@ -538,6 +538,7 @@ impl SettingsStore {
|
||||
&self,
|
||||
target_file: SettingsFile,
|
||||
pick: fn(&SettingsContent) -> &Option<T>,
|
||||
type_name: &'static str,
|
||||
) -> (SettingsFile, &T) {
|
||||
// TODO: 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
|
||||
@@ -568,7 +569,7 @@ impl SettingsStore {
|
||||
}
|
||||
}
|
||||
|
||||
unreachable!("All values should have defaults");
|
||||
unreachable!("{type_name}: doesn't have a default value");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1714,16 +1715,24 @@ mod tests {
|
||||
let default_value = get(&store.default_settings).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
store.get_value_from_file(SettingsFile::Local(local.clone()), get),
|
||||
store.get_value_from_file(
|
||||
SettingsFile::Local(local.clone()),
|
||||
get,
|
||||
"preferred line length"
|
||||
),
|
||||
(SettingsFile::User, &0)
|
||||
);
|
||||
assert_eq!(
|
||||
store.get_value_from_file(SettingsFile::User, get),
|
||||
store.get_value_from_file(SettingsFile::User, get, "preferred line length"),
|
||||
(SettingsFile::User, &0)
|
||||
);
|
||||
store.set_user_settings(r#"{}"#, cx).unwrap();
|
||||
assert_eq!(
|
||||
store.get_value_from_file(SettingsFile::Local(local.clone()), get),
|
||||
store.get_value_from_file(
|
||||
SettingsFile::Local(local.clone()),
|
||||
get,
|
||||
"preferred line length"
|
||||
),
|
||||
(SettingsFile::Default, &default_value)
|
||||
);
|
||||
store
|
||||
@@ -1736,11 +1745,15 @@ mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
store.get_value_from_file(SettingsFile::Local(local.clone()), get),
|
||||
store.get_value_from_file(
|
||||
SettingsFile::Local(local.clone()),
|
||||
get,
|
||||
"preferred line length"
|
||||
),
|
||||
(SettingsFile::Local(local), &80)
|
||||
);
|
||||
assert_eq!(
|
||||
store.get_value_from_file(SettingsFile::User, get),
|
||||
store.get_value_from_file(SettingsFile::User, get, "preferred line length"),
|
||||
(SettingsFile::Default, &default_value)
|
||||
);
|
||||
}
|
||||
@@ -1817,11 +1830,19 @@ mod tests {
|
||||
|
||||
// each local child should only inherit from it's parent
|
||||
assert_eq!(
|
||||
store.get_value_from_file(SettingsFile::Local(local_2_child), get),
|
||||
store.get_value_from_file(
|
||||
SettingsFile::Local(local_2_child),
|
||||
get,
|
||||
"preferred_line_length"
|
||||
),
|
||||
(SettingsFile::Local(local_2), &2)
|
||||
);
|
||||
assert_eq!(
|
||||
store.get_value_from_file(SettingsFile::Local(local_1_child.clone()), get),
|
||||
store.get_value_from_file(
|
||||
SettingsFile::Local(local_1_child.clone()),
|
||||
get,
|
||||
"preferred_line_length"
|
||||
),
|
||||
(SettingsFile::Local(local_1.clone()), &1)
|
||||
);
|
||||
|
||||
@@ -1847,7 +1868,11 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
store.get_value_from_file(SettingsFile::Local(local_1_adjacent_child.clone()), get),
|
||||
store.get_value_from_file(
|
||||
SettingsFile::Local(local_1_adjacent_child.clone()),
|
||||
get,
|
||||
"preferred_line_length"
|
||||
),
|
||||
(SettingsFile::Local(local_1.clone()), &1)
|
||||
);
|
||||
store
|
||||
@@ -1869,7 +1894,11 @@ mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
store.get_value_from_file(SettingsFile::Local(local_1_child), get),
|
||||
store.get_value_from_file(
|
||||
SettingsFile::Local(local_1_child),
|
||||
get,
|
||||
"preferred_line_length"
|
||||
),
|
||||
(SettingsFile::Local(local_1), &1)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -712,6 +712,41 @@ pub(crate) fn user_settings_data() -> Vec<SettingsPage> {
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Expand Excerpt Lines",
|
||||
description: "How many lines to expand the multibuffer excerpts by default",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| &settings_content.editor.expand_excerpt_lines,
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content.editor.expand_excerpt_lines
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Excerpt Context Lines",
|
||||
description: "How many lines of context to provide in multibuffer excerpts by default",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| &settings_content.editor.excerpt_context_lines,
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content.editor.excerpt_context_lines
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Minimum Contrast For Highlights",
|
||||
description: "The minimum APCA perceptual contrast to maintain when rendering text over highlight backgrounds",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
&settings_content.editor.minimum_contrast_for_highlights
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content.editor.minimum_contrast_for_highlights
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SectionHeader("Scrolling"),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Scroll Beyond Last Line",
|
||||
@@ -1181,6 +1216,354 @@ pub(crate) fn user_settings_data() -> Vec<SettingsPage> {
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Min Line Number Digits",
|
||||
description: "Minimum number of characters to reserve space for in the gutter.",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(gutter) = &settings_content.editor.gutter {
|
||||
&gutter.min_line_number_digits
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.editor
|
||||
.gutter
|
||||
.get_or_insert_default()
|
||||
.min_line_number_digits
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SectionHeader("Scrollbar"),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Show",
|
||||
description: "When to show the scrollbar in the editor",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(scrollbar) = &settings_content.editor.scrollbar {
|
||||
&scrollbar.show
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.editor
|
||||
.scrollbar
|
||||
.get_or_insert_default()
|
||||
.show
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Cursors",
|
||||
description: "Whether to show cursor positions in the scrollbar",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(scrollbar) = &settings_content.editor.scrollbar {
|
||||
&scrollbar.cursors
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.editor
|
||||
.scrollbar
|
||||
.get_or_insert_default()
|
||||
.cursors
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Git Diff",
|
||||
description: "Whether to show git diff indicators in the scrollbar",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(scrollbar) = &settings_content.editor.scrollbar {
|
||||
&scrollbar.git_diff
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.editor
|
||||
.scrollbar
|
||||
.get_or_insert_default()
|
||||
.git_diff
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Search Results",
|
||||
description: "Whether to show buffer search result indicators in the scrollbar",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(scrollbar) = &settings_content.editor.scrollbar {
|
||||
&scrollbar.search_results
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.editor
|
||||
.scrollbar
|
||||
.get_or_insert_default()
|
||||
.search_results
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Selected Text",
|
||||
description: "Whether to show selected text occurrences in the scrollbar",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(scrollbar) = &settings_content.editor.scrollbar {
|
||||
&scrollbar.selected_text
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.editor
|
||||
.scrollbar
|
||||
.get_or_insert_default()
|
||||
.selected_text
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Selected Symbol",
|
||||
description: "Whether to show selected symbol occurrences in the scrollbar",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(scrollbar) = &settings_content.editor.scrollbar {
|
||||
&scrollbar.selected_symbol
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.editor
|
||||
.scrollbar
|
||||
.get_or_insert_default()
|
||||
.selected_symbol
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Diagnostics",
|
||||
description: "Which diagnostic indicators to show in the scrollbar",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(scrollbar) = &settings_content.editor.scrollbar {
|
||||
&scrollbar.diagnostics
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.editor
|
||||
.scrollbar
|
||||
.get_or_insert_default()
|
||||
.diagnostics
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Horizontal Scrollbar",
|
||||
description: "When false, forcefully disables the horizontal scrollbar",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(scrollbar) = &settings_content.editor.scrollbar {
|
||||
if let Some(axes) = &scrollbar.axes {
|
||||
&axes.horizontal
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.editor
|
||||
.scrollbar
|
||||
.get_or_insert_default()
|
||||
.axes
|
||||
.get_or_insert_default()
|
||||
.horizontal
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Vertical Scrollbar",
|
||||
description: "When false, forcefully disables the vertical scrollbar",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(scrollbar) = &settings_content.editor.scrollbar {
|
||||
if let Some(axes) = &scrollbar.axes {
|
||||
&axes.vertical
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.editor
|
||||
.scrollbar
|
||||
.get_or_insert_default()
|
||||
.axes
|
||||
.get_or_insert_default()
|
||||
.vertical
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SectionHeader("Minimap"),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Show",
|
||||
description: "When to show the minimap in the editor",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(minimap) = &settings_content.editor.minimap {
|
||||
&minimap.show
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content.editor.minimap.get_or_insert_default().show
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Display In",
|
||||
description: "Where to show the minimap in the editor",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(minimap) = &settings_content.editor.minimap {
|
||||
&minimap.display_in
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.editor
|
||||
.minimap
|
||||
.get_or_insert_default()
|
||||
.display_in
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Thumb",
|
||||
description: "When to show the minimap thumb",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(minimap) = &settings_content.editor.minimap {
|
||||
&minimap.thumb
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.editor
|
||||
.minimap
|
||||
.get_or_insert_default()
|
||||
.thumb
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Thumb Border",
|
||||
description: "Border style for the minimap's scrollbar thumb",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(minimap) = &settings_content.editor.minimap {
|
||||
&minimap.thumb_border
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.editor
|
||||
.minimap
|
||||
.get_or_insert_default()
|
||||
.thumb_border
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Current Line Highlight",
|
||||
description: "How to highlight the current line in the minimap",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(minimap) = &settings_content.editor.minimap
|
||||
&& minimap.current_line_highlight.is_some()
|
||||
{
|
||||
&minimap.current_line_highlight
|
||||
} else {
|
||||
&settings_content.editor.current_line_highlight
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.editor
|
||||
.minimap
|
||||
.get_or_insert_default()
|
||||
.current_line_highlight
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Max Width Columns",
|
||||
description: "Maximum number of columns to display in the minimap",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(minimap) = &settings_content.editor.minimap {
|
||||
&minimap.max_width_columns
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.editor
|
||||
.minimap
|
||||
.get_or_insert_default()
|
||||
.max_width_columns
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SectionHeader("Tabs"),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Show Tab Bar",
|
||||
@@ -1253,6 +1636,8 @@ pub(crate) fn user_settings_data() -> Vec<SettingsPage> {
|
||||
// SettingsPageItem::SettingItem(SettingItem {
|
||||
// title: "Maximum Tabs",
|
||||
// description: "Maximum open tabs in a pane. Will not close an unsaved tab",
|
||||
// // todo(settings_ui): The default for this value is null and it's use in code
|
||||
// // is complex, so I'm going to come back to this later
|
||||
// field: Box::new(SettingField {
|
||||
// pick: |settings_content| &settings_content.workspace.max_tabs,
|
||||
// pick_mut: |settings_content| &mut settings_content.workspace.max_tabs,
|
||||
@@ -2593,6 +2978,61 @@ pub(crate) fn user_settings_data() -> Vec<SettingsPage> {
|
||||
// }),
|
||||
// metadata: None,
|
||||
// }),
|
||||
SettingsPageItem::SectionHeader("Git Panel"),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Button",
|
||||
description: "Whether to show the git panel button in the status bar",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(git_panel) = &settings_content.git_panel {
|
||||
&git_panel.button
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content.git_panel.get_or_insert_default().button
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Dock",
|
||||
description: "Where to dock the git panel",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(git_panel) = &settings_content.git_panel {
|
||||
&git_panel.dock
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content.git_panel.get_or_insert_default().dock
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Default Width",
|
||||
description: "Default width of the git panel in pixels",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(git_panel) = &settings_content.git_panel {
|
||||
&git_panel.default_width
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.git_panel
|
||||
.get_or_insert_default()
|
||||
.default_width
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SectionHeader("Notification Panel"),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Notification Panel Button",
|
||||
@@ -2742,23 +3182,23 @@ pub(crate) fn user_settings_data() -> Vec<SettingsPage> {
|
||||
metadata: None,
|
||||
}),
|
||||
// todo(settings_ui): Figure out the right default for this value in default.json
|
||||
// SettingsPageItem::SettingItem(SettingItem {
|
||||
// title: "Gutter Debounce",
|
||||
// description: "Debounce threshold in milliseconds after which changes are reflected in the git gutter",
|
||||
// field: Box::new(SettingField {
|
||||
// pick: |settings_content| {
|
||||
// if let Some(git) = &settings_content.git {
|
||||
// &git.gutter_debounce
|
||||
// } else {
|
||||
// &None
|
||||
// }
|
||||
// },
|
||||
// pick_mut: |settings_content| {
|
||||
// &mut settings_content.git.get_or_insert_default().gutter_debounce
|
||||
// },
|
||||
// }),
|
||||
// metadata: None,
|
||||
// }),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Gutter Debounce",
|
||||
description: "Debounce threshold in milliseconds after which changes are reflected in the git gutter",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(git) = &settings_content.git {
|
||||
&git.gutter_debounce
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content.git.get_or_insert_default().gutter_debounce
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Inline Git Blame",
|
||||
description: "Whether or not to show git blame data inline in the currently focused line",
|
||||
@@ -3195,6 +3635,143 @@ pub(crate) fn user_settings_data() -> Vec<SettingsPage> {
|
||||
}),
|
||||
],
|
||||
},
|
||||
SettingsPage {
|
||||
title: "Debugger",
|
||||
items: vec![
|
||||
SettingsPageItem::SectionHeader("General"),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Stepping Granularity",
|
||||
description: "Determines the stepping granularity for debug operations",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(debugger) = &settings_content.debugger {
|
||||
&debugger.stepping_granularity
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.debugger
|
||||
.get_or_insert_default()
|
||||
.stepping_granularity
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Save Breakpoints",
|
||||
description: "Whether breakpoints should be reused across Zed sessions",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(debugger) = &settings_content.debugger {
|
||||
&debugger.save_breakpoints
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.debugger
|
||||
.get_or_insert_default()
|
||||
.save_breakpoints
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Timeout",
|
||||
description: "Time in milliseconds until timeout error when connecting to a TCP debug adapter",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(debugger) = &settings_content.debugger {
|
||||
&debugger.timeout
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content.debugger.get_or_insert_default().timeout
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Dock",
|
||||
description: "The dock position of the debug panel",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(debugger) = &settings_content.debugger {
|
||||
&debugger.dock
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content.debugger.get_or_insert_default().dock
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Log DAP Communications",
|
||||
description: "Whether to log messages between active debug adapters and Zed",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(debugger) = &settings_content.debugger {
|
||||
&debugger.log_dap_communications
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.debugger
|
||||
.get_or_insert_default()
|
||||
.log_dap_communications
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Format DAP Log Messages",
|
||||
description: "Whether to format DAP messages when adding them to debug adapter logger",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(debugger) = &settings_content.debugger {
|
||||
&debugger.format_dap_log_messages
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.debugger
|
||||
.get_or_insert_default()
|
||||
.format_dap_log_messages
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Button",
|
||||
description: "Whether to show the debug button in the status bar",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(debugger) = &settings_content.debugger {
|
||||
&debugger.button
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content.debugger.get_or_insert_default().button
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
],
|
||||
},
|
||||
SettingsPage {
|
||||
title: "Collaboration",
|
||||
items: vec![
|
||||
@@ -3251,6 +3828,83 @@ pub(crate) fn user_settings_data() -> Vec<SettingsPage> {
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Auto Microphone Volume",
|
||||
description: "Automatically adjust microphone volume (requires Rodio Audio)",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(audio) = &settings_content.audio {
|
||||
&audio.auto_microphone_volume
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.audio
|
||||
.get_or_insert_default()
|
||||
.auto_microphone_volume
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Auto Speaker Volume",
|
||||
description: "Automatically adjust volume of other call members (requires Rodio Audio)",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(audio) = &settings_content.audio {
|
||||
&audio.auto_speaker_volume
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.audio
|
||||
.get_or_insert_default()
|
||||
.auto_speaker_volume
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Denoise",
|
||||
description: "Remove background noises (requires Rodio Audio)",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(audio) = &settings_content.audio {
|
||||
&audio.denoise
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content.audio.get_or_insert_default().denoise
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Legacy Audio Compatible",
|
||||
description: "Use audio parameters compatible with previous versions (requires Rodio Audio)",
|
||||
field: Box::new(SettingField {
|
||||
pick: |settings_content| {
|
||||
if let Some(audio) = &settings_content.audio {
|
||||
&audio.legacy_audio_compatible
|
||||
} else {
|
||||
&None
|
||||
}
|
||||
},
|
||||
pick_mut: |settings_content| {
|
||||
&mut settings_content
|
||||
.audio
|
||||
.get_or_insert_default()
|
||||
.legacy_audio_compatible
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
}),
|
||||
],
|
||||
},
|
||||
SettingsPage {
|
||||
|
||||
@@ -22,7 +22,7 @@ use std::{
|
||||
any::{Any, TypeId, type_name},
|
||||
cell::RefCell,
|
||||
collections::HashMap,
|
||||
num::NonZeroU32,
|
||||
num::{NonZero, NonZeroU32},
|
||||
ops::Range,
|
||||
rc::Rc,
|
||||
sync::{Arc, LazyLock, RwLock, atomic::AtomicBool},
|
||||
@@ -105,9 +105,11 @@ impl<T> AnySettingField for SettingField<T> {
|
||||
return file.to_settings();
|
||||
}
|
||||
|
||||
let (file, _) = cx
|
||||
.global::<SettingsStore>()
|
||||
.get_value_from_file(file.to_settings(), self.pick);
|
||||
let (file, _) = cx.global::<SettingsStore>().get_value_from_file(
|
||||
file.to_settings(),
|
||||
self.pick,
|
||||
self.type_name(),
|
||||
);
|
||||
return file;
|
||||
}
|
||||
}
|
||||
@@ -381,6 +383,12 @@ fn init_renderers(cx: &mut App) {
|
||||
.add_renderer::<u64>(|settings_field, file, _, window, cx| {
|
||||
render_numeric_stepper(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<usize>(|settings_field, file, _, window, cx| {
|
||||
render_numeric_stepper(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<NonZero<usize>>(|settings_field, file, _, window, cx| {
|
||||
render_numeric_stepper(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<NonZeroU32>(|settings_field, file, _, window, cx| {
|
||||
render_numeric_stepper(*settings_field, file, window, cx)
|
||||
})
|
||||
@@ -389,6 +397,30 @@ fn init_renderers(cx: &mut App) {
|
||||
})
|
||||
.add_renderer::<FontWeight>(|settings_field, file, _, window, cx| {
|
||||
render_numeric_stepper(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::MinimumContrast>(|settings_field, file, _, window, cx| {
|
||||
render_numeric_stepper(*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
|
||||
@@ -1439,8 +1471,11 @@ fn render_text_field<T: From<String> + Into<String> + AsRef<str> + Clone>(
|
||||
metadata: Option<&SettingsFieldMetadata>,
|
||||
cx: &mut App,
|
||||
) -> AnyElement {
|
||||
let (_, initial_text) =
|
||||
SettingsStore::global(cx).get_value_from_file(file.to_settings(), field.pick);
|
||||
let (_, initial_text) = SettingsStore::global(cx).get_value_from_file(
|
||||
file.to_settings(),
|
||||
field.pick,
|
||||
field.type_name(),
|
||||
);
|
||||
let initial_text = Some(initial_text.clone()).filter(|s| !s.as_ref().is_empty());
|
||||
|
||||
SettingsEditor::new()
|
||||
@@ -1468,7 +1503,11 @@ fn render_toggle_button<B: Into<bool> + From<bool> + Copy>(
|
||||
file: SettingsUiFile,
|
||||
cx: &mut App,
|
||||
) -> AnyElement {
|
||||
let (_, &value) = SettingsStore::global(cx).get_value_from_file(file.to_settings(), field.pick);
|
||||
let (_, &value) = SettingsStore::global(cx).get_value_from_file(
|
||||
file.to_settings(),
|
||||
field.pick,
|
||||
field.type_name(),
|
||||
);
|
||||
|
||||
let toggle_state = if value.into() {
|
||||
ToggleState::Selected
|
||||
@@ -1499,7 +1538,7 @@ fn render_font_picker(
|
||||
cx: &mut App,
|
||||
) -> AnyElement {
|
||||
let current_value = SettingsStore::global(cx)
|
||||
.get_value_from_file(file.to_settings(), field.pick)
|
||||
.get_value_from_file(file.to_settings(), field.pick, field.type_name())
|
||||
.1
|
||||
.clone();
|
||||
|
||||
@@ -1556,7 +1595,11 @@ fn render_numeric_stepper<T: NumericStepperType + Send + Sync>(
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> AnyElement {
|
||||
let (_, &value) = SettingsStore::global(cx).get_value_from_file(file.to_settings(), field.pick);
|
||||
let (_, &value) = SettingsStore::global(cx).get_value_from_file(
|
||||
file.to_settings(),
|
||||
field.pick,
|
||||
field.type_name(),
|
||||
);
|
||||
|
||||
NumericStepper::new("numeric_stepper", value, window, cx)
|
||||
.on_change({
|
||||
@@ -1585,8 +1628,11 @@ where
|
||||
let variants = || -> &'static [T] { <T as strum::VariantArray>::VARIANTS };
|
||||
let labels = || -> &'static [&'static str] { <T as strum::VariantNames>::VARIANTS };
|
||||
|
||||
let (_, ¤t_value) =
|
||||
SettingsStore::global(cx).get_value_from_file(file.to_settings(), field.pick);
|
||||
let (_, ¤t_value) = SettingsStore::global(cx).get_value_from_file(
|
||||
file.to_settings(),
|
||||
field.pick,
|
||||
field.type_name(),
|
||||
);
|
||||
|
||||
let current_value_label =
|
||||
labels()[variants().iter().position(|v| *v == current_value).unwrap()];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::{
|
||||
fmt::Display,
|
||||
num::{NonZeroU32, NonZeroU64},
|
||||
num::{NonZero, NonZeroU32, NonZeroU64},
|
||||
rc::Rc,
|
||||
str::FromStr,
|
||||
};
|
||||
@@ -8,7 +8,7 @@ use std::{
|
||||
use editor::{Editor, EditorStyle};
|
||||
use gpui::{ClickEvent, Entity, FocusHandle, Focusable, FontWeight, Modifiers};
|
||||
|
||||
use settings::CodeFade;
|
||||
use settings::{CodeFade, MinimumContrast};
|
||||
use ui::{IconButtonShape, prelude::*};
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
@@ -88,6 +88,30 @@ impl NumericStepperType for settings::CodeFade {
|
||||
}
|
||||
}
|
||||
|
||||
impl NumericStepperType for settings::MinimumContrast {
|
||||
fn default_step() -> Self {
|
||||
MinimumContrast(1.0)
|
||||
}
|
||||
fn large_step() -> Self {
|
||||
MinimumContrast(10.0)
|
||||
}
|
||||
fn small_step() -> Self {
|
||||
MinimumContrast(0.5)
|
||||
}
|
||||
fn min_value() -> Self {
|
||||
MinimumContrast(0.0)
|
||||
}
|
||||
fn max_value() -> Self {
|
||||
MinimumContrast(106.0)
|
||||
}
|
||||
fn saturating_add(self, rhs: Self) -> Self {
|
||||
MinimumContrast((self.0 + rhs.0).min(Self::max_value().0))
|
||||
}
|
||||
fn saturating_sub(self, rhs: Self) -> Self {
|
||||
MinimumContrast((self.0 - rhs.0).max(Self::min_value().0))
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_numeric_stepper_int {
|
||||
($type:ident) => {
|
||||
impl NumericStepperType for $type {
|
||||
@@ -207,6 +231,7 @@ impl_numeric_stepper_int!(u64);
|
||||
|
||||
impl_numeric_stepper_nonzero_int!(NonZeroU32, u32);
|
||||
impl_numeric_stepper_nonzero_int!(NonZeroU64, u64);
|
||||
impl_numeric_stepper_nonzero_int!(NonZero<usize>, usize);
|
||||
|
||||
#[derive(RegisterComponent)]
|
||||
pub struct NumericStepper<T = usize> {
|
||||
|
||||
Reference in New Issue
Block a user