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
This commit is contained in:
Piotr Osiewicz 2024-04-30 18:51:20 +02:00 committed by GitHub
parent 713c314d67
commit ada2791fa3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 35 additions and 13 deletions

View File

@ -764,10 +764,10 @@ impl ContextMenu {
max_height: Pixels,
workspace: Option<WeakView<Workspace>>,
cx: &mut ViewContext<Editor>,
) -> (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<Editor>,
) -> (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<Editor>,
) -> Option<(DisplayPoint, AnyElement)> {
) -> Option<(ContextMenuOrigin, AnyElement)> {
self.context_menu.read().as_ref().map(|menu| {
menu.render(
cursor_position,

View File

@ -1949,6 +1949,7 @@ impl EditorElement {
scroll_pixel_position: gpui::Point<Pixels>,
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 {