mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-08 07:35:01 +03:00
Add ability to scroll popovers with vim (#12650)
Co-Authored-By: ahmadraheel@gmail.com Release Notes: - vim: allow scrolling the currently open information overlay using `ctrl-{u,d,e,y}`etc. (#11883)
This commit is contained in:
parent
f3460d440c
commit
428c143fbb
@ -1,5 +1,6 @@
|
||||
use crate::{
|
||||
hover_popover::{self, InlayHover},
|
||||
scroll::ScrollAmount,
|
||||
Anchor, Editor, EditorSnapshot, FindAllReferences, GoToDefinition, GoToTypeDefinition, InlayId,
|
||||
PointForPosition, SelectPhase,
|
||||
};
|
||||
@ -38,7 +39,11 @@ impl RangeInEditor {
|
||||
}
|
||||
}
|
||||
|
||||
fn point_within_range(&self, trigger_point: &TriggerPoint, snapshot: &EditorSnapshot) -> bool {
|
||||
pub fn point_within_range(
|
||||
&self,
|
||||
trigger_point: &TriggerPoint,
|
||||
snapshot: &EditorSnapshot,
|
||||
) -> bool {
|
||||
match (self, trigger_point) {
|
||||
(Self::Text(range), TriggerPoint::Text(point)) => {
|
||||
let point_after_start = range.start.cmp(point, &snapshot.buffer_snapshot).is_le();
|
||||
@ -169,6 +174,21 @@ impl Editor {
|
||||
.detach();
|
||||
}
|
||||
|
||||
pub fn scroll_hover(&mut self, amount: &ScrollAmount, cx: &mut ViewContext<Self>) -> bool {
|
||||
let selection = self.selections.newest_anchor().head();
|
||||
let snapshot = self.snapshot(cx);
|
||||
|
||||
let Some(popover) = self.hover_state.info_popovers.iter().find(|popover| {
|
||||
popover
|
||||
.symbol_range
|
||||
.point_within_range(&TriggerPoint::Text(selection), &snapshot)
|
||||
}) else {
|
||||
return false;
|
||||
};
|
||||
popover.scroll(amount, cx);
|
||||
true
|
||||
}
|
||||
|
||||
fn cmd_click_reveal_task(
|
||||
&mut self,
|
||||
point: PointForPosition,
|
||||
|
@ -1,14 +1,15 @@
|
||||
use crate::{
|
||||
display_map::{InlayOffset, ToDisplayPoint},
|
||||
hover_links::{InlayHighlight, RangeInEditor},
|
||||
scroll::ScrollAmount,
|
||||
Anchor, AnchorRangeExt, DisplayPoint, DisplayRow, Editor, EditorSettings, EditorSnapshot,
|
||||
EditorStyle, ExcerptId, Hover, RangeToAnchorExt,
|
||||
};
|
||||
use futures::{stream::FuturesUnordered, FutureExt};
|
||||
use gpui::{
|
||||
div, px, AnyElement, CursorStyle, Hsla, InteractiveElement, IntoElement, MouseButton,
|
||||
ParentElement, Pixels, SharedString, Size, StatefulInteractiveElement, Styled, Task,
|
||||
ViewContext, WeakView,
|
||||
ParentElement, Pixels, ScrollHandle, SharedString, Size, StatefulInteractiveElement, Styled,
|
||||
Task, ViewContext, WeakView,
|
||||
};
|
||||
use language::{markdown, DiagnosticEntry, Language, LanguageRegistry, ParsedMarkdown};
|
||||
|
||||
@ -118,6 +119,7 @@ pub fn hover_at_inlay(editor: &mut Editor, inlay_hover: InlayHover, cx: &mut Vie
|
||||
let hover_popover = InfoPopover {
|
||||
symbol_range: RangeInEditor::Inlay(inlay_hover.range.clone()),
|
||||
parsed_content,
|
||||
scroll_handle: ScrollHandle::new(),
|
||||
};
|
||||
|
||||
this.update(&mut cx, |this, cx| {
|
||||
@ -317,6 +319,7 @@ fn show_hover(
|
||||
InfoPopover {
|
||||
symbol_range: RangeInEditor::Text(range),
|
||||
parsed_content,
|
||||
scroll_handle: ScrollHandle::new(),
|
||||
},
|
||||
)
|
||||
})
|
||||
@ -423,7 +426,7 @@ async fn parse_blocks(
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
#[derive(Default, Debug)]
|
||||
pub struct HoverState {
|
||||
pub info_popovers: Vec<InfoPopover>,
|
||||
pub diagnostic_popover: Option<DiagnosticPopover>,
|
||||
@ -487,10 +490,11 @@ impl HoverState {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct InfoPopover {
|
||||
symbol_range: RangeInEditor,
|
||||
parsed_content: ParsedMarkdown,
|
||||
pub symbol_range: RangeInEditor,
|
||||
pub parsed_content: ParsedMarkdown,
|
||||
pub scroll_handle: ScrollHandle,
|
||||
}
|
||||
|
||||
impl InfoPopover {
|
||||
@ -504,23 +508,33 @@ impl InfoPopover {
|
||||
div()
|
||||
.id("info_popover")
|
||||
.elevation_2(cx)
|
||||
.p_2()
|
||||
.overflow_y_scroll()
|
||||
.track_scroll(&self.scroll_handle)
|
||||
.max_w(max_size.width)
|
||||
.max_h(max_size.height)
|
||||
// Prevent a mouse down/move on the popover from being propagated to the editor,
|
||||
// because that would dismiss the popover.
|
||||
.on_mouse_move(|_, cx| cx.stop_propagation())
|
||||
.on_mouse_down(MouseButton::Left, |_, cx| cx.stop_propagation())
|
||||
.child(crate::render_parsed_markdown(
|
||||
.child(div().p_2().child(crate::render_parsed_markdown(
|
||||
"content",
|
||||
&self.parsed_content,
|
||||
style,
|
||||
workspace,
|
||||
cx,
|
||||
))
|
||||
)))
|
||||
.into_any_element()
|
||||
}
|
||||
|
||||
pub fn scroll(&self, amount: &ScrollAmount, cx: &mut ViewContext<Editor>) {
|
||||
let mut current = self.scroll_handle.offset();
|
||||
current.y -= amount.pixels(
|
||||
cx.line_height(),
|
||||
self.scroll_handle.bounds().size.height - px(16.),
|
||||
) / 2.0;
|
||||
cx.notify();
|
||||
self.scroll_handle.set_offset(current);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -1,7 +1,8 @@
|
||||
use crate::Editor;
|
||||
use serde::Deserialize;
|
||||
use ui::{px, Pixels};
|
||||
|
||||
#[derive(Clone, PartialEq, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||
pub enum ScrollAmount {
|
||||
// Scroll N lines (positive is towards the end of the document)
|
||||
Line(f32),
|
||||
@ -25,4 +26,11 @@ impl ScrollAmount {
|
||||
.unwrap_or(0.),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pixels(&self, line_height: Pixels, height: Pixels) -> Pixels {
|
||||
match self {
|
||||
ScrollAmount::Line(x) => px(line_height.0 * x),
|
||||
ScrollAmount::Page(x) => px(height.0 * x),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2437,7 +2437,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
#[derive(Default, Debug)]
|
||||
struct ScrollHandleState {
|
||||
offset: Rc<RefCell<Point<Pixels>>>,
|
||||
bounds: Bounds<Pixels>,
|
||||
@ -2449,7 +2449,7 @@ struct ScrollHandleState {
|
||||
/// A handle to the scrollable aspects of an element.
|
||||
/// Used for accessing scroll state, like the current scroll offset,
|
||||
/// and for mutating the scroll state, like scrolling to a specific child.
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ScrollHandle(Rc<RefCell<ScrollHandleState>>);
|
||||
|
||||
impl Default for ScrollHandle {
|
||||
@ -2526,6 +2526,14 @@ impl ScrollHandle {
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the offset explicitly. The offset is the distance from the top left of the
|
||||
/// parent container to the top left of the first child.
|
||||
/// As you scroll further down the offset becomes more negative.
|
||||
pub fn set_offset(&self, mut position: Point<Pixels>) {
|
||||
let state = self.0.borrow();
|
||||
*state.offset.borrow_mut() = position;
|
||||
}
|
||||
|
||||
/// Get the logical scroll top, based on a child index and a pixel offset.
|
||||
pub fn logical_scroll_top(&self) -> (usize, Pixels) {
|
||||
let ix = self.top_item();
|
||||
|
@ -69,6 +69,10 @@ fn scroll_editor(
|
||||
let should_move_cursor = editor.newest_selection_on_screen(cx).is_eq();
|
||||
let old_top_anchor = editor.scroll_manager.anchor().anchor;
|
||||
|
||||
if editor.scroll_hover(amount, cx) {
|
||||
return;
|
||||
}
|
||||
|
||||
editor.scroll_screen(amount, cx);
|
||||
if should_move_cursor {
|
||||
let visible_rows = if let Some(visible_rows) = editor.visible_line_count() {
|
||||
|
Loading…
Reference in New Issue
Block a user