Use Popover and ListItem in code actions menu (#22112)

This is good for code sharing but also sets up #22102 for making
assumptions about popover y padding.

Release Notes:

- N/A
This commit is contained in:
Michael Sloan 2024-12-16 16:24:38 -07:00 committed by GitHub
parent ccf2a60039
commit ac24f074df
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -4,7 +4,7 @@ use std::{cell::Cell, cmp::Reverse, ops::Range, rc::Rc};
use fuzzy::{StringMatch, StringMatchCandidate}; use fuzzy::{StringMatch, StringMatchCandidate};
use gpui::{ use gpui::{
div, px, uniform_list, AnyElement, BackgroundExecutor, Div, FontWeight, ListSizingBehavior, div, px, uniform_list, AnyElement, BackgroundExecutor, Div, FontWeight, ListSizingBehavior,
Model, MouseButton, Pixels, ScrollStrategy, SharedString, StrikethroughStyle, StyledText, Model, Pixels, ScrollStrategy, SharedString, StrikethroughStyle, StyledText,
UniformListScrollHandle, ViewContext, WeakView, UniformListScrollHandle, ViewContext, WeakView,
}; };
use language::Buffer; use language::Buffer;
@ -17,7 +17,7 @@ use task::ResolvedTask;
use ui::{ use ui::{
h_flex, ActiveTheme as _, Color, FluentBuilder as _, InteractiveElement as _, IntoElement, h_flex, ActiveTheme as _, Color, FluentBuilder as _, InteractiveElement as _, IntoElement,
Label, LabelCommon as _, LabelSize, ListItem, ParentElement as _, Popover, Label, LabelCommon as _, LabelSize, ListItem, ParentElement as _, Popover,
StatefulInteractiveElement as _, Styled, StyledExt as _, Toggleable as _, StatefulInteractiveElement as _, Styled, Toggleable as _,
}; };
use util::ResultExt as _; use util::ResultExt as _;
use workspace::Workspace; use workspace::Workspace;
@ -788,7 +788,7 @@ impl CodeActionsMenu {
) -> (ContextMenuOrigin, AnyElement) { ) -> (ContextMenuOrigin, AnyElement) {
let actions = self.actions.clone(); let actions = self.actions.clone();
let selected_item = self.selected_item; let selected_item = self.selected_item;
let element = uniform_list( let list = uniform_list(
cx.view().clone(), cx.view().clone(),
"code_actions_menu", "code_actions_menu",
self.actions.len(), self.actions.len(),
@ -800,27 +800,14 @@ impl CodeActionsMenu {
.enumerate() .enumerate()
.map(|(ix, action)| { .map(|(ix, action)| {
let item_ix = range.start + ix; let item_ix = range.start + ix;
let selected = selected_item == item_ix; let selected = item_ix == selected_item;
let colors = cx.theme().colors(); let colors = cx.theme().colors();
div() div().min_w(px(220.)).max_w(px(540.)).child(
.px_1() ListItem::new(item_ix)
.rounded_md() .inset(true)
.text_color(colors.text) .toggle_state(selected)
.when(selected, |style| {
style
.bg(colors.element_active)
.text_color(colors.text_accent)
})
.hover(|style| {
style
.bg(colors.element_hover)
.text_color(colors.text_accent)
})
.whitespace_nowrap()
.when_some(action.as_code_action(), |this, action| { .when_some(action.as_code_action(), |this, action| {
this.on_mouse_down( this.on_click(cx.listener(move |editor, _, cx| {
MouseButton::Left,
cx.listener(move |editor, _, cx| {
cx.stop_propagation(); cx.stop_propagation();
if let Some(task) = editor.confirm_code_action( if let Some(task) = editor.confirm_code_action(
&ConfirmCodeAction { &ConfirmCodeAction {
@ -830,17 +817,21 @@ impl CodeActionsMenu {
) { ) {
task.detach_and_log_err(cx) task.detach_and_log_err(cx)
} }
}))
.child(
h_flex()
.overflow_hidden()
.child(
// TASK: It would be good to make lsp_action.title a SharedString to avoid allocating here.
action.lsp_action.title.replace("\n", ""),
)
.when(selected, |this| {
this.text_color(colors.text_accent)
}), }),
) )
// TASK: It would be good to make lsp_action.title a SharedString to avoid allocating here.
.child(SharedString::from(
action.lsp_action.title.replace("\n", ""),
))
}) })
.when_some(action.as_task(), |this, task| { .when_some(action.as_task(), |this, task| {
this.on_mouse_down( this.on_click(cx.listener(move |editor, _, cx| {
MouseButton::Left,
cx.listener(move |editor, _, cx| {
cx.stop_propagation(); cx.stop_propagation();
if let Some(task) = editor.confirm_code_action( if let Some(task) = editor.confirm_code_action(
&ConfirmCodeAction { &ConfirmCodeAction {
@ -850,18 +841,23 @@ impl CodeActionsMenu {
) { ) {
task.detach_and_log_err(cx) task.detach_and_log_err(cx)
} }
}))
.child(
h_flex()
.overflow_hidden()
.child(task.resolved_label.replace("\n", ""))
.when(selected, |this| {
this.text_color(colors.text_accent)
}),
)
}), }),
) )
.child(SharedString::from(task.resolved_label.replace("\n", "")))
})
}) })
.collect() .collect()
}, },
) )
.elevation_1(cx)
.p_1()
.max_h(max_height)
.occlude() .occlude()
.max_h(max_height)
.track_scroll(self.scroll_handle.clone()) .track_scroll(self.scroll_handle.clone())
.with_width_from_item( .with_width_from_item(
self.actions self.actions
@ -875,8 +871,9 @@ impl CodeActionsMenu {
}) })
.map(|(ix, _)| ix), .map(|(ix, _)| ix),
) )
.with_sizing_behavior(ListSizingBehavior::Infer) .with_sizing_behavior(ListSizingBehavior::Infer);
.into_any_element();
let element = Popover::new().child(list).into_any_element();
let cursor_position = if let Some(row) = self.deployed_from_indicator { let cursor_position = if let Some(row) = self.deployed_from_indicator {
ContextMenuOrigin::GutterIndicator(row) ContextMenuOrigin::GutterIndicator(row)