Skip to content

Commit

Permalink
Add action editor::OpenContextMenu
Browse files Browse the repository at this point in the history
  • Loading branch information
mgsloan committed Dec 3, 2024
1 parent afb253b commit ac9a83b
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 60 deletions.
4 changes: 3 additions & 1 deletion assets/keymaps/default-linux.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@
"ctrl-'": "editor::ToggleHunkDiff",
"ctrl-\"": "editor::ExpandAllHunkDiffs",
"ctrl-i": "editor::ShowSignatureHelp",
"alt-g b": "editor::ToggleGitBlame"
"alt-g b": "editor::ToggleGitBlame",
"menu": "editor::OpenContextMenu",
"shift-f10": "editor::OpenContextMenu"
}
},
{
Expand Down
1 change: 1 addition & 0 deletions crates/editor/src/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ gpui::actions!(
NewlineBelow,
NextInlineCompletion,
NextScreen,
OpenContextMenu,
OpenExcerpts,
OpenExcerptsSplit,
OpenProposedChangesEditor,
Expand Down
38 changes: 27 additions & 11 deletions crates/editor/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7576,6 +7576,12 @@ impl Editor {
.update(cx, |buffer, cx| buffer.group_until_transaction(tx_id, cx));
}

pub fn open_context_menu(&mut self, _: &OpenContextMenu, cx: &mut ViewContext<Self>) {
self.request_autoscroll(Autoscroll::newest(), cx);
let position = self.selections.newest_display(cx).end;
mouse_context_menu::deploy_context_menu(self, None, position, cx);
}

pub fn move_left(&mut self, _: &MoveLeft, cx: &mut ViewContext<Self>) {
self.change_selections(Some(Autoscroll::fit()), cx, |s| {
let line_mode = s.line_mode;
Expand Down Expand Up @@ -13266,6 +13272,23 @@ impl Editor {
.get(&type_id)
.and_then(|item| item.to_any().downcast_ref::<T>())
}

fn character_size(&self, cx: &mut ViewContext<Self>) -> gpui::Point<Pixels> {
let text_layout_details = self.text_layout_details(cx);
let style = &text_layout_details.editor_style;
let font_id = cx.text_system().resolve_font(&style.text.font());
let font_size = style.text.font_size.to_pixels(cx.rem_size());
let line_height = style.text.line_height_in_pixels(cx.rem_size());

let em_width = cx
.text_system()
.typographic_bounds(font_id, font_size, 'm')
.unwrap()
.size
.width;

gpui::Point::new(em_width, line_height)
}
}

fn char_len_with_expanded_tabs(offset: usize, text: &str, tab_size: NonZeroU32) -> usize {
Expand Down Expand Up @@ -14645,17 +14668,10 @@ impl ViewInputHandler for Editor {
cx: &mut ViewContext<Self>,
) -> Option<gpui::Bounds<Pixels>> {
let text_layout_details = self.text_layout_details(cx);
let style = &text_layout_details.editor_style;
let font_id = cx.text_system().resolve_font(&style.text.font());
let font_size = style.text.font_size.to_pixels(cx.rem_size());
let line_height = style.text.line_height_in_pixels(cx.rem_size());

let em_width = cx
.text_system()
.typographic_bounds(font_id, font_size, 'm')
.unwrap()
.size
.width;
let gpui::Point {
x: em_width,
y: line_height,
} = self.character_size(cx);

let snapshot = self.snapshot(cx);
let scroll_position = snapshot.scroll_position();
Expand Down
29 changes: 15 additions & 14 deletions crates/editor/src/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ impl EditorElement {

crate::rust_analyzer_ext::apply_related_actions(view, cx);
crate::clangd_ext::apply_related_actions(view, cx);
register_action(view, cx, Editor::open_context_menu);
register_action(view, cx, Editor::move_left);
register_action(view, cx, Editor::move_right);
register_action(view, cx, Editor::move_down);
Expand Down Expand Up @@ -594,7 +595,7 @@ impl EditorElement {
position_map.point_for_position(text_hitbox.bounds, event.position);
mouse_context_menu::deploy_context_menu(
editor,
event.position,
Some(event.position),
point_for_position.previous_valid,
cx,
);
Expand Down Expand Up @@ -2729,6 +2730,7 @@ impl EditorElement {
&self,
editor_snapshot: &EditorSnapshot,
visible_range: Range<DisplayRow>,
content_origin: gpui::Point<Pixels>,
cx: &mut WindowContext,
) -> Option<AnyElement> {
let position = self.editor.update(cx, |editor, cx| {
Expand All @@ -2746,16 +2748,11 @@ impl EditorElement {
let mouse_context_menu = editor.mouse_context_menu.as_ref()?;
let (source_display_point, position) = match mouse_context_menu.position {
MenuPosition::PinnedToScreen(point) => (None, point),
MenuPosition::PinnedToEditor {
source,
offset_x,
offset_y,
} => {
MenuPosition::PinnedToEditor { source, offset } => {
let source_display_point = source.to_display_point(editor_snapshot);
let mut source_point = editor.to_pixel_point(source, editor_snapshot, cx)?;
source_point.x += offset_x;
source_point.y += offset_y;
(Some(source_display_point), source_point)
let source_point = editor.to_pixel_point(source, editor_snapshot, cx)?;
let position = content_origin + source_point + offset;
(Some(source_display_point), position)
}
};

Expand Down Expand Up @@ -4330,8 +4327,8 @@ fn deploy_blame_entry_context_menu(
});

editor.update(cx, move |editor, cx| {
editor.mouse_context_menu = Some(MouseContextMenu::pinned_to_screen(
position,
editor.mouse_context_menu = Some(MouseContextMenu::new(
MenuPosition::PinnedToScreen(position),
context_menu,
cx,
));
Expand Down Expand Up @@ -5583,8 +5580,12 @@ impl Element for EditorElement {
);
}

let mouse_context_menu =
self.layout_mouse_context_menu(&snapshot, start_row..end_row, cx);
let mouse_context_menu = self.layout_mouse_context_menu(
&snapshot,
start_row..end_row,
content_origin,
cx,
);

cx.with_element_namespace("crease_toggles", |cx| {
self.prepaint_crease_toggles(
Expand Down
65 changes: 31 additions & 34 deletions crates/editor/src/mouse_context_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ pub enum MenuPosition {
/// Disappears when the position is no longer visible.
PinnedToEditor {
source: multi_buffer::Anchor,
offset_x: Pixels,
offset_y: Pixels,
offset: Point<Pixels>,
},
}

Expand All @@ -48,36 +47,22 @@ impl MouseContextMenu {
context_menu: View<ui::ContextMenu>,
cx: &mut ViewContext<Editor>,
) -> Option<Self> {
let context_menu_focus = context_menu.focus_handle(cx);
cx.focus(&context_menu_focus);

let _subscription = cx.subscribe(
&context_menu,
move |editor, _, _event: &DismissEvent, cx| {
editor.mouse_context_menu.take();
if context_menu_focus.contains_focused(cx) {
editor.focus(cx);
}
},
);

let editor_snapshot = editor.snapshot(cx);
let source_point = editor.to_pixel_point(source, &editor_snapshot, cx)?;
let offset = position - source_point;

Some(Self {
position: MenuPosition::PinnedToEditor {
source,
offset_x: offset.x,
offset_y: offset.y,
},
context_menu,
_subscription,
})
let content_origin = editor.last_bounds?.origin
+ Point {
x: editor.gutter_dimensions.width,
y: Pixels(0.0),
};
let source_position = editor.to_pixel_point(source, &editor_snapshot, cx)?;
let menu_position = MenuPosition::PinnedToEditor {
source,
offset: position - (source_position + content_origin),
};
return Some(MouseContextMenu::new(menu_position, context_menu, cx));
}

pub(crate) fn pinned_to_screen(
position: Point<Pixels>,
pub(crate) fn new(
position: MenuPosition,
context_menu: View<ui::ContextMenu>,
cx: &mut ViewContext<Editor>,
) -> Self {
Expand All @@ -95,7 +80,7 @@ impl MouseContextMenu {
);

Self {
position: MenuPosition::PinnedToScreen(position),
position,
context_menu,
_subscription,
}
Expand All @@ -119,7 +104,7 @@ fn display_ranges<'a>(

pub fn deploy_context_menu(
editor: &mut Editor,
position: Point<Pixels>,
position: Option<Point<Pixels>>,
point: DisplayPoint,
cx: &mut ViewContext<Editor>,
) {
Expand Down Expand Up @@ -213,8 +198,18 @@ pub fn deploy_context_menu(
})
};

editor.mouse_context_menu =
MouseContextMenu::pinned_to_editor(editor, source_anchor, position, context_menu, cx);
editor.mouse_context_menu = match position {
Some(position) => {
MouseContextMenu::pinned_to_editor(editor, source_anchor, position, context_menu, cx)
}
None => {
let menu_position = MenuPosition::PinnedToEditor {
source: source_anchor,
offset: editor.character_size(cx),
};
Some(MouseContextMenu::new(menu_position, context_menu, cx))
}
};
cx.notify();
}

Expand Down Expand Up @@ -248,7 +243,9 @@ mod tests {
}
"});
cx.editor(|editor, _app| assert!(editor.mouse_context_menu.is_none()));
cx.update_editor(|editor, cx| deploy_context_menu(editor, Default::default(), point, cx));
cx.update_editor(|editor, cx| {
deploy_context_menu(editor, Some(Default::default()), point, cx)
});

cx.assert_editor_state(indoc! {"
fn test() {
Expand Down

0 comments on commit ac9a83b

Please sign in to comment.