Detailed changes
@@ -1341,7 +1341,7 @@ async fn test_hover_diagnostic_and_info_popovers(cx: &mut gpui::TestAppContext)
range: Some(range),
}))
});
- let delay = cx.update(|_, cx| EditorSettings::get_global(cx).hover_popover_delay + 1);
+ let delay = cx.update(|_, cx| EditorSettings::get_global(cx).hover_popover_delay.0 + 1);
cx.background_executor
.advance_clock(Duration::from_millis(delay));
@@ -6772,7 +6772,7 @@ impl Editor {
if let Some(state) = &mut self.inline_blame_popover {
state.hide_task.take();
} else {
- let blame_popover_delay = EditorSettings::get_global(cx).hover_popover_delay;
+ let blame_popover_delay = EditorSettings::get_global(cx).hover_popover_delay.0;
let blame_entry = blame_entry.clone();
let show_task = cx.spawn(async move |editor, cx| {
if !ignore_timeout {
@@ -6863,7 +6863,7 @@ impl Editor {
return None;
}
- let debounce = EditorSettings::get_global(cx).lsp_highlight_debounce;
+ let debounce = EditorSettings::get_global(cx).lsp_highlight_debounce.0;
self.document_highlights_task = Some(cx.spawn(async move |this, cx| {
cx.background_executor()
.timer(Duration::from_millis(debounce))
@@ -5,7 +5,7 @@ use language::CursorShape;
use project::project_settings::DiagnosticSeverity;
use settings::Settings;
pub use settings::{
- CurrentLineHighlight, DisplayIn, DocumentColorsRenderMode, DoubleClickInMultibuffer,
+ CurrentLineHighlight, DelayMs, DisplayIn, DocumentColorsRenderMode, DoubleClickInMultibuffer,
GoToDefinitionFallback, HideMouseMode, MinimapThumb, MinimapThumbBorder, MultiCursorModifier,
ScrollBeyondLastLine, ScrollbarDiagnostics, SeedQuerySetting, ShowMinimap, SnippetSortOrder,
};
@@ -20,9 +20,9 @@ pub struct EditorSettings {
pub current_line_highlight: CurrentLineHighlight,
pub selection_highlight: bool,
pub rounded_selection: bool,
- pub lsp_highlight_debounce: u64,
+ pub lsp_highlight_debounce: DelayMs,
pub hover_popover_enabled: bool,
- pub hover_popover_delay: u64,
+ pub hover_popover_delay: DelayMs,
pub toolbar: Toolbar,
pub scrollbar: Scrollbar,
pub minimap: Minimap,
@@ -147,7 +147,7 @@ pub struct DragAndDropSelection {
/// The delay in milliseconds that must elapse before drag and drop is allowed. Otherwise, a new text selection is created.
///
/// Default: 300
- pub delay: u64,
+ pub delay: DelayMs,
}
/// Default options for buffer and project search items.
@@ -1070,7 +1070,10 @@ impl EditorElement {
ref mouse_down_time,
} => {
let drag_and_drop_delay = Duration::from_millis(
- EditorSettings::get_global(cx).drag_and_drop_selection.delay,
+ EditorSettings::get_global(cx)
+ .drag_and_drop_selection
+ .delay
+ .0,
);
if mouse_down_time.elapsed() >= drag_and_drop_delay {
let drop_cursor = Selection {
@@ -6172,7 +6175,10 @@ impl EditorElement {
} = &editor.selection_drag_state
{
let drag_and_drop_delay = Duration::from_millis(
- EditorSettings::get_global(cx).drag_and_drop_selection.delay,
+ EditorSettings::get_global(cx)
+ .drag_and_drop_selection
+ .delay
+ .0,
);
if mouse_down_time.elapsed() >= drag_and_drop_delay {
window.set_cursor_style(
@@ -154,7 +154,7 @@ pub fn hover_at_inlay(
hide_hover(editor, cx);
}
- let hover_popover_delay = EditorSettings::get_global(cx).hover_popover_delay;
+ let hover_popover_delay = EditorSettings::get_global(cx).hover_popover_delay.0;
let task = cx.spawn_in(window, async move |this, cx| {
async move {
@@ -275,7 +275,7 @@ fn show_hover(
return None;
}
- let hover_popover_delay = EditorSettings::get_global(cx).hover_popover_delay;
+ let hover_popover_delay = EditorSettings::get_global(cx).hover_popover_delay.0;
let all_diagnostics_active = editor.active_diagnostics == ActiveDiagnostic::All;
let active_group_id = if let ActiveDiagnostic::Group(group) = &editor.active_diagnostics {
Some(group.group_id)
@@ -1004,7 +1004,7 @@ mod tests {
use text::Bias;
fn get_hover_popover_delay(cx: &gpui::TestAppContext) -> u64 {
- cx.read(|cx: &App| -> u64 { EditorSettings::get_global(cx).hover_popover_delay })
+ cx.read(|cx: &App| -> u64 { EditorSettings::get_global(cx).hover_popover_delay.0 })
}
impl InfoPopover {
@@ -331,7 +331,7 @@ pub struct InlineBlameSettings {
/// after a delay once the cursor stops moving.
///
/// Default: 0
- pub delay_ms: std::time::Duration,
+ pub delay_ms: settings::DelayMs,
/// The amount of padding between the end of the source line and the start
/// of the inline blame in units of columns.
///
@@ -357,8 +357,8 @@ pub struct BlameSettings {
impl GitSettings {
pub fn inline_blame_delay(&self) -> Option<Duration> {
- if self.inline_blame.delay_ms.as_millis() > 0 {
- Some(self.inline_blame.delay_ms)
+ if self.inline_blame.delay_ms.0 > 0 {
+ Some(Duration::from_millis(self.inline_blame.delay_ms.0))
} else {
None
}
@@ -452,7 +452,7 @@ impl Settings for ProjectSettings {
let inline = git.inline_blame.unwrap();
InlineBlameSettings {
enabled: inline.enabled.unwrap(),
- delay_ms: std::time::Duration::from_millis(inline.delay_ms.unwrap()),
+ delay_ms: inline.delay_ms.unwrap(),
padding: inline.padding.unwrap(),
min_column: inline.min_column.unwrap(),
show_commit_summary: inline.show_commit_summary.unwrap(),
@@ -504,11 +504,11 @@ impl Settings for ProjectSettings {
include_warnings: diagnostics.include_warnings.unwrap(),
lsp_pull_diagnostics: LspPullDiagnosticsSettings {
enabled: lsp_pull_diagnostics.enabled.unwrap(),
- debounce_ms: lsp_pull_diagnostics.debounce_ms.unwrap(),
+ debounce_ms: lsp_pull_diagnostics.debounce_ms.unwrap().0,
},
inline: InlineDiagnosticsSettings {
enabled: inline_diagnostics.enabled.unwrap(),
- update_debounce_ms: inline_diagnostics.update_debounce_ms.unwrap(),
+ update_debounce_ms: inline_diagnostics.update_debounce_ms.unwrap().0,
padding: inline_diagnostics.padding.unwrap(),
min_column: inline_diagnostics.min_column.unwrap(),
max_severity: inline_diagnostics.max_severity.map(Into::into),
@@ -985,3 +985,33 @@ impl merge_from::MergeFrom for SaturatingBool {
self.0 |= other.0
}
}
+
+#[derive(
+ Copy,
+ Clone,
+ Default,
+ Debug,
+ PartialEq,
+ Eq,
+ PartialOrd,
+ Ord,
+ Serialize,
+ Deserialize,
+ MergeFrom,
+ JsonSchema,
+ derive_more::FromStr,
+)]
+#[serde(transparent)]
+pub struct DelayMs(pub u64);
+
+impl From<u64> for DelayMs {
+ fn from(n: u64) -> Self {
+ Self(n)
+ }
+}
+
+impl std::fmt::Display for DelayMs {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "{}ms", self.0)
+ }
+}
@@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
use settings_macros::MergeFrom;
-use crate::{DiagnosticSeverityContent, ShowScrollbar};
+use crate::{DelayMs, DiagnosticSeverityContent, ShowScrollbar};
#[skip_serializing_none]
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
@@ -45,7 +45,7 @@ pub struct EditorSettingsContent {
/// server based on the current cursor location.
///
/// Default: 75
- pub lsp_highlight_debounce: Option<u64>,
+ pub lsp_highlight_debounce: Option<DelayMs>,
/// Whether to show the informational hover box when moving the mouse
/// over symbols in the editor.
///
@@ -54,7 +54,7 @@ pub struct EditorSettingsContent {
/// Time to wait in milliseconds before showing the informational hover box.
///
/// Default: 300
- pub hover_popover_delay: Option<u64>,
+ pub hover_popover_delay: Option<DelayMs>,
/// Toolbar related settings
pub toolbar: Option<ToolbarContent>,
/// Scrollbar related settings
@@ -722,7 +722,7 @@ pub struct DragAndDropSelectionContent {
/// The delay in milliseconds that must elapse before drag and drop is allowed. Otherwise, a new text selection is created.
///
/// Default: 300
- pub delay: Option<u64>,
+ pub delay: Option<DelayMs>,
}
/// When to show the minimap in the editor.
@@ -804,6 +804,12 @@ impl Display for MinimumContrast {
}
}
+impl From<f32> for MinimumContrast {
+ fn from(x: f32) -> Self {
+ Self(x)
+ }
+}
+
/// Opacity of the inactive panes. 0 means transparent, 1 means opaque.
///
/// Valid range: 0.0 to 1.0
@@ -828,3 +834,9 @@ impl Display for InactiveOpacity {
write!(f, "{:.1}", self.0)
}
}
+
+impl From<f32> for InactiveOpacity {
+ fn from(x: f32) -> Self {
+ Self(x)
+ }
+}
@@ -8,7 +8,8 @@ use settings_macros::MergeFrom;
use util::serde::default_true;
use crate::{
- AllLanguageSettingsContent, ExtendingVec, ProjectTerminalSettingsContent, SlashCommandSettings,
+ AllLanguageSettingsContent, DelayMs, ExtendingVec, ProjectTerminalSettingsContent,
+ SlashCommandSettings,
};
#[skip_serializing_none]
@@ -310,7 +311,7 @@ pub struct InlineBlameSettings {
/// after a delay once the cursor stops moving.
///
/// Default: 0
- pub delay_ms: Option<u64>,
+ pub delay_ms: Option<DelayMs>,
/// The amount of padding between the end of the source line and the start
/// of the inline blame in units of columns.
///
@@ -397,7 +398,7 @@ pub struct LspPullDiagnosticsSettingsContent {
/// 0 turns the debounce off.
///
/// Default: 50
- pub debounce_ms: Option<u64>,
+ pub debounce_ms: Option<DelayMs>,
}
#[skip_serializing_none]
@@ -413,7 +414,7 @@ pub struct InlineDiagnosticsSettingsContent {
/// last editor event.
///
/// Default: 150
- pub update_debounce_ms: Option<u64>,
+ pub update_debounce_ms: Option<DelayMs>,
/// The amount of padding between the end of the source line and the start
/// of the inline diagnostic in units of columns.
///
@@ -112,6 +112,12 @@ impl Display for CodeFade {
}
}
+impl From<f32> for CodeFade {
+ fn from(x: f32) -> Self {
+ Self(x)
+ }
+}
+
fn default_font_features() -> Option<FontFeatures> {
Some(FontFeatures::default())
}
@@ -6,7 +6,9 @@ use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
use settings_macros::MergeFrom;
-use crate::{DockPosition, DockSide, InactiveOpacity, ScrollbarSettingsContent, ShowIndentGuides};
+use crate::{
+ DelayMs, DockPosition, DockSide, InactiveOpacity, ScrollbarSettingsContent, ShowIndentGuides,
+};
#[skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
@@ -386,7 +388,7 @@ pub enum AutosaveSetting {
/// Disable autosave.
Off,
/// Save after inactivity period of `milliseconds`.
- AfterDelay { milliseconds: u64 },
+ AfterDelay { milliseconds: DelayMs },
/// Autosave when focus changes.
OnFocusChange,
/// Autosave when the active window changes.
@@ -259,7 +259,7 @@ impl VsCodeSettings {
gutter: self.gutter_content(),
hide_mouse: None,
horizontal_scroll_margin: None,
- hover_popover_delay: self.read_u64("editor.hover.delay"),
+ hover_popover_delay: self.read_u64("editor.hover.delay").map(Into::into),
hover_popover_enabled: self.read_bool("editor.hover.enabled"),
inline_code_actions: None,
jupyter: None,
@@ -791,7 +791,8 @@ impl VsCodeSettings {
milliseconds: self
.read_value("files.autoSaveDelay")
.and_then(|v| v.as_u64())
- .unwrap_or(1000),
+ .unwrap_or(1000)
+ .into(),
}),
"onFocusChange" => Some(AutosaveSetting::OnFocusChange),
"onWindowChange" => Some(AutosaveSetting::OnWindowChange),
@@ -417,6 +417,7 @@ fn init_renderers(cx: &mut App) {
.add_basic_renderer::<NonZero<usize>>(render_number_field)
.add_basic_renderer::<NonZeroU32>(render_number_field)
.add_basic_renderer::<settings::CodeFade>(render_number_field)
+ .add_basic_renderer::<settings::DelayMs>(render_number_field)
.add_basic_renderer::<gpui::FontWeight>(render_number_field)
.add_basic_renderer::<settings::InactiveOpacity>(render_number_field)
.add_basic_renderer::<settings::MinimumContrast>(render_number_field)
@@ -8,7 +8,7 @@ use std::{
use editor::{Editor, EditorStyle};
use gpui::{ClickEvent, Entity, FocusHandle, Focusable, FontWeight, Modifiers};
-use settings::{CodeFade, InactiveOpacity, MinimumContrast};
+use settings::{CodeFade, DelayMs, InactiveOpacity, MinimumContrast};
use ui::prelude::*;
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
@@ -31,102 +31,47 @@ pub trait NumberFieldType: Display + Copy + Clone + Sized + PartialOrd + FromStr
fn saturating_sub(self, rhs: Self) -> Self;
}
-impl NumberFieldType for gpui::FontWeight {
- fn default_step() -> Self {
- FontWeight(50.0)
- }
- fn large_step() -> Self {
- FontWeight(100.0)
- }
- fn small_step() -> Self {
- FontWeight(10.0)
- }
- fn min_value() -> Self {
- gpui::FontWeight::THIN
- }
- fn max_value() -> Self {
- gpui::FontWeight::BLACK
- }
- fn saturating_add(self, rhs: Self) -> Self {
- FontWeight((self.0 + rhs.0).min(Self::max_value().0))
- }
- fn saturating_sub(self, rhs: Self) -> Self {
- FontWeight((self.0 - rhs.0).max(Self::min_value().0))
- }
-}
+macro_rules! impl_newtype_numeric_stepper {
+ ($type:ident, $default:expr, $large:expr, $small:expr, $min:expr, $max:expr) => {
+ impl NumberFieldType for $type {
+ fn default_step() -> Self {
+ $default.into()
+ }
-impl NumberFieldType for settings::CodeFade {
- fn default_step() -> Self {
- CodeFade(0.10)
- }
- fn large_step() -> Self {
- CodeFade(0.20)
- }
- fn small_step() -> Self {
- CodeFade(0.05)
- }
- fn min_value() -> Self {
- CodeFade(0.0)
- }
- fn max_value() -> Self {
- CodeFade(0.9)
- }
- fn saturating_add(self, rhs: Self) -> Self {
- CodeFade((self.0 + rhs.0).min(Self::max_value().0))
- }
- fn saturating_sub(self, rhs: Self) -> Self {
- CodeFade((self.0 - rhs.0).max(Self::min_value().0))
- }
-}
+ fn large_step() -> Self {
+ $large.into()
+ }
-impl NumberFieldType for settings::InactiveOpacity {
- fn default_step() -> Self {
- InactiveOpacity(0.10)
- }
- fn large_step() -> Self {
- InactiveOpacity(0.20)
- }
- fn small_step() -> Self {
- InactiveOpacity(0.05)
- }
- fn min_value() -> Self {
- InactiveOpacity(0.0)
- }
- fn max_value() -> Self {
- InactiveOpacity(1.0)
- }
- fn saturating_add(self, rhs: Self) -> Self {
- InactiveOpacity((self.0 + rhs.0).min(Self::max_value().0))
- }
- fn saturating_sub(self, rhs: Self) -> Self {
- InactiveOpacity((self.0 - rhs.0).max(Self::min_value().0))
- }
-}
+ fn small_step() -> Self {
+ $small.into()
+ }
-impl NumberFieldType 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))
- }
+ fn min_value() -> Self {
+ $min.into()
+ }
+
+ fn max_value() -> Self {
+ $max.into()
+ }
+
+ fn saturating_add(self, rhs: Self) -> Self {
+ $type((self.0 + rhs.0).min(Self::max_value().0))
+ }
+
+ fn saturating_sub(self, rhs: Self) -> Self {
+ $type((self.0 - rhs.0).max(Self::min_value().0))
+ }
+ }
+ };
}
+#[rustfmt::skip]
+impl_newtype_numeric_stepper!(FontWeight, 50., 100., 10., FontWeight::THIN, FontWeight::BLACK);
+impl_newtype_numeric_stepper!(CodeFade, 0.1, 0.2, 0.05, 0.0, 0.9);
+impl_newtype_numeric_stepper!(InactiveOpacity, 0.1, 0.2, 0.05, 0.0, 1.0);
+impl_newtype_numeric_stepper!(MinimumContrast, 1., 10., 0.5, 0.0, 106.0);
+impl_newtype_numeric_stepper!(DelayMs, 100, 500, 10, 0, 2000);
+
macro_rules! impl_numeric_stepper_int {
($type:ident) => {
impl NumberFieldType for $type {
@@ -811,7 +811,7 @@ impl<T: Item> ItemHandle for Entity<T> {
let autosave = item.workspace_settings(cx).autosave;
if let AutosaveSetting::AfterDelay { milliseconds } = autosave {
- let delay = Duration::from_millis(milliseconds);
+ let delay = Duration::from_millis(milliseconds.0);
let item = item.clone();
pending_autosave.fire_new(
delay,
@@ -8799,8 +8799,9 @@ mod tests {
item.update(cx, |item, cx| {
SettingsStore::update_global(cx, |settings, cx| {
settings.update_user_settings(cx, |settings| {
- settings.workspace.autosave =
- Some(AutosaveSetting::AfterDelay { milliseconds: 500 });
+ settings.workspace.autosave = Some(AutosaveSetting::AfterDelay {
+ milliseconds: 500.into(),
+ });
})
});
item.is_dirty = true;