Add setting for hover delay (#22006)

This PR adds a new `hover_popover_delay` setting that allows the user to
specify how long to wait before showing informational hover boxes. It
defaults to the existing delay.

Release Notes:

- Added a setting to control the delay for informational hover boxes
This commit is contained in:
Aaron Feickert 2024-12-13 22:34:16 -06:00 committed by GitHub
parent cd5d8b4173
commit ff2d20780f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 25 additions and 12 deletions

View file

@ -101,6 +101,8 @@
// Whether to show the informational hover box when moving the mouse // Whether to show the informational hover box when moving the mouse
// over symbols in the editor. // over symbols in the editor.
"hover_popover_enabled": true, "hover_popover_enabled": true,
// Time to wait before showing the informational hover box
"hover_popover_delay": 350,
// Whether to confirm before quitting Zed. // Whether to confirm before quitting Zed.
"confirm_quit": false, "confirm_quit": false,
// Whether to restore last closed project when fresh Zed instance is opened. // Whether to restore last closed project when fresh Zed instance is opened.

View file

@ -11,6 +11,7 @@ pub struct EditorSettings {
pub current_line_highlight: CurrentLineHighlight, pub current_line_highlight: CurrentLineHighlight,
pub lsp_highlight_debounce: u64, pub lsp_highlight_debounce: u64,
pub hover_popover_enabled: bool, pub hover_popover_enabled: bool,
pub hover_popover_delay: u64,
pub toolbar: Toolbar, pub toolbar: Toolbar,
pub scrollbar: Scrollbar, pub scrollbar: Scrollbar,
pub gutter: Gutter, pub gutter: Gutter,
@ -196,7 +197,10 @@ pub struct EditorSettingsContent {
/// ///
/// Default: true /// Default: true
pub hover_popover_enabled: Option<bool>, pub hover_popover_enabled: Option<bool>,
/// Time to wait before showing the informational hover box
///
/// Default: 350
pub hover_popover_delay: Option<u64>,
/// Toolbar related settings /// Toolbar related settings
pub toolbar: Option<ToolbarContent>, pub toolbar: Option<ToolbarContent>,
/// Scrollbar related settings /// Scrollbar related settings

View file

@ -23,7 +23,6 @@ use std::{ops::Range, sync::Arc, time::Duration};
use theme::ThemeSettings; use theme::ThemeSettings;
use ui::{prelude::*, window_is_transparent, Scrollbar, ScrollbarState}; use ui::{prelude::*, window_is_transparent, Scrollbar, ScrollbarState};
use util::TryFutureExt; use util::TryFutureExt;
pub const HOVER_DELAY_MILLIS: u64 = 350;
pub const HOVER_REQUEST_DELAY_MILLIS: u64 = 200; pub const HOVER_REQUEST_DELAY_MILLIS: u64 = 200;
pub const MIN_POPOVER_CHARACTER_WIDTH: f32 = 20.; pub const MIN_POPOVER_CHARACTER_WIDTH: f32 = 20.;
@ -131,10 +130,12 @@ pub fn hover_at_inlay(editor: &mut Editor, inlay_hover: InlayHover, cx: &mut Vie
hide_hover(editor, cx); hide_hover(editor, cx);
} }
let hover_popover_delay = EditorSettings::get_global(cx).hover_popover_delay;
let task = cx.spawn(|this, mut cx| { let task = cx.spawn(|this, mut cx| {
async move { async move {
cx.background_executor() cx.background_executor()
.timer(Duration::from_millis(HOVER_DELAY_MILLIS)) .timer(Duration::from_millis(hover_popover_delay))
.await; .await;
this.update(&mut cx, |this, _| { this.update(&mut cx, |this, _| {
this.hover_state.diagnostic_popover = None; this.hover_state.diagnostic_popover = None;
@ -236,6 +237,8 @@ fn show_hover(
} }
} }
let hover_popover_delay = EditorSettings::get_global(cx).hover_popover_delay;
let task = cx.spawn(|this, mut cx| { let task = cx.spawn(|this, mut cx| {
async move { async move {
// If we need to delay, delay a set amount initially before making the lsp request // If we need to delay, delay a set amount initially before making the lsp request
@ -245,7 +248,7 @@ fn show_hover(
// Construct delay task to wait for later // Construct delay task to wait for later
let total_delay = Some( let total_delay = Some(
cx.background_executor() cx.background_executor()
.timer(Duration::from_millis(HOVER_DELAY_MILLIS)), .timer(Duration::from_millis(hover_popover_delay)),
); );
cx.background_executor() cx.background_executor()
@ -856,6 +859,7 @@ mod tests {
InlayId, PointForPosition, InlayId, PointForPosition,
}; };
use collections::BTreeSet; use collections::BTreeSet;
use gpui::AppContext;
use indoc::indoc; use indoc::indoc;
use language::{language_settings::InlayHintSettings, Diagnostic, DiagnosticSet}; use language::{language_settings::InlayHintSettings, Diagnostic, DiagnosticSet};
use lsp::LanguageServerId; use lsp::LanguageServerId;
@ -865,6 +869,10 @@ mod tests {
use std::sync::atomic::AtomicUsize; use std::sync::atomic::AtomicUsize;
use text::Bias; use text::Bias;
fn get_hover_popover_delay(cx: &gpui::TestAppContext) -> u64 {
cx.read(|cx: &AppContext| -> u64 { EditorSettings::get_global(cx).hover_popover_delay })
}
impl InfoPopover { impl InfoPopover {
fn get_rendered_text(&self, cx: &gpui::AppContext) -> String { fn get_rendered_text(&self, cx: &gpui::AppContext) -> String {
let mut rendered_text = String::new(); let mut rendered_text = String::new();
@ -889,7 +897,6 @@ mod tests {
cx: &mut gpui::TestAppContext, cx: &mut gpui::TestAppContext,
) { ) {
init_test(cx, |_| {}); init_test(cx, |_| {});
const HOVER_DELAY_MILLIS: u64 = 350;
let mut cx = EditorLspTestContext::new_rust( let mut cx = EditorLspTestContext::new_rust(
lsp::ServerCapabilities { lsp::ServerCapabilities {
@ -963,7 +970,7 @@ mod tests {
})) }))
}); });
cx.background_executor cx.background_executor
.advance_clock(Duration::from_millis(HOVER_DELAY_MILLIS + 100)); .advance_clock(Duration::from_millis(get_hover_popover_delay(&cx) + 100));
requests.next().await; requests.next().await;
cx.editor(|editor, cx| { cx.editor(|editor, cx| {
@ -1042,7 +1049,7 @@ mod tests {
hover_at(editor, Some(anchor), cx) hover_at(editor, Some(anchor), cx)
}); });
cx.background_executor cx.background_executor
.advance_clock(Duration::from_millis(HOVER_DELAY_MILLIS + 100)); .advance_clock(Duration::from_millis(get_hover_popover_delay(&cx) + 100));
request.next().await; request.next().await;
// verify that the information popover is no longer visible // verify that the information popover is no longer visible
@ -1096,7 +1103,7 @@ mod tests {
})) }))
}); });
cx.background_executor cx.background_executor
.advance_clock(Duration::from_millis(HOVER_DELAY_MILLIS + 100)); .advance_clock(Duration::from_millis(get_hover_popover_delay(&cx) + 100));
requests.next().await; requests.next().await;
cx.editor(|editor, cx| { cx.editor(|editor, cx| {
@ -1132,7 +1139,7 @@ mod tests {
hover_at(editor, Some(anchor), cx) hover_at(editor, Some(anchor), cx)
}); });
cx.background_executor cx.background_executor
.advance_clock(Duration::from_millis(HOVER_DELAY_MILLIS + 100)); .advance_clock(Duration::from_millis(get_hover_popover_delay(&cx) + 100));
request.next().await; request.next().await;
cx.editor(|editor, _| { cx.editor(|editor, _| {
assert!(!editor.hover_state.visible()); assert!(!editor.hover_state.visible());
@ -1394,7 +1401,7 @@ mod tests {
})) }))
}); });
cx.background_executor cx.background_executor
.advance_clock(Duration::from_millis(HOVER_DELAY_MILLIS + 100)); .advance_clock(Duration::from_millis(get_hover_popover_delay(&cx) + 100));
cx.background_executor.run_until_parked(); cx.background_executor.run_until_parked();
cx.editor(|Editor { hover_state, .. }, _| { cx.editor(|Editor { hover_state, .. }, _| {
@ -1682,7 +1689,7 @@ mod tests {
); );
}); });
cx.background_executor cx.background_executor
.advance_clock(Duration::from_millis(HOVER_DELAY_MILLIS + 100)); .advance_clock(Duration::from_millis(get_hover_popover_delay(&cx) + 100));
cx.background_executor.run_until_parked(); cx.background_executor.run_until_parked();
cx.update_editor(|editor, cx| { cx.update_editor(|editor, cx| {
let hover_state = &editor.hover_state; let hover_state = &editor.hover_state;
@ -1736,7 +1743,7 @@ mod tests {
); );
}); });
cx.background_executor cx.background_executor
.advance_clock(Duration::from_millis(HOVER_DELAY_MILLIS + 100)); .advance_clock(Duration::from_millis(get_hover_popover_delay(&cx) + 100));
cx.background_executor.run_until_parked(); cx.background_executor.run_until_parked();
cx.update_editor(|editor, cx| { cx.update_editor(|editor, cx| {
let hover_state = &editor.hover_state; let hover_state = &editor.hover_state;