From ee33fb03f28e54137d51fef6688b03286144ae42 Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Tue, 7 Jun 2022 18:07:24 -0700 Subject: [PATCH] wip --- crates/editor/src/editor.rs | 96 +----------------------------- crates/editor/src/hover_popover.rs | 94 +++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 95 deletions(-) create mode 100644 crates/editor/src/hover_popover.rs diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 41f2b4092a5e368575afcce178faef6cbf5856a6..25c0c53b3d091739e3a79e255685f2cd08ee30bf 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -1,5 +1,6 @@ pub mod display_map; mod element; +mod hover; pub mod items; pub mod movement; mod multi_buffer; @@ -431,7 +432,6 @@ pub struct Editor { next_completion_id: CompletionId, available_code_actions: Option<(ModelHandle, Arc<[CodeAction]>)>, code_actions_task: Option>, - hover_task: Option>>, document_highlights_task: Option>, pending_rename: Option, searchable: bool, @@ -442,39 +442,6 @@ pub struct Editor { hover_state: HoverState, } -/// Keeps track of the state of the [`HoverPopover`]. -/// Times out the initial delay and the grace period. -pub struct HoverState { - popover: Option, - last_hover: std::time::Instant, - start_grace: std::time::Instant, -} - -impl HoverState { - /// Takes whether the cursor is currently hovering over a symbol, - /// and returns a tuple containing whether there was a recent hover, - /// and whether the hover is still in the grace period. - pub fn determine_state(&mut self, hovering: bool) -> (bool, bool) { - // NOTE: We use some sane defaults, but it might be - // nice to make these values configurable. - let recent_hover = self.last_hover.elapsed() < std::time::Duration::from_millis(500); - if !hovering { - self.last_hover = std::time::Instant::now(); - } - - let in_grace = self.start_grace.elapsed() < std::time::Duration::from_millis(250); - if hovering && !recent_hover { - self.start_grace = std::time::Instant::now(); - } - - return (recent_hover, in_grace); - } - - pub fn close(&mut self) { - self.popover.take(); - } -} - pub struct EditorSnapshot { pub mode: EditorMode, pub display_snapshot: DisplaySnapshot, @@ -899,67 +866,6 @@ impl CodeActionsMenu { } } -#[derive(Clone)] -pub(crate) struct HoverPopover { - pub project: ModelHandle, - pub hover_point: DisplayPoint, - pub range: Range, - pub contents: Vec, -} - -impl HoverPopover { - fn render( - &self, - style: EditorStyle, - cx: &mut RenderContext, - ) -> (DisplayPoint, ElementBox) { - let element = MouseEventHandler::new::(0, cx, |_, cx| { - let mut flex = Flex::new(Axis::Vertical).scrollable::(1, None, cx); - flex.extend(self.contents.iter().map(|content| { - let project = self.project.read(cx); - if let Some(language) = content - .language - .clone() - .and_then(|language| project.languages().get_language(&language)) - { - let runs = language - .highlight_text(&content.text.as_str().into(), 0..content.text.len()); - - Text::new(content.text.clone(), style.text.clone()) - .with_soft_wrap(true) - .with_highlights( - runs.iter() - .filter_map(|(range, id)| { - id.style(style.theme.syntax.as_ref()) - .map(|style| (range.clone(), style)) - }) - .collect(), - ) - .boxed() - } else { - Text::new(content.text.clone(), style.hover_popover.prose.clone()) - .with_soft_wrap(true) - .contained() - .with_style(style.hover_popover.block_style) - .boxed() - } - })); - flex.contained() - .with_style(style.hover_popover.container) - .boxed() - }) - .with_cursor_style(CursorStyle::Arrow) - .with_padding(Padding { - bottom: 5., - top: 5., - ..Default::default() - }) - .boxed(); - - (self.range.start, element) - } -} - #[derive(Debug)] struct ActiveDiagnosticGroup { primary_range: Range, diff --git a/crates/editor/src/hover_popover.rs b/crates/editor/src/hover_popover.rs new file mode 100644 index 0000000000000000000000000000000000000000..6fb28c0b08bfef67a53e565a7c70db6c418eb927 --- /dev/null +++ b/crates/editor/src/hover_popover.rs @@ -0,0 +1,94 @@ +/// Keeps track of the state of the [`HoverPopover`]. +/// Times out the initial delay and the grace period. +pub struct HoverState { + popover: Option, + last_hover: std::time::Instant, + start_grace: std::time::Instant, +} + +impl HoverState { + /// Takes whether the cursor is currently hovering over a symbol, + /// and returns a tuple containing whether there was a recent hover, + /// and whether the hover is still in the grace period. + pub fn determine_state(&mut self, hovering: bool) -> (bool, bool) { + // NOTE: We use some sane defaults, but it might be + // nice to make these values configurable. + let recent_hover = self.last_hover.elapsed() < std::time::Duration::from_millis(500); + if !hovering { + self.last_hover = std::time::Instant::now(); + } + + let in_grace = self.start_grace.elapsed() < std::time::Duration::from_millis(250); + if hovering && !recent_hover { + self.start_grace = std::time::Instant::now(); + } + + return (recent_hover, in_grace); + } + + pub fn close(&mut self) { + self.popover.take(); + } +} + +#[derive(Clone)] +pub(crate) struct HoverPopover { + pub project: ModelHandle, + pub hover_point: DisplayPoint, + pub range: Range, + pub contents: Vec, + pub task: Option>, +} + +impl HoverPopover { + fn render( + &self, + style: EditorStyle, + cx: &mut RenderContext, + ) -> (DisplayPoint, ElementBox) { + let element = MouseEventHandler::new::(0, cx, |_, cx| { + let mut flex = Flex::new(Axis::Vertical).scrollable::(1, None, cx); + flex.extend(self.contents.iter().map(|content| { + let project = self.project.read(cx); + if let Some(language) = content + .language + .clone() + .and_then(|language| project.languages().get_language(&language)) + { + let runs = language + .highlight_text(&content.text.as_str().into(), 0..content.text.len()); + + Text::new(content.text.clone(), style.text.clone()) + .with_soft_wrap(true) + .with_highlights( + runs.iter() + .filter_map(|(range, id)| { + id.style(style.theme.syntax.as_ref()) + .map(|style| (range.clone(), style)) + }) + .collect(), + ) + .boxed() + } else { + Text::new(content.text.clone(), style.hover_popover.prose.clone()) + .with_soft_wrap(true) + .contained() + .with_style(style.hover_popover.block_style) + .boxed() + } + })); + flex.contained() + .with_style(style.hover_popover.container) + .boxed() + }) + .with_cursor_style(CursorStyle::Arrow) + .with_padding(Padding { + bottom: 5., + top: 5., + ..Default::default() + }) + .boxed(); + + (self.range.start, element) + } +}