Merge branch 'main' into picker
This commit is contained in:
commit
fe28d8faea
31 changed files with 5218 additions and 4767 deletions
File diff suppressed because it is too large
Load diff
|
@ -2,16 +2,25 @@ use crate::{
|
|||
display_map::{BlockStyle, DisplaySnapshot, FoldStatus, HighlightedChunk, ToDisplayPoint},
|
||||
editor_settings::ShowScrollbar,
|
||||
git::{diff_hunk_to_display, DisplayDiffHunk},
|
||||
hover_popover::hover_at,
|
||||
link_go_to_definition::{
|
||||
go_to_fetched_definition, go_to_fetched_type_definition, update_go_to_definition_link,
|
||||
update_inlay_link_and_hover_points, GoToDefinitionTrigger,
|
||||
},
|
||||
scroll::scroll_amount::ScrollAmount,
|
||||
CursorShape, DisplayPoint, Editor, EditorMode, EditorSettings, EditorSnapshot, EditorStyle,
|
||||
MoveDown, Point, Selection, SoftWrap, ToPoint, MAX_LINE_LEN,
|
||||
HalfPageDown, HalfPageUp, LineDown, LineUp, MoveDown, PageDown, PageUp, Point, SelectPhase,
|
||||
Selection, SoftWrap, ToPoint, MAX_LINE_LEN,
|
||||
};
|
||||
use anyhow::Result;
|
||||
use collections::{BTreeMap, HashMap};
|
||||
use gpui::{
|
||||
black, hsla, point, px, relative, size, transparent_black, Action, AnyElement, BorrowWindow,
|
||||
Bounds, ContentMask, Corners, DispatchContext, DispatchPhase, Edges, Element, ElementId,
|
||||
Entity, Hsla, KeyDownEvent, KeyListener, KeyMatch, Line, Pixels, ScrollWheelEvent, ShapedGlyph,
|
||||
Size, StatefulInteractivity, Style, TextRun, TextStyle, TextSystem, ViewContext, WindowContext,
|
||||
black, hsla, point, px, relative, size, transparent_black, Action, AnyElement,
|
||||
BorrowAppContext, BorrowWindow, Bounds, ContentMask, Corners, DispatchContext, DispatchPhase,
|
||||
Edges, Element, ElementId, Entity, GlobalElementId, Hsla, KeyDownEvent, KeyListener, KeyMatch,
|
||||
Line, Modifiers, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels,
|
||||
ScrollWheelEvent, ShapedGlyph, Size, Style, TextRun, TextStyle, TextSystem, ViewContext,
|
||||
WindowContext,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use language::language_settings::ShowWhitespaceSetting;
|
||||
|
@ -30,6 +39,7 @@ use std::{
|
|||
};
|
||||
use sum_tree::Bias;
|
||||
use theme::{ActiveTheme, PlayerColor};
|
||||
use util::ResultExt;
|
||||
use workspace::item::Item;
|
||||
|
||||
enum FoldMarkers {}
|
||||
|
@ -103,194 +113,54 @@ impl EditorElement {
|
|||
Self { style }
|
||||
}
|
||||
|
||||
// fn attach_mouse_handlers(
|
||||
// position_map: &Arc<PositionMap>,
|
||||
// has_popovers: bool,
|
||||
// visible_bounds: Bounds<Pixels>,
|
||||
// text_bounds: Bounds<Pixels>,
|
||||
// gutter_bounds: Bounds<Pixels>,
|
||||
// bounds: Bounds<Pixels>,
|
||||
// cx: &mut ViewContext<Editor>,
|
||||
// ) {
|
||||
// enum EditorElementMouseHandlers {}
|
||||
// let view_id = cx.view_id();
|
||||
// cx.scene().push_mouse_region(
|
||||
// MouseRegion::new::<EditorElementMouseHandlers>(view_id, view_id, visible_bounds)
|
||||
// .on_down(MouseButton::Left, {
|
||||
// let position_map = position_map.clone();
|
||||
// move |event, editor, cx| {
|
||||
// if !Self::mouse_down(
|
||||
// editor,
|
||||
// event.platform_event,
|
||||
// position_map.as_ref(),
|
||||
// text_bounds,
|
||||
// gutter_bounds,
|
||||
// cx,
|
||||
// ) {
|
||||
// cx.propagate_event();
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// .on_down(MouseButton::Right, {
|
||||
// let position_map = position_map.clone();
|
||||
// move |event, editor, cx| {
|
||||
// if !Self::mouse_right_down(
|
||||
// editor,
|
||||
// event.position,
|
||||
// position_map.as_ref(),
|
||||
// text_bounds,
|
||||
// cx,
|
||||
// ) {
|
||||
// cx.propagate_event();
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// .on_up(MouseButton::Left, {
|
||||
// let position_map = position_map.clone();
|
||||
// move |event, editor, cx| {
|
||||
// if !Self::mouse_up(
|
||||
// editor,
|
||||
// event.position,
|
||||
// event.cmd,
|
||||
// event.shift,
|
||||
// event.alt,
|
||||
// position_map.as_ref(),
|
||||
// text_bounds,
|
||||
// cx,
|
||||
// ) {
|
||||
// cx.propagate_event()
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// .on_drag(MouseButton::Left, {
|
||||
// let position_map = position_map.clone();
|
||||
// move |event, editor, cx| {
|
||||
// if event.end {
|
||||
// return;
|
||||
// }
|
||||
fn mouse_down(
|
||||
editor: &mut Editor,
|
||||
event: &MouseDownEvent,
|
||||
position_map: &PositionMap,
|
||||
text_bounds: Bounds<Pixels>,
|
||||
gutter_bounds: Bounds<Pixels>,
|
||||
cx: &mut ViewContext<Editor>,
|
||||
) -> bool {
|
||||
let mut click_count = event.click_count;
|
||||
let modifiers = event.modifiers;
|
||||
|
||||
// if !Self::mouse_dragged(
|
||||
// editor,
|
||||
// event.platform_event,
|
||||
// position_map.as_ref(),
|
||||
// text_bounds,
|
||||
// cx,
|
||||
// ) {
|
||||
// cx.propagate_event()
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// .on_move({
|
||||
// let position_map = position_map.clone();
|
||||
// move |event, editor, cx| {
|
||||
// if !Self::mouse_moved(
|
||||
// editor,
|
||||
// event.platform_event,
|
||||
// &position_map,
|
||||
// text_bounds,
|
||||
// cx,
|
||||
// ) {
|
||||
// cx.propagate_event()
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// .on_move_out(move |_, editor: &mut Editor, cx| {
|
||||
// if has_popovers {
|
||||
// hide_hover(editor, cx);
|
||||
// }
|
||||
// })
|
||||
// .on_scroll({
|
||||
// let position_map = position_map.clone();
|
||||
// move |event, editor, cx| {
|
||||
// if !Self::scroll(
|
||||
// editor,
|
||||
// event.position,
|
||||
// *event.delta.raw(),
|
||||
// event.delta.precise(),
|
||||
// &position_map,
|
||||
// bounds,
|
||||
// cx,
|
||||
// ) {
|
||||
// cx.propagate_event()
|
||||
// }
|
||||
// }
|
||||
// }),
|
||||
// );
|
||||
if gutter_bounds.contains_point(&event.position) {
|
||||
click_count = 3; // Simulate triple-click when clicking the gutter to select lines
|
||||
} else if !text_bounds.contains_point(&event.position) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// enum GutterHandlers {}
|
||||
// let view_id = cx.view_id();
|
||||
// let region_id = cx.view_id() + 1;
|
||||
// cx.scene().push_mouse_region(
|
||||
// MouseRegion::new::<GutterHandlers>(view_id, region_id, gutter_bounds).on_hover(
|
||||
// |hover, editor: &mut Editor, cx| {
|
||||
// editor.gutter_hover(
|
||||
// &GutterHover {
|
||||
// hovered: hover.started,
|
||||
// },
|
||||
// cx,
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// )
|
||||
// }
|
||||
let point_for_position = position_map.point_for_position(text_bounds, event.position);
|
||||
let position = point_for_position.previous_valid;
|
||||
if modifiers.shift && modifiers.alt {
|
||||
editor.select(
|
||||
SelectPhase::BeginColumnar {
|
||||
position,
|
||||
goal_column: point_for_position.exact_unclipped.column(),
|
||||
},
|
||||
cx,
|
||||
);
|
||||
} else if modifiers.shift && !modifiers.control && !modifiers.alt && !modifiers.command {
|
||||
editor.select(
|
||||
SelectPhase::Extend {
|
||||
position,
|
||||
click_count,
|
||||
},
|
||||
cx,
|
||||
);
|
||||
} else {
|
||||
editor.select(
|
||||
SelectPhase::Begin {
|
||||
position,
|
||||
add: modifiers.alt,
|
||||
click_count,
|
||||
},
|
||||
cx,
|
||||
);
|
||||
}
|
||||
|
||||
// fn mouse_down(
|
||||
// editor: &mut Editor,
|
||||
// MouseButtonEvent {
|
||||
// position,
|
||||
// modifiers:
|
||||
// Modifiers {
|
||||
// shift,
|
||||
// ctrl,
|
||||
// alt,
|
||||
// cmd,
|
||||
// ..
|
||||
// },
|
||||
// mut click_count,
|
||||
// ..
|
||||
// }: MouseButtonEvent,
|
||||
// position_map: &PositionMap,
|
||||
// text_bounds: Bounds<Pixels>,
|
||||
// gutter_bounds: Bounds<Pixels>,
|
||||
// cx: &mut EventContext<Editor>,
|
||||
// ) -> bool {
|
||||
// if gutter_bounds.contains_point(position) {
|
||||
// click_count = 3; // Simulate triple-click when clicking the gutter to select lines
|
||||
// } else if !text_bounds.contains_point(position) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// let point_for_position = position_map.point_for_position(text_bounds, position);
|
||||
// let position = point_for_position.previous_valid;
|
||||
// if shift && alt {
|
||||
// editor.select(
|
||||
// SelectPhase::BeginColumnar {
|
||||
// position,
|
||||
// goal_column: point_for_position.exact_unclipped.column(),
|
||||
// },
|
||||
// cx,
|
||||
// );
|
||||
// } else if shift && !ctrl && !alt && !cmd {
|
||||
// editor.select(
|
||||
// SelectPhase::Extend {
|
||||
// position,
|
||||
// click_count,
|
||||
// },
|
||||
// cx,
|
||||
// );
|
||||
// } else {
|
||||
// editor.select(
|
||||
// SelectPhase::Begin {
|
||||
// position,
|
||||
// add: alt,
|
||||
// click_count,
|
||||
// },
|
||||
// cx,
|
||||
// );
|
||||
// }
|
||||
|
||||
// true
|
||||
// }
|
||||
true
|
||||
}
|
||||
|
||||
// fn mouse_right_down(
|
||||
// editor: &mut Editor,
|
||||
|
@ -312,157 +182,120 @@ impl EditorElement {
|
|||
// true
|
||||
// }
|
||||
|
||||
// fn mouse_up(
|
||||
// editor: &mut Editor,
|
||||
// position: gpui::Point<Pixels>,
|
||||
// cmd: bool,
|
||||
// shift: bool,
|
||||
// alt: bool,
|
||||
// position_map: &PositionMap,
|
||||
// text_bounds: Bounds<Pixels>,
|
||||
// cx: &mut EventContext<Editor>,
|
||||
// ) -> bool {
|
||||
// let end_selection = editor.has_pending_selection();
|
||||
// let pending_nonempty_selections = editor.has_pending_nonempty_selection();
|
||||
fn mouse_up(
|
||||
editor: &mut Editor,
|
||||
event: &MouseUpEvent,
|
||||
position_map: &PositionMap,
|
||||
text_bounds: Bounds<Pixels>,
|
||||
cx: &mut ViewContext<Editor>,
|
||||
) -> bool {
|
||||
let end_selection = editor.has_pending_selection();
|
||||
let pending_nonempty_selections = editor.has_pending_nonempty_selection();
|
||||
|
||||
// if end_selection {
|
||||
// editor.select(SelectPhase::End, cx);
|
||||
// }
|
||||
if end_selection {
|
||||
editor.select(SelectPhase::End, cx);
|
||||
}
|
||||
|
||||
// if !pending_nonempty_selections && cmd && text_bounds.contains_point(position) {
|
||||
// let point = position_map.point_for_position(text_bounds, position);
|
||||
// let could_be_inlay = point.as_valid().is_none();
|
||||
// if shift || could_be_inlay {
|
||||
// go_to_fetched_type_definition(editor, point, alt, cx);
|
||||
// } else {
|
||||
// go_to_fetched_definition(editor, point, alt, cx);
|
||||
// }
|
||||
if !pending_nonempty_selections
|
||||
&& event.modifiers.command
|
||||
&& text_bounds.contains_point(&event.position)
|
||||
{
|
||||
let point = position_map.point_for_position(text_bounds, event.position);
|
||||
let could_be_inlay = point.as_valid().is_none();
|
||||
let split = event.modifiers.alt;
|
||||
if event.modifiers.shift || could_be_inlay {
|
||||
go_to_fetched_type_definition(editor, point, split, cx);
|
||||
} else {
|
||||
go_to_fetched_definition(editor, point, split, cx);
|
||||
}
|
||||
|
||||
// return true;
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
// end_selection
|
||||
// }
|
||||
end_selection
|
||||
}
|
||||
|
||||
// fn mouse_dragged(
|
||||
// editor: &mut Editor,
|
||||
// MouseMovedEvent {
|
||||
// modifiers: Modifiers { cmd, shift, .. },
|
||||
// position,
|
||||
// ..
|
||||
// }: MouseMovedEvent,
|
||||
// position_map: &PositionMap,
|
||||
// text_bounds: Bounds<Pixels>,
|
||||
// cx: &mut EventContext<Editor>,
|
||||
// ) -> bool {
|
||||
// // This will be handled more correctly once https://github.com/zed-industries/zed/issues/1218 is completed
|
||||
// // Don't trigger hover popover if mouse is hovering over context menu
|
||||
// let point = if text_bounds.contains_point(position) {
|
||||
// position_map
|
||||
// .point_for_position(text_bounds, position)
|
||||
// .as_valid()
|
||||
// } else {
|
||||
// None
|
||||
// };
|
||||
fn mouse_moved(
|
||||
editor: &mut Editor,
|
||||
event: &MouseMoveEvent,
|
||||
position_map: &PositionMap,
|
||||
text_bounds: Bounds<Pixels>,
|
||||
gutter_bounds: Bounds<Pixels>,
|
||||
cx: &mut ViewContext<Editor>,
|
||||
) -> bool {
|
||||
let modifiers = event.modifiers;
|
||||
if editor.has_pending_selection() && event.pressed_button == Some(MouseButton::Left) {
|
||||
let point_for_position = position_map.point_for_position(text_bounds, event.position);
|
||||
let mut scroll_delta = gpui::Point::<f32>::zero();
|
||||
let vertical_margin = position_map.line_height.min(text_bounds.size.height / 3.0);
|
||||
let top = text_bounds.origin.y + vertical_margin;
|
||||
let bottom = text_bounds.lower_left().y - vertical_margin;
|
||||
if event.position.y < top {
|
||||
scroll_delta.y = -scale_vertical_mouse_autoscroll_delta(top - event.position.y);
|
||||
}
|
||||
if event.position.y > bottom {
|
||||
scroll_delta.y = scale_vertical_mouse_autoscroll_delta(event.position.y - bottom);
|
||||
}
|
||||
|
||||
// update_go_to_definition_link(
|
||||
// editor,
|
||||
// point.map(GoToDefinitionTrigger::Text),
|
||||
// cmd,
|
||||
// shift,
|
||||
// cx,
|
||||
// );
|
||||
let horizontal_margin = position_map.line_height.min(text_bounds.size.width / 3.0);
|
||||
let left = text_bounds.origin.x + horizontal_margin;
|
||||
let right = text_bounds.upper_right().x - horizontal_margin;
|
||||
if event.position.x < left {
|
||||
scroll_delta.x = -scale_horizontal_mouse_autoscroll_delta(left - event.position.x);
|
||||
}
|
||||
if event.position.x > right {
|
||||
scroll_delta.x = scale_horizontal_mouse_autoscroll_delta(event.position.x - right);
|
||||
}
|
||||
|
||||
// if editor.has_pending_selection() {
|
||||
// let mut scroll_delta = gpui::Point::<Pixels>::zero();
|
||||
editor.select(
|
||||
SelectPhase::Update {
|
||||
position: point_for_position.previous_valid,
|
||||
goal_column: point_for_position.exact_unclipped.column(),
|
||||
scroll_position: (position_map.snapshot.scroll_position() + scroll_delta)
|
||||
.clamp(&gpui::Point::zero(), &position_map.scroll_max),
|
||||
},
|
||||
cx,
|
||||
);
|
||||
}
|
||||
|
||||
// let vertical_margin = position_map.line_height.min(text_bounds.height() / 3.0);
|
||||
// let top = text_bounds.origin.y + vertical_margin;
|
||||
// let bottom = text_bounds.lower_left().y - vertical_margin;
|
||||
// if position.y < top {
|
||||
// scroll_delta.set_y(-scale_vertical_mouse_autoscroll_delta(top - position.y))
|
||||
// }
|
||||
// if position.y > bottom {
|
||||
// scroll_delta.set_y(scale_vertical_mouse_autoscroll_delta(position.y - bottom))
|
||||
// }
|
||||
let text_hovered = text_bounds.contains_point(&event.position);
|
||||
let gutter_hovered = gutter_bounds.contains_point(&event.position);
|
||||
editor.set_gutter_hovered(gutter_hovered, cx);
|
||||
|
||||
// let horizontal_margin = position_map.line_height.min(text_bounds.width() / 3.0);
|
||||
// let left = text_bounds.origin.x + horizontal_margin;
|
||||
// let right = text_bounds.upper_right().x - horizontal_margin;
|
||||
// if position.x < left {
|
||||
// scroll_delta.set_x(-scale_horizontal_mouse_autoscroll_delta(
|
||||
// left - position.x,
|
||||
// ))
|
||||
// }
|
||||
// if position.x > right {
|
||||
// scroll_delta.set_x(scale_horizontal_mouse_autoscroll_delta(
|
||||
// position.x - right,
|
||||
// ))
|
||||
// }
|
||||
// Don't trigger hover popover if mouse is hovering over context menu
|
||||
if text_hovered {
|
||||
let point_for_position = position_map.point_for_position(text_bounds, event.position);
|
||||
|
||||
// let point_for_position = position_map.point_for_position(text_bounds, position);
|
||||
match point_for_position.as_valid() {
|
||||
Some(point) => {
|
||||
update_go_to_definition_link(
|
||||
editor,
|
||||
Some(GoToDefinitionTrigger::Text(point)),
|
||||
modifiers.command,
|
||||
modifiers.shift,
|
||||
cx,
|
||||
);
|
||||
hover_at(editor, Some(point), cx);
|
||||
}
|
||||
None => {
|
||||
update_inlay_link_and_hover_points(
|
||||
&position_map.snapshot,
|
||||
point_for_position,
|
||||
editor,
|
||||
modifiers.command,
|
||||
modifiers.shift,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// editor.select(
|
||||
// SelectPhase::Update {
|
||||
// position: point_for_position.previous_valid,
|
||||
// goal_column: point_for_position.exact_unclipped.column(),
|
||||
// scroll_position: (position_map.snapshot.scroll_position() + scroll_delta)
|
||||
// .clamp(gpui::Point::<Pixels>::zero(), position_map.scroll_max),
|
||||
// },
|
||||
// cx,
|
||||
// );
|
||||
// hover_at(editor, point, cx);
|
||||
// true
|
||||
// } else {
|
||||
// hover_at(editor, point, cx);
|
||||
// false
|
||||
// }
|
||||
// }
|
||||
|
||||
// fn mouse_moved(
|
||||
// editor: &mut Editor,
|
||||
// MouseMovedEvent {
|
||||
// modifiers: Modifiers { shift, cmd, .. },
|
||||
// position,
|
||||
// ..
|
||||
// }: MouseMovedEvent,
|
||||
// position_map: &PositionMap,
|
||||
// text_bounds: Bounds<Pixels>,
|
||||
// cx: &mut ViewContext<Editor>,
|
||||
// ) -> bool {
|
||||
// // This will be handled more correctly once https://github.com/zed-industries/zed/issues/1218 is completed
|
||||
// // Don't trigger hover popover if mouse is hovering over context menu
|
||||
// if text_bounds.contains_point(position) {
|
||||
// let point_for_position = position_map.point_for_position(text_bounds, position);
|
||||
// match point_for_position.as_valid() {
|
||||
// Some(point) => {
|
||||
// update_go_to_definition_link(
|
||||
// editor,
|
||||
// Some(GoToDefinitionTrigger::Text(point)),
|
||||
// cmd,
|
||||
// shift,
|
||||
// cx,
|
||||
// );
|
||||
// hover_at(editor, Some(point), cx);
|
||||
// }
|
||||
// None => {
|
||||
// update_inlay_link_and_hover_points(
|
||||
// &position_map.snapshot,
|
||||
// point_for_position,
|
||||
// editor,
|
||||
// cmd,
|
||||
// shift,
|
||||
// cx,
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// update_go_to_definition_link(editor, None, cmd, shift, cx);
|
||||
// hover_at(editor, None, cx);
|
||||
// }
|
||||
|
||||
// true
|
||||
// }
|
||||
true
|
||||
} else {
|
||||
update_go_to_definition_link(editor, None, modifiers.command, modifiers.shift, cx);
|
||||
hover_at(editor, None, cx);
|
||||
gutter_hovered
|
||||
}
|
||||
}
|
||||
|
||||
fn scroll(
|
||||
editor: &mut Editor,
|
||||
|
@ -2336,6 +2169,79 @@ impl EditorElement {
|
|||
// blocks,
|
||||
// )
|
||||
// }
|
||||
|
||||
fn paint_mouse_listeners(
|
||||
&mut self,
|
||||
bounds: Bounds<Pixels>,
|
||||
gutter_bounds: Bounds<Pixels>,
|
||||
text_bounds: Bounds<Pixels>,
|
||||
position_map: &Arc<PositionMap>,
|
||||
cx: &mut ViewContext<Editor>,
|
||||
) {
|
||||
cx.on_mouse_event({
|
||||
let position_map = position_map.clone();
|
||||
move |editor, event: &ScrollWheelEvent, phase, cx| {
|
||||
if phase != DispatchPhase::Bubble {
|
||||
return;
|
||||
}
|
||||
|
||||
if Self::scroll(editor, event, &position_map, bounds, cx) {
|
||||
cx.stop_propagation();
|
||||
}
|
||||
}
|
||||
});
|
||||
cx.on_mouse_event({
|
||||
let position_map = position_map.clone();
|
||||
move |editor, event: &MouseDownEvent, phase, cx| {
|
||||
if phase != DispatchPhase::Bubble {
|
||||
return;
|
||||
}
|
||||
|
||||
if Self::mouse_down(editor, event, &position_map, text_bounds, gutter_bounds, cx) {
|
||||
cx.stop_propagation()
|
||||
}
|
||||
}
|
||||
});
|
||||
cx.on_mouse_event({
|
||||
let position_map = position_map.clone();
|
||||
move |editor, event: &MouseUpEvent, phase, cx| {
|
||||
if phase != DispatchPhase::Bubble {
|
||||
return;
|
||||
}
|
||||
|
||||
if Self::mouse_up(editor, event, &position_map, text_bounds, cx) {
|
||||
cx.stop_propagation()
|
||||
}
|
||||
}
|
||||
});
|
||||
// todo!()
|
||||
// on_down(MouseButton::Right, {
|
||||
// let position_map = position_map.clone();
|
||||
// move |event, editor, cx| {
|
||||
// if !Self::mouse_right_down(
|
||||
// editor,
|
||||
// event.position,
|
||||
// position_map.as_ref(),
|
||||
// text_bounds,
|
||||
// cx,
|
||||
// ) {
|
||||
// cx.propagate_event();
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
cx.on_mouse_event({
|
||||
let position_map = position_map.clone();
|
||||
move |editor, event: &MouseMoveEvent, phase, cx| {
|
||||
if phase != DispatchPhase::Bubble {
|
||||
return;
|
||||
}
|
||||
|
||||
if Self::mouse_moved(editor, event, &position_map, text_bounds, gutter_bounds, cx) {
|
||||
cx.stop_propagation()
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -2555,30 +2461,9 @@ impl Element<Editor> for EditorElement {
|
|||
let dispatch_context = editor.dispatch_context(cx);
|
||||
cx.with_element_id(cx.view().entity_id(), |global_id, cx| {
|
||||
cx.with_key_dispatch_context(dispatch_context, |cx| {
|
||||
cx.with_key_listeners(
|
||||
[
|
||||
build_action_listener(Editor::move_left),
|
||||
build_action_listener(Editor::move_right),
|
||||
build_action_listener(Editor::move_down),
|
||||
build_action_listener(Editor::move_up),
|
||||
build_key_listener(
|
||||
move |editor, key_down: &KeyDownEvent, dispatch_context, phase, cx| {
|
||||
if phase == DispatchPhase::Bubble {
|
||||
if let KeyMatch::Some(action) = cx.match_keystroke(
|
||||
&global_id,
|
||||
&key_down.keystroke,
|
||||
dispatch_context,
|
||||
) {
|
||||
return Some(action);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
},
|
||||
),
|
||||
],
|
||||
|cx| cx.with_focus(editor.focus_handle.clone(), |_| {}),
|
||||
);
|
||||
cx.with_key_listeners(build_key_listeners(global_id), |cx| {
|
||||
cx.with_focus(editor.focus_handle.clone(), |_| {})
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
@ -2608,34 +2493,27 @@ impl Element<Editor> for EditorElement {
|
|||
cx: &mut gpui::ViewContext<Editor>,
|
||||
) {
|
||||
let layout = self.compute_layout(editor, cx, bounds);
|
||||
|
||||
cx.on_mouse_event({
|
||||
let position_map = layout.position_map.clone();
|
||||
move |editor, event: &ScrollWheelEvent, phase, cx| {
|
||||
if phase != DispatchPhase::Bubble {
|
||||
return;
|
||||
}
|
||||
|
||||
if Self::scroll(editor, event, &position_map, bounds, cx) {
|
||||
cx.stop_propagation();
|
||||
}
|
||||
}
|
||||
});
|
||||
let gutter_bounds = Bounds {
|
||||
origin: bounds.origin,
|
||||
size: layout.gutter_size,
|
||||
};
|
||||
let text_bounds = Bounds {
|
||||
origin: gutter_bounds.upper_right(),
|
||||
size: layout.text_size,
|
||||
};
|
||||
|
||||
if editor.focus_handle.is_focused(cx) {
|
||||
cx.handle_text_input();
|
||||
}
|
||||
|
||||
cx.with_content_mask(ContentMask { bounds }, |cx| {
|
||||
let gutter_bounds = Bounds {
|
||||
origin: bounds.origin,
|
||||
size: layout.gutter_size,
|
||||
};
|
||||
let text_bounds = Bounds {
|
||||
origin: gutter_bounds.upper_right(),
|
||||
size: layout.text_size,
|
||||
};
|
||||
|
||||
self.paint_mouse_listeners(
|
||||
bounds,
|
||||
gutter_bounds,
|
||||
text_bounds,
|
||||
&layout.position_map,
|
||||
cx,
|
||||
);
|
||||
self.paint_background(gutter_bounds, text_bounds, &layout, cx);
|
||||
if layout.gutter_size.width > Pixels::ZERO {
|
||||
self.paint_gutter(gutter_bounds, &layout, editor, cx);
|
||||
|
@ -3664,12 +3542,12 @@ impl HighlightedRange {
|
|||
// bounds.into_iter()
|
||||
// }
|
||||
|
||||
pub fn scale_vertical_mouse_autoscroll_delta(delta: f32) -> f32 {
|
||||
delta.powf(1.5) / 100.0
|
||||
pub fn scale_vertical_mouse_autoscroll_delta(delta: Pixels) -> f32 {
|
||||
(delta.pow(1.5) / 100.0).into()
|
||||
}
|
||||
|
||||
fn scale_horizontal_mouse_autoscroll_delta(delta: f32) -> f32 {
|
||||
delta.powf(1.2) / 300.0
|
||||
fn scale_horizontal_mouse_autoscroll_delta(delta: Pixels) -> f32 {
|
||||
(delta.pow(1.2) / 300.0).into()
|
||||
}
|
||||
|
||||
// #[cfg(test)]
|
||||
|
@ -4115,6 +3993,178 @@ fn scale_horizontal_mouse_autoscroll_delta(delta: f32) -> f32 {
|
|||
// }
|
||||
// }
|
||||
|
||||
fn build_key_listeners(
|
||||
global_element_id: GlobalElementId,
|
||||
) -> impl IntoIterator<Item = (TypeId, KeyListener<Editor>)> {
|
||||
[
|
||||
build_action_listener(Editor::move_left),
|
||||
build_action_listener(Editor::move_right),
|
||||
build_action_listener(Editor::move_down),
|
||||
build_action_listener(Editor::move_up),
|
||||
// build_action_listener(Editor::new_file), todo!()
|
||||
// build_action_listener(Editor::new_file_in_direction), todo!()
|
||||
build_action_listener(Editor::cancel),
|
||||
build_action_listener(Editor::newline),
|
||||
build_action_listener(Editor::newline_above),
|
||||
build_action_listener(Editor::newline_below),
|
||||
build_action_listener(Editor::backspace),
|
||||
build_action_listener(Editor::delete),
|
||||
build_action_listener(Editor::tab),
|
||||
build_action_listener(Editor::tab_prev),
|
||||
build_action_listener(Editor::indent),
|
||||
build_action_listener(Editor::outdent),
|
||||
build_action_listener(Editor::delete_line),
|
||||
build_action_listener(Editor::join_lines),
|
||||
build_action_listener(Editor::sort_lines_case_sensitive),
|
||||
build_action_listener(Editor::sort_lines_case_insensitive),
|
||||
build_action_listener(Editor::reverse_lines),
|
||||
build_action_listener(Editor::shuffle_lines),
|
||||
build_action_listener(Editor::convert_to_upper_case),
|
||||
build_action_listener(Editor::convert_to_lower_case),
|
||||
build_action_listener(Editor::convert_to_title_case),
|
||||
build_action_listener(Editor::convert_to_snake_case),
|
||||
build_action_listener(Editor::convert_to_kebab_case),
|
||||
build_action_listener(Editor::convert_to_upper_camel_case),
|
||||
build_action_listener(Editor::convert_to_lower_camel_case),
|
||||
build_action_listener(Editor::delete_to_previous_word_start),
|
||||
build_action_listener(Editor::delete_to_previous_subword_start),
|
||||
build_action_listener(Editor::delete_to_next_word_end),
|
||||
build_action_listener(Editor::delete_to_next_subword_end),
|
||||
build_action_listener(Editor::delete_to_beginning_of_line),
|
||||
build_action_listener(Editor::delete_to_end_of_line),
|
||||
build_action_listener(Editor::cut_to_end_of_line),
|
||||
build_action_listener(Editor::duplicate_line),
|
||||
build_action_listener(Editor::move_line_up),
|
||||
build_action_listener(Editor::move_line_down),
|
||||
build_action_listener(Editor::transpose),
|
||||
build_action_listener(Editor::cut),
|
||||
build_action_listener(Editor::copy),
|
||||
build_action_listener(Editor::paste),
|
||||
build_action_listener(Editor::undo),
|
||||
build_action_listener(Editor::redo),
|
||||
build_action_listener(Editor::move_page_up),
|
||||
build_action_listener(Editor::move_page_down),
|
||||
build_action_listener(Editor::next_screen),
|
||||
build_action_listener(Editor::scroll_cursor_top),
|
||||
build_action_listener(Editor::scroll_cursor_center),
|
||||
build_action_listener(Editor::scroll_cursor_bottom),
|
||||
build_action_listener(|editor, _: &LineDown, cx| {
|
||||
editor.scroll_screen(&ScrollAmount::Line(1.), cx)
|
||||
}),
|
||||
build_action_listener(|editor, _: &LineUp, cx| {
|
||||
editor.scroll_screen(&ScrollAmount::Line(-1.), cx)
|
||||
}),
|
||||
build_action_listener(|editor, _: &HalfPageDown, cx| {
|
||||
editor.scroll_screen(&ScrollAmount::Page(0.5), cx)
|
||||
}),
|
||||
build_action_listener(|editor, _: &HalfPageUp, cx| {
|
||||
editor.scroll_screen(&ScrollAmount::Page(-0.5), cx)
|
||||
}),
|
||||
build_action_listener(|editor, _: &PageDown, cx| {
|
||||
editor.scroll_screen(&ScrollAmount::Page(1.), cx)
|
||||
}),
|
||||
build_action_listener(|editor, _: &PageUp, cx| {
|
||||
editor.scroll_screen(&ScrollAmount::Page(-1.), cx)
|
||||
}),
|
||||
build_action_listener(Editor::move_to_previous_word_start),
|
||||
build_action_listener(Editor::move_to_previous_subword_start),
|
||||
build_action_listener(Editor::move_to_next_word_end),
|
||||
build_action_listener(Editor::move_to_next_subword_end),
|
||||
build_action_listener(Editor::move_to_beginning_of_line),
|
||||
build_action_listener(Editor::move_to_end_of_line),
|
||||
build_action_listener(Editor::move_to_start_of_paragraph),
|
||||
build_action_listener(Editor::move_to_end_of_paragraph),
|
||||
build_action_listener(Editor::move_to_beginning),
|
||||
build_action_listener(Editor::move_to_end),
|
||||
build_action_listener(Editor::select_up),
|
||||
build_action_listener(Editor::select_down),
|
||||
build_action_listener(Editor::select_left),
|
||||
build_action_listener(Editor::select_right),
|
||||
build_action_listener(Editor::select_to_previous_word_start),
|
||||
build_action_listener(Editor::select_to_previous_subword_start),
|
||||
build_action_listener(Editor::select_to_next_word_end),
|
||||
build_action_listener(Editor::select_to_next_subword_end),
|
||||
build_action_listener(Editor::select_to_beginning_of_line),
|
||||
build_action_listener(Editor::select_to_end_of_line),
|
||||
build_action_listener(Editor::select_to_start_of_paragraph),
|
||||
build_action_listener(Editor::select_to_end_of_paragraph),
|
||||
build_action_listener(Editor::select_to_beginning),
|
||||
build_action_listener(Editor::select_to_end),
|
||||
build_action_listener(Editor::select_all),
|
||||
build_action_listener(|editor, action, cx| {
|
||||
editor.select_all_matches(action, cx).log_err();
|
||||
}),
|
||||
build_action_listener(Editor::select_line),
|
||||
build_action_listener(Editor::split_selection_into_lines),
|
||||
build_action_listener(Editor::add_selection_above),
|
||||
build_action_listener(Editor::add_selection_below),
|
||||
build_action_listener(|editor, action, cx| {
|
||||
editor.select_next(action, cx).log_err();
|
||||
}),
|
||||
build_action_listener(|editor, action, cx| {
|
||||
editor.select_previous(action, cx).log_err();
|
||||
}),
|
||||
build_action_listener(Editor::toggle_comments),
|
||||
build_action_listener(Editor::select_larger_syntax_node),
|
||||
build_action_listener(Editor::select_smaller_syntax_node),
|
||||
build_action_listener(Editor::move_to_enclosing_bracket),
|
||||
build_action_listener(Editor::undo_selection),
|
||||
build_action_listener(Editor::redo_selection),
|
||||
build_action_listener(Editor::go_to_diagnostic),
|
||||
build_action_listener(Editor::go_to_prev_diagnostic),
|
||||
build_action_listener(Editor::go_to_hunk),
|
||||
build_action_listener(Editor::go_to_prev_hunk),
|
||||
build_action_listener(Editor::go_to_definition),
|
||||
build_action_listener(Editor::go_to_definition_split),
|
||||
build_action_listener(Editor::go_to_type_definition),
|
||||
build_action_listener(Editor::go_to_type_definition_split),
|
||||
build_action_listener(Editor::fold),
|
||||
build_action_listener(Editor::fold_at),
|
||||
build_action_listener(Editor::unfold_lines),
|
||||
build_action_listener(Editor::unfold_at),
|
||||
build_action_listener(Editor::fold_selected_ranges),
|
||||
build_action_listener(Editor::show_completions),
|
||||
// build_action_listener(Editor::toggle_code_actions), todo!()
|
||||
// build_action_listener(Editor::open_excerpts), todo!()
|
||||
build_action_listener(Editor::toggle_soft_wrap),
|
||||
build_action_listener(Editor::toggle_inlay_hints),
|
||||
build_action_listener(Editor::reveal_in_finder),
|
||||
build_action_listener(Editor::copy_path),
|
||||
build_action_listener(Editor::copy_relative_path),
|
||||
build_action_listener(Editor::copy_highlight_json),
|
||||
build_action_listener(|editor, action, cx| {
|
||||
editor
|
||||
.format(action, cx)
|
||||
.map(|task| task.detach_and_log_err(cx));
|
||||
}),
|
||||
build_action_listener(Editor::restart_language_server),
|
||||
build_action_listener(Editor::show_character_palette),
|
||||
// build_action_listener(Editor::confirm_completion), todo!()
|
||||
// build_action_listener(Editor::confirm_code_action), todo!()
|
||||
// build_action_listener(Editor::rename), todo!()
|
||||
// build_action_listener(Editor::confirm_rename), todo!()
|
||||
// build_action_listener(Editor::find_all_references), todo!()
|
||||
build_action_listener(Editor::next_copilot_suggestion),
|
||||
build_action_listener(Editor::previous_copilot_suggestion),
|
||||
build_action_listener(Editor::copilot_suggest),
|
||||
build_key_listener(
|
||||
move |editor, key_down: &KeyDownEvent, dispatch_context, phase, cx| {
|
||||
if phase == DispatchPhase::Bubble {
|
||||
if let KeyMatch::Some(action) = cx.match_keystroke(
|
||||
&global_element_id,
|
||||
&key_down.keystroke,
|
||||
dispatch_context,
|
||||
) {
|
||||
return Some(action);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
},
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
fn build_key_listener<T: 'static>(
|
||||
listener: impl Fn(
|
||||
&mut Editor,
|
||||
|
|
|
@ -144,8 +144,7 @@ pub fn hide_hover(editor: &mut Editor, cx: &mut ViewContext<Editor>) -> bool {
|
|||
editor.hover_state.info_task = None;
|
||||
editor.hover_state.triggered_from = None;
|
||||
|
||||
// todo!()
|
||||
// editor.clear_background_highlights::<HoverState>(cx);
|
||||
editor.clear_background_highlights::<HoverState>(cx);
|
||||
|
||||
if did_hide {
|
||||
cx.notify();
|
||||
|
@ -325,23 +324,22 @@ fn show_hover(
|
|||
};
|
||||
|
||||
this.update(&mut cx, |this, cx| {
|
||||
todo!();
|
||||
// if let Some(symbol_range) = hover_popover
|
||||
// .as_ref()
|
||||
// .and_then(|hover_popover| hover_popover.symbol_range.as_text_range())
|
||||
// {
|
||||
// // Highlight the selected symbol using a background highlight
|
||||
// this.highlight_background::<HoverState>(
|
||||
// vec![symbol_range],
|
||||
// |theme| theme.editor.hover_popover.highlight,
|
||||
// cx,
|
||||
// );
|
||||
// } else {
|
||||
// this.clear_background_highlights::<HoverState>(cx);
|
||||
// }
|
||||
//
|
||||
// this.hover_state.info_popover = hover_popover;
|
||||
// cx.notify();
|
||||
if let Some(symbol_range) = hover_popover
|
||||
.as_ref()
|
||||
.and_then(|hover_popover| hover_popover.symbol_range.as_text_range())
|
||||
{
|
||||
// Highlight the selected symbol using a background highlight
|
||||
this.highlight_background::<HoverState>(
|
||||
vec![symbol_range],
|
||||
|theme| theme.element_hover, // todo! update theme
|
||||
cx,
|
||||
);
|
||||
} else {
|
||||
this.clear_background_highlights::<HoverState>(cx);
|
||||
}
|
||||
|
||||
this.hover_state.info_popover = hover_popover;
|
||||
cx.notify();
|
||||
})?;
|
||||
|
||||
Ok::<_, anyhow::Error>(())
|
||||
|
|
|
@ -171,173 +171,170 @@ pub fn update_inlay_link_and_hover_points(
|
|||
shift_held: bool,
|
||||
cx: &mut ViewContext<'_, Editor>,
|
||||
) {
|
||||
todo!("old implementation below")
|
||||
}
|
||||
// ) {
|
||||
// let hovered_offset = if point_for_position.column_overshoot_after_line_end == 0 {
|
||||
// Some(snapshot.display_point_to_inlay_offset(point_for_position.exact_unclipped, Bias::Left))
|
||||
// } else {
|
||||
// None
|
||||
// };
|
||||
// let mut go_to_definition_updated = false;
|
||||
// let mut hover_updated = false;
|
||||
// if let Some(hovered_offset) = hovered_offset {
|
||||
// let buffer_snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
// let previous_valid_anchor = buffer_snapshot.anchor_at(
|
||||
// point_for_position.previous_valid.to_point(snapshot),
|
||||
// Bias::Left,
|
||||
// );
|
||||
// let next_valid_anchor = buffer_snapshot.anchor_at(
|
||||
// point_for_position.next_valid.to_point(snapshot),
|
||||
// Bias::Right,
|
||||
// );
|
||||
// if let Some(hovered_hint) = editor
|
||||
// .visible_inlay_hints(cx)
|
||||
// .into_iter()
|
||||
// .skip_while(|hint| {
|
||||
// hint.position
|
||||
// .cmp(&previous_valid_anchor, &buffer_snapshot)
|
||||
// .is_lt()
|
||||
// })
|
||||
// .take_while(|hint| {
|
||||
// hint.position
|
||||
// .cmp(&next_valid_anchor, &buffer_snapshot)
|
||||
// .is_le()
|
||||
// })
|
||||
// .max_by_key(|hint| hint.id)
|
||||
// {
|
||||
// let inlay_hint_cache = editor.inlay_hint_cache();
|
||||
// let excerpt_id = previous_valid_anchor.excerpt_id;
|
||||
// if let Some(cached_hint) = inlay_hint_cache.hint_by_id(excerpt_id, hovered_hint.id) {
|
||||
// match cached_hint.resolve_state {
|
||||
// ResolveState::CanResolve(_, _) => {
|
||||
// if let Some(buffer_id) = previous_valid_anchor.buffer_id {
|
||||
// inlay_hint_cache.spawn_hint_resolve(
|
||||
// buffer_id,
|
||||
// excerpt_id,
|
||||
// hovered_hint.id,
|
||||
// cx,
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// ResolveState::Resolved => {
|
||||
// let mut extra_shift_left = 0;
|
||||
// let mut extra_shift_right = 0;
|
||||
// if cached_hint.padding_left {
|
||||
// extra_shift_left += 1;
|
||||
// extra_shift_right += 1;
|
||||
// }
|
||||
// if cached_hint.padding_right {
|
||||
// extra_shift_right += 1;
|
||||
// }
|
||||
// match cached_hint.label {
|
||||
// project::InlayHintLabel::String(_) => {
|
||||
// if let Some(tooltip) = cached_hint.tooltip {
|
||||
// hover_popover::hover_at_inlay(
|
||||
// editor,
|
||||
// InlayHover {
|
||||
// excerpt: excerpt_id,
|
||||
// tooltip: match tooltip {
|
||||
// InlayHintTooltip::String(text) => HoverBlock {
|
||||
// text,
|
||||
// kind: HoverBlockKind::PlainText,
|
||||
// },
|
||||
// InlayHintTooltip::MarkupContent(content) => {
|
||||
// HoverBlock {
|
||||
// text: content.value,
|
||||
// kind: content.kind,
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// range: InlayHighlight {
|
||||
// inlay: hovered_hint.id,
|
||||
// inlay_position: hovered_hint.position,
|
||||
// range: extra_shift_left
|
||||
// ..hovered_hint.text.len() + extra_shift_right,
|
||||
// },
|
||||
// },
|
||||
// cx,
|
||||
// );
|
||||
// hover_updated = true;
|
||||
// }
|
||||
// }
|
||||
// project::InlayHintLabel::LabelParts(label_parts) => {
|
||||
// let hint_start =
|
||||
// snapshot.anchor_to_inlay_offset(hovered_hint.position);
|
||||
// if let Some((hovered_hint_part, part_range)) =
|
||||
// hover_popover::find_hovered_hint_part(
|
||||
// label_parts,
|
||||
// hint_start,
|
||||
// hovered_offset,
|
||||
// )
|
||||
// {
|
||||
// let highlight_start =
|
||||
// (part_range.start - hint_start).0 + extra_shift_left;
|
||||
// let highlight_end =
|
||||
// (part_range.end - hint_start).0 + extra_shift_right;
|
||||
// let highlight = InlayHighlight {
|
||||
// inlay: hovered_hint.id,
|
||||
// inlay_position: hovered_hint.position,
|
||||
// range: highlight_start..highlight_end,
|
||||
// };
|
||||
// if let Some(tooltip) = hovered_hint_part.tooltip {
|
||||
// hover_popover::hover_at_inlay(
|
||||
// editor,
|
||||
// InlayHover {
|
||||
// excerpt: excerpt_id,
|
||||
// tooltip: match tooltip {
|
||||
// InlayHintLabelPartTooltip::String(text) => {
|
||||
// HoverBlock {
|
||||
// text,
|
||||
// kind: HoverBlockKind::PlainText,
|
||||
// }
|
||||
// }
|
||||
// InlayHintLabelPartTooltip::MarkupContent(
|
||||
// content,
|
||||
// ) => HoverBlock {
|
||||
// text: content.value,
|
||||
// kind: content.kind,
|
||||
// },
|
||||
// },
|
||||
// range: highlight.clone(),
|
||||
// },
|
||||
// cx,
|
||||
// );
|
||||
// hover_updated = true;
|
||||
// }
|
||||
// if let Some((language_server_id, location)) =
|
||||
// hovered_hint_part.location
|
||||
// {
|
||||
// go_to_definition_updated = true;
|
||||
// update_go_to_definition_link(
|
||||
// editor,
|
||||
// Some(GoToDefinitionTrigger::InlayHint(
|
||||
// highlight,
|
||||
// location,
|
||||
// language_server_id,
|
||||
// )),
|
||||
// cmd_held,
|
||||
// shift_held,
|
||||
// cx,
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
// ResolveState::Resolving => {}
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
let hovered_offset = if point_for_position.column_overshoot_after_line_end == 0 {
|
||||
Some(snapshot.display_point_to_inlay_offset(point_for_position.exact_unclipped, Bias::Left))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let mut go_to_definition_updated = false;
|
||||
let mut hover_updated = false;
|
||||
if let Some(hovered_offset) = hovered_offset {
|
||||
let buffer_snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
let previous_valid_anchor = buffer_snapshot.anchor_at(
|
||||
point_for_position.previous_valid.to_point(snapshot),
|
||||
Bias::Left,
|
||||
);
|
||||
let next_valid_anchor = buffer_snapshot.anchor_at(
|
||||
point_for_position.next_valid.to_point(snapshot),
|
||||
Bias::Right,
|
||||
);
|
||||
if let Some(hovered_hint) = editor
|
||||
.visible_inlay_hints(cx)
|
||||
.into_iter()
|
||||
.skip_while(|hint| {
|
||||
hint.position
|
||||
.cmp(&previous_valid_anchor, &buffer_snapshot)
|
||||
.is_lt()
|
||||
})
|
||||
.take_while(|hint| {
|
||||
hint.position
|
||||
.cmp(&next_valid_anchor, &buffer_snapshot)
|
||||
.is_le()
|
||||
})
|
||||
.max_by_key(|hint| hint.id)
|
||||
{
|
||||
let inlay_hint_cache = editor.inlay_hint_cache();
|
||||
let excerpt_id = previous_valid_anchor.excerpt_id;
|
||||
if let Some(cached_hint) = inlay_hint_cache.hint_by_id(excerpt_id, hovered_hint.id) {
|
||||
match cached_hint.resolve_state {
|
||||
ResolveState::CanResolve(_, _) => {
|
||||
if let Some(buffer_id) = previous_valid_anchor.buffer_id {
|
||||
inlay_hint_cache.spawn_hint_resolve(
|
||||
buffer_id,
|
||||
excerpt_id,
|
||||
hovered_hint.id,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
}
|
||||
ResolveState::Resolved => {
|
||||
let mut extra_shift_left = 0;
|
||||
let mut extra_shift_right = 0;
|
||||
if cached_hint.padding_left {
|
||||
extra_shift_left += 1;
|
||||
extra_shift_right += 1;
|
||||
}
|
||||
if cached_hint.padding_right {
|
||||
extra_shift_right += 1;
|
||||
}
|
||||
match cached_hint.label {
|
||||
project::InlayHintLabel::String(_) => {
|
||||
if let Some(tooltip) = cached_hint.tooltip {
|
||||
hover_popover::hover_at_inlay(
|
||||
editor,
|
||||
InlayHover {
|
||||
excerpt: excerpt_id,
|
||||
tooltip: match tooltip {
|
||||
InlayHintTooltip::String(text) => HoverBlock {
|
||||
text,
|
||||
kind: HoverBlockKind::PlainText,
|
||||
},
|
||||
InlayHintTooltip::MarkupContent(content) => {
|
||||
HoverBlock {
|
||||
text: content.value,
|
||||
kind: content.kind,
|
||||
}
|
||||
}
|
||||
},
|
||||
range: InlayHighlight {
|
||||
inlay: hovered_hint.id,
|
||||
inlay_position: hovered_hint.position,
|
||||
range: extra_shift_left
|
||||
..hovered_hint.text.len() + extra_shift_right,
|
||||
},
|
||||
},
|
||||
cx,
|
||||
);
|
||||
hover_updated = true;
|
||||
}
|
||||
}
|
||||
project::InlayHintLabel::LabelParts(label_parts) => {
|
||||
let hint_start =
|
||||
snapshot.anchor_to_inlay_offset(hovered_hint.position);
|
||||
if let Some((hovered_hint_part, part_range)) =
|
||||
hover_popover::find_hovered_hint_part(
|
||||
label_parts,
|
||||
hint_start,
|
||||
hovered_offset,
|
||||
)
|
||||
{
|
||||
let highlight_start =
|
||||
(part_range.start - hint_start).0 + extra_shift_left;
|
||||
let highlight_end =
|
||||
(part_range.end - hint_start).0 + extra_shift_right;
|
||||
let highlight = InlayHighlight {
|
||||
inlay: hovered_hint.id,
|
||||
inlay_position: hovered_hint.position,
|
||||
range: highlight_start..highlight_end,
|
||||
};
|
||||
if let Some(tooltip) = hovered_hint_part.tooltip {
|
||||
hover_popover::hover_at_inlay(
|
||||
editor,
|
||||
InlayHover {
|
||||
excerpt: excerpt_id,
|
||||
tooltip: match tooltip {
|
||||
InlayHintLabelPartTooltip::String(text) => {
|
||||
HoverBlock {
|
||||
text,
|
||||
kind: HoverBlockKind::PlainText,
|
||||
}
|
||||
}
|
||||
InlayHintLabelPartTooltip::MarkupContent(
|
||||
content,
|
||||
) => HoverBlock {
|
||||
text: content.value,
|
||||
kind: content.kind,
|
||||
},
|
||||
},
|
||||
range: highlight.clone(),
|
||||
},
|
||||
cx,
|
||||
);
|
||||
hover_updated = true;
|
||||
}
|
||||
if let Some((language_server_id, location)) =
|
||||
hovered_hint_part.location
|
||||
{
|
||||
go_to_definition_updated = true;
|
||||
update_go_to_definition_link(
|
||||
editor,
|
||||
Some(GoToDefinitionTrigger::InlayHint(
|
||||
highlight,
|
||||
location,
|
||||
language_server_id,
|
||||
)),
|
||||
cmd_held,
|
||||
shift_held,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
ResolveState::Resolving => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if !go_to_definition_updated {
|
||||
// update_go_to_definition_link(editor, None, cmd_held, shift_held, cx);
|
||||
// }
|
||||
// if !hover_updated {
|
||||
// hover_popover::hover_at(editor, None, cx);
|
||||
// }
|
||||
// }
|
||||
if !go_to_definition_updated {
|
||||
update_go_to_definition_link(editor, None, cmd_held, shift_held, cx);
|
||||
}
|
||||
if !hover_updated {
|
||||
hover_popover::hover_at(editor, None, cx);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum LinkDefinitionKind {
|
||||
|
|
|
@ -288,16 +288,15 @@ impl ScrollManager {
|
|||
}
|
||||
}
|
||||
|
||||
// todo!()
|
||||
impl Editor {
|
||||
// pub fn vertical_scroll_margin(&mut self) -> usize {
|
||||
// self.scroll_manager.vertical_scroll_margin as usize
|
||||
// }
|
||||
pub fn vertical_scroll_margin(&mut self) -> usize {
|
||||
self.scroll_manager.vertical_scroll_margin as usize
|
||||
}
|
||||
|
||||
// pub fn set_vertical_scroll_margin(&mut self, margin_rows: usize, cx: &mut ViewContext<Self>) {
|
||||
// self.scroll_manager.vertical_scroll_margin = margin_rows as f32;
|
||||
// cx.notify();
|
||||
// }
|
||||
pub fn set_vertical_scroll_margin(&mut self, margin_rows: usize, cx: &mut ViewContext<Self>) {
|
||||
self.scroll_manager.vertical_scroll_margin = margin_rows as f32;
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn visible_line_count(&self) -> Option<f32> {
|
||||
self.scroll_manager.visible_line_count
|
||||
|
@ -349,11 +348,9 @@ impl Editor {
|
|||
self.refresh_inlay_hints(InlayHintRefreshReason::NewLinesShown, cx);
|
||||
}
|
||||
|
||||
pub fn scroll_position(&self, cx: &mut ViewContext<Self>) -> gpui::Point<Pixels> {
|
||||
pub fn scroll_position(&self, cx: &mut ViewContext<Self>) -> gpui::Point<f32> {
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
// todo!() Should `self.scroll_manager.anchor.scroll_position()` return `Pixels`?
|
||||
// self.scroll_manager.anchor.scroll_position(&display_map)
|
||||
todo!()
|
||||
self.scroll_manager.anchor.scroll_position(&display_map)
|
||||
}
|
||||
|
||||
pub fn set_scroll_anchor(&mut self, scroll_anchor: ScrollAnchor, cx: &mut ViewContext<Self>) {
|
||||
|
@ -382,50 +379,50 @@ impl Editor {
|
|||
.set_anchor(scroll_anchor, top_row, false, false, workspace_id, cx);
|
||||
}
|
||||
|
||||
// pub fn scroll_screen(&mut self, amount: &ScrollAmount, cx: &mut ViewContext<Self>) {
|
||||
// if matches!(self.mode, EditorMode::SingleLine) {
|
||||
// cx.propagate_action();
|
||||
// return;
|
||||
// }
|
||||
pub fn scroll_screen(&mut self, amount: &ScrollAmount, cx: &mut ViewContext<Self>) {
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
||||
// if self.take_rename(true, cx).is_some() {
|
||||
// return;
|
||||
// }
|
||||
if self.take_rename(true, cx).is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
// let cur_position = self.scroll_position(cx);
|
||||
// let new_pos = cur_position + point(0., amount.lines(self));
|
||||
// self.set_scroll_position(new_pos, cx);
|
||||
// }
|
||||
let cur_position = self.scroll_position(cx);
|
||||
let new_pos = cur_position + point(0., amount.lines(self));
|
||||
self.set_scroll_position(new_pos, cx);
|
||||
}
|
||||
|
||||
// /// Returns an ordering. The newest selection is:
|
||||
// /// Ordering::Equal => on screen
|
||||
// /// Ordering::Less => above the screen
|
||||
// /// Ordering::Greater => below the screen
|
||||
// pub fn newest_selection_on_screen(&self, cx: &mut AppContext) -> Ordering {
|
||||
// let snapshot = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
// let newest_head = self
|
||||
// .selections
|
||||
// .newest_anchor()
|
||||
// .head()
|
||||
// .to_display_point(&snapshot);
|
||||
// let screen_top = self
|
||||
// .scroll_manager
|
||||
// .anchor
|
||||
// .anchor
|
||||
// .to_display_point(&snapshot);
|
||||
/// Returns an ordering. The newest selection is:
|
||||
/// Ordering::Equal => on screen
|
||||
/// Ordering::Less => above the screen
|
||||
/// Ordering::Greater => below the screen
|
||||
pub fn newest_selection_on_screen(&self, cx: &mut AppContext) -> Ordering {
|
||||
let snapshot = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let newest_head = self
|
||||
.selections
|
||||
.newest_anchor()
|
||||
.head()
|
||||
.to_display_point(&snapshot);
|
||||
let screen_top = self
|
||||
.scroll_manager
|
||||
.anchor
|
||||
.anchor
|
||||
.to_display_point(&snapshot);
|
||||
|
||||
// if screen_top > newest_head {
|
||||
// return Ordering::Less;
|
||||
// }
|
||||
if screen_top > newest_head {
|
||||
return Ordering::Less;
|
||||
}
|
||||
|
||||
// if let Some(visible_lines) = self.visible_line_count() {
|
||||
// if newest_head.row() < screen_top.row() + visible_lines as u32 {
|
||||
// return Ordering::Equal;
|
||||
// }
|
||||
// }
|
||||
if let Some(visible_lines) = self.visible_line_count() {
|
||||
if newest_head.row() < screen_top.row() + visible_lines as u32 {
|
||||
return Ordering::Equal;
|
||||
}
|
||||
}
|
||||
|
||||
// Ordering::Greater
|
||||
// }
|
||||
Ordering::Greater
|
||||
}
|
||||
|
||||
pub fn read_scroll_position_from_db(
|
||||
&mut self,
|
||||
|
|
|
@ -1,66 +1,27 @@
|
|||
use super::Axis;
|
||||
use crate::Editor;
|
||||
use gpui::{AppContext, Point, ViewContext};
|
||||
|
||||
// actions!(
|
||||
// editor,
|
||||
// [
|
||||
// LineDown,
|
||||
// LineUp,
|
||||
// HalfPageDown,
|
||||
// HalfPageUp,
|
||||
// PageDown,
|
||||
// PageUp,
|
||||
// NextScreen,
|
||||
// ScrollCursorTop,
|
||||
// ScrollCursorCenter,
|
||||
// ScrollCursorBottom,
|
||||
// ]
|
||||
// );
|
||||
|
||||
pub fn init(cx: &mut AppContext) {
|
||||
// todo!()
|
||||
// cx.add_action(Editor::next_screen);
|
||||
// cx.add_action(Editor::scroll_cursor_top);
|
||||
// cx.add_action(Editor::scroll_cursor_center);
|
||||
// cx.add_action(Editor::scroll_cursor_bottom);
|
||||
// cx.add_action(|this: &mut Editor, _: &LineDown, cx| {
|
||||
// this.scroll_screen(&ScrollAmount::Line(1.), cx)
|
||||
// });
|
||||
// cx.add_action(|this: &mut Editor, _: &LineUp, cx| {
|
||||
// this.scroll_screen(&ScrollAmount::Line(-1.), cx)
|
||||
// });
|
||||
// cx.add_action(|this: &mut Editor, _: &HalfPageDown, cx| {
|
||||
// this.scroll_screen(&ScrollAmount::Page(0.5), cx)
|
||||
// });
|
||||
// cx.add_action(|this: &mut Editor, _: &HalfPageUp, cx| {
|
||||
// this.scroll_screen(&ScrollAmount::Page(-0.5), cx)
|
||||
// });
|
||||
// cx.add_action(|this: &mut Editor, _: &PageDown, cx| {
|
||||
// this.scroll_screen(&ScrollAmount::Page(1.), cx)
|
||||
// });
|
||||
// cx.add_action(|this: &mut Editor, _: &PageUp, cx| {
|
||||
// this.scroll_screen(&ScrollAmount::Page(-1.), cx)
|
||||
// });
|
||||
}
|
||||
use crate::{
|
||||
Autoscroll, Bias, Editor, EditorMode, NextScreen, ScrollAnchor, ScrollCursorBottom,
|
||||
ScrollCursorCenter, ScrollCursorTop,
|
||||
};
|
||||
use gpui::{actions, AppContext, Point, ViewContext};
|
||||
|
||||
impl Editor {
|
||||
// pub fn next_screen(&mut self, _: &NextScreen, cx: &mut ViewContext<Editor>) -> Option<()> {
|
||||
// if self.take_rename(true, cx).is_some() {
|
||||
// return None;
|
||||
// }
|
||||
pub fn next_screen(&mut self, _: &NextScreen, cx: &mut ViewContext<Editor>) {
|
||||
if self.take_rename(true, cx).is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
// if self.mouse_context_menu.read(cx).visible() {
|
||||
// return None;
|
||||
// }
|
||||
// todo!()
|
||||
// if self.mouse_context_menu.read(cx).visible() {
|
||||
// return None;
|
||||
// }
|
||||
|
||||
// if matches!(self.mode, EditorMode::SingleLine) {
|
||||
// cx.propagate_action();
|
||||
// return None;
|
||||
// }
|
||||
// self.request_autoscroll(Autoscroll::Next, cx);
|
||||
// Some(())
|
||||
// }
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
self.request_autoscroll(Autoscroll::Next, cx);
|
||||
}
|
||||
|
||||
pub fn scroll(
|
||||
&mut self,
|
||||
|
@ -72,79 +33,71 @@ impl Editor {
|
|||
self.set_scroll_position(scroll_position, cx);
|
||||
}
|
||||
|
||||
// fn scroll_cursor_top(editor: &mut Editor, _: &ScrollCursorTop, cx: &mut ViewContext<Editor>) {
|
||||
// let snapshot = editor.snapshot(cx).display_snapshot;
|
||||
// let scroll_margin_rows = editor.vertical_scroll_margin() as u32;
|
||||
pub fn scroll_cursor_top(&mut self, _: &ScrollCursorTop, cx: &mut ViewContext<Editor>) {
|
||||
let snapshot = self.snapshot(cx).display_snapshot;
|
||||
let scroll_margin_rows = self.vertical_scroll_margin() as u32;
|
||||
|
||||
// let mut new_screen_top = editor.selections.newest_display(cx).head();
|
||||
// *new_screen_top.row_mut() = new_screen_top.row().saturating_sub(scroll_margin_rows);
|
||||
// *new_screen_top.column_mut() = 0;
|
||||
// let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
|
||||
// let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
|
||||
let mut new_screen_top = self.selections.newest_display(cx).head();
|
||||
*new_screen_top.row_mut() = new_screen_top.row().saturating_sub(scroll_margin_rows);
|
||||
*new_screen_top.column_mut() = 0;
|
||||
let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
|
||||
let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
|
||||
|
||||
// editor.set_scroll_anchor(
|
||||
// ScrollAnchor {
|
||||
// anchor: new_anchor,
|
||||
// offset: Default::default(),
|
||||
// },
|
||||
// cx,
|
||||
// )
|
||||
// }
|
||||
self.set_scroll_anchor(
|
||||
ScrollAnchor {
|
||||
anchor: new_anchor,
|
||||
offset: Default::default(),
|
||||
},
|
||||
cx,
|
||||
)
|
||||
}
|
||||
|
||||
// fn scroll_cursor_center(
|
||||
// editor: &mut Editor,
|
||||
// _: &ScrollCursorCenter,
|
||||
// cx: &mut ViewContext<Editor>,
|
||||
// ) {
|
||||
// let snapshot = editor.snapshot(cx).display_snapshot;
|
||||
// let visible_rows = if let Some(visible_rows) = editor.visible_line_count() {
|
||||
// visible_rows as u32
|
||||
// } else {
|
||||
// return;
|
||||
// };
|
||||
pub fn scroll_cursor_center(&mut self, _: &ScrollCursorCenter, cx: &mut ViewContext<Editor>) {
|
||||
let snapshot = self.snapshot(cx).display_snapshot;
|
||||
let visible_rows = if let Some(visible_rows) = self.visible_line_count() {
|
||||
visible_rows as u32
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
|
||||
// let mut new_screen_top = editor.selections.newest_display(cx).head();
|
||||
// *new_screen_top.row_mut() = new_screen_top.row().saturating_sub(visible_rows / 2);
|
||||
// *new_screen_top.column_mut() = 0;
|
||||
// let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
|
||||
// let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
|
||||
let mut new_screen_top = self.selections.newest_display(cx).head();
|
||||
*new_screen_top.row_mut() = new_screen_top.row().saturating_sub(visible_rows / 2);
|
||||
*new_screen_top.column_mut() = 0;
|
||||
let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
|
||||
let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
|
||||
|
||||
// editor.set_scroll_anchor(
|
||||
// ScrollAnchor {
|
||||
// anchor: new_anchor,
|
||||
// offset: Default::default(),
|
||||
// },
|
||||
// cx,
|
||||
// )
|
||||
// }
|
||||
self.set_scroll_anchor(
|
||||
ScrollAnchor {
|
||||
anchor: new_anchor,
|
||||
offset: Default::default(),
|
||||
},
|
||||
cx,
|
||||
)
|
||||
}
|
||||
|
||||
// fn scroll_cursor_bottom(
|
||||
// editor: &mut Editor,
|
||||
// _: &ScrollCursorBottom,
|
||||
// cx: &mut ViewContext<Editor>,
|
||||
// ) {
|
||||
// let snapshot = editor.snapshot(cx).display_snapshot;
|
||||
// let scroll_margin_rows = editor.vertical_scroll_margin() as u32;
|
||||
// let visible_rows = if let Some(visible_rows) = editor.visible_line_count() {
|
||||
// visible_rows as u32
|
||||
// } else {
|
||||
// return;
|
||||
// };
|
||||
pub fn scroll_cursor_bottom(&mut self, _: &ScrollCursorBottom, cx: &mut ViewContext<Editor>) {
|
||||
let snapshot = self.snapshot(cx).display_snapshot;
|
||||
let scroll_margin_rows = self.vertical_scroll_margin() as u32;
|
||||
let visible_rows = if let Some(visible_rows) = self.visible_line_count() {
|
||||
visible_rows as u32
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
|
||||
// let mut new_screen_top = editor.selections.newest_display(cx).head();
|
||||
// *new_screen_top.row_mut() = new_screen_top
|
||||
// .row()
|
||||
// .saturating_sub(visible_rows.saturating_sub(scroll_margin_rows));
|
||||
// *new_screen_top.column_mut() = 0;
|
||||
// let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
|
||||
// let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
|
||||
let mut new_screen_top = self.selections.newest_display(cx).head();
|
||||
*new_screen_top.row_mut() = new_screen_top
|
||||
.row()
|
||||
.saturating_sub(visible_rows.saturating_sub(scroll_margin_rows));
|
||||
*new_screen_top.column_mut() = 0;
|
||||
let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
|
||||
let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
|
||||
|
||||
// editor.set_scroll_anchor(
|
||||
// ScrollAnchor {
|
||||
// anchor: new_anchor,
|
||||
// offset: Default::default(),
|
||||
// },
|
||||
// cx,
|
||||
// )
|
||||
// }
|
||||
self.set_scroll_anchor(
|
||||
ScrollAnchor {
|
||||
anchor: new_anchor,
|
||||
offset: Default::default(),
|
||||
},
|
||||
cx,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -302,39 +302,39 @@ impl SelectionsCollection {
|
|||
.collect()
|
||||
}
|
||||
|
||||
// pub fn build_columnar_selection(
|
||||
// &mut self,
|
||||
// display_map: &DisplaySnapshot,
|
||||
// row: u32,
|
||||
// positions: &Range<Pixels>,
|
||||
// reversed: bool,
|
||||
// text_layout_details: &TextLayoutDetails,
|
||||
// ) -> Option<Selection<Point>> {
|
||||
// let is_empty = positions.start == positions.end;
|
||||
// let line_len = display_map.line_len(row);
|
||||
pub fn build_columnar_selection(
|
||||
&mut self,
|
||||
display_map: &DisplaySnapshot,
|
||||
row: u32,
|
||||
positions: &Range<Pixels>,
|
||||
reversed: bool,
|
||||
text_layout_details: &TextLayoutDetails,
|
||||
) -> Option<Selection<Point>> {
|
||||
let is_empty = positions.start == positions.end;
|
||||
let line_len = display_map.line_len(row);
|
||||
|
||||
// let layed_out_line = display_map.lay_out_line_for_row(row, &text_layout_details);
|
||||
let layed_out_line = display_map.lay_out_line_for_row(row, &text_layout_details);
|
||||
|
||||
// let start_col = layed_out_line.closest_index_for_x(positions.start) as u32;
|
||||
// if start_col < line_len || (is_empty && positions.start == layed_out_line.width()) {
|
||||
// let start = DisplayPoint::new(row, start_col);
|
||||
// let end_col = layed_out_line.closest_index_for_x(positions.end) as u32;
|
||||
// let end = DisplayPoint::new(row, end_col);
|
||||
let start_col = layed_out_line.closest_index_for_x(positions.start) as u32;
|
||||
if start_col < line_len || (is_empty && positions.start == layed_out_line.width) {
|
||||
let start = DisplayPoint::new(row, start_col);
|
||||
let end_col = layed_out_line.closest_index_for_x(positions.end) as u32;
|
||||
let end = DisplayPoint::new(row, end_col);
|
||||
|
||||
// Some(Selection {
|
||||
// id: post_inc(&mut self.next_selection_id),
|
||||
// start: start.to_point(display_map),
|
||||
// end: end.to_point(display_map),
|
||||
// reversed,
|
||||
// goal: SelectionGoal::HorizontalRange {
|
||||
// start: positions.start,
|
||||
// end: positions.end,
|
||||
// },
|
||||
// })
|
||||
// } else {
|
||||
// None
|
||||
// }
|
||||
// }
|
||||
Some(Selection {
|
||||
id: post_inc(&mut self.next_selection_id),
|
||||
start: start.to_point(display_map),
|
||||
end: end.to_point(display_map),
|
||||
reversed,
|
||||
goal: SelectionGoal::HorizontalRange {
|
||||
start: positions.start.into(),
|
||||
end: positions.end.into(),
|
||||
},
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn change_with<R>(
|
||||
&mut self,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue