From ada2791fa3a4216d1e631734c431d43e43c2cf0c Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Tue, 30 Apr 2024 18:51:20 +0200 Subject: [PATCH] editor: Move code actions menu closer to the indicator when it is deployed via click (#11214) Before: ![image](https://github.com/zed-industries/zed/assets/24362066/98d633a7-c982-4522-b4dc-b944b70b8081) After: ![image](https://github.com/zed-industries/zed/assets/24362066/79931e12-0e6c-4ece-b734-5af7d02f7e50) Release Notes: - N/A --- crates/editor/src/editor.rs | 26 ++++++++++++++++---------- crates/editor/src/element.rs | 22 +++++++++++++++++++--- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 9f9a8fff31..57be49d21b 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -764,10 +764,10 @@ impl ContextMenu { max_height: Pixels, workspace: Option>, cx: &mut ViewContext, - ) -> (DisplayPoint, AnyElement) { + ) -> (ContextMenuOrigin, AnyElement) { match self { ContextMenu::Completions(menu) => ( - cursor_position, + ContextMenuOrigin::EditorPoint(cursor_position), menu.render(style, max_height, workspace, cx), ), ContextMenu::CodeActions(menu) => menu.render(cursor_position, style, max_height, cx), @@ -775,6 +775,11 @@ impl ContextMenu { } } +enum ContextMenuOrigin { + EditorPoint(DisplayPoint), + GutterIndicator(u32), +} + #[derive(Clone)] struct CompletionsMenu { id: CompletionId, @@ -1208,11 +1213,11 @@ impl CodeActionsMenu { fn render( &self, - mut cursor_position: DisplayPoint, + cursor_position: DisplayPoint, _style: &EditorStyle, max_height: Pixels, cx: &mut ViewContext, - ) -> (DisplayPoint, AnyElement) { + ) -> (ContextMenuOrigin, AnyElement) { let actions = self.actions.clone(); let selected_item = self.selected_item; @@ -1277,10 +1282,11 @@ impl CodeActionsMenu { ) .into_any_element(); - if self.deployed_from_indicator { - *cursor_position.column_mut() = 0; - } - + let cursor_position = if self.deployed_from_indicator { + ContextMenuOrigin::GutterIndicator(cursor_position.row()) + } else { + ContextMenuOrigin::EditorPoint(cursor_position) + }; (cursor_position, element) } } @@ -4247,13 +4253,13 @@ impl Editor { .map_or(false, |menu| menu.visible()) } - pub fn render_context_menu( + fn render_context_menu( &self, cursor_position: DisplayPoint, style: &EditorStyle, max_height: Pixels, cx: &mut ViewContext, - ) -> Option<(DisplayPoint, AnyElement)> { + ) -> Option<(ContextMenuOrigin, AnyElement)> { self.context_menu.read().as_ref().map(|menu| { menu.render( cursor_position, diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 203f33b44b..ab6480a6c9 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -1949,6 +1949,7 @@ impl EditorElement { scroll_pixel_position: gpui::Point, line_layouts: &[LineWithInvisibles], newest_selection_head: DisplayPoint, + gutter_overshoot: Pixels, cx: &mut WindowContext, ) -> bool { let max_height = cmp::min( @@ -1968,9 +1969,23 @@ impl EditorElement { let available_space = size(AvailableSpace::MinContent, AvailableSpace::MinContent); let context_menu_size = context_menu.layout_as_root(available_space, cx); - let cursor_row_layout = &line_layouts[(position.row() - start_row) as usize].line; - let x = cursor_row_layout.x_for_index(position.column() as usize) - scroll_pixel_position.x; - let y = (position.row() + 1) as f32 * line_height - scroll_pixel_position.y; + let (x, y) = match position { + crate::ContextMenuOrigin::EditorPoint(point) => { + let cursor_row_layout = &line_layouts[(point.row() - start_row) as usize].line; + let x = cursor_row_layout.x_for_index(point.column() as usize) + - scroll_pixel_position.x; + let y = (point.row() + 1) as f32 * line_height - scroll_pixel_position.y; + (x, y) + } + crate::ContextMenuOrigin::GutterIndicator(row) => { + // Context menu was spawned via a click on a gutter. Ensure it's a bit closer to the indicator than just a plain first column of the + // text field. + let x = -gutter_overshoot; + let y = (row + 1) as f32 * line_height - scroll_pixel_position.y; + (x, y) + } + }; + let mut list_origin = content_origin + point(x, y); let list_width = context_menu_size.width; let list_height = context_menu_size.height; @@ -3826,6 +3841,7 @@ impl Element for EditorElement { scroll_pixel_position, &line_layouts, newest_selection_head, + gutter_dimensions.width - gutter_dimensions.left_padding, cx, ); if gutter_settings.code_actions {