diff --git a/crates/editor2/src/editor.rs b/crates/editor2/src/editor.rs index 5e00faf3d2..5317e4ac2b 100644 --- a/crates/editor2/src/editor.rs +++ b/crates/editor2/src/editor.rs @@ -1605,6 +1605,13 @@ impl CodeActionsMenu { .bg(cx.theme().colors().element_background) .px_2() .py_1() + .with_width_from_item( + self.actions + .iter() + .enumerate() + .max_by_key(|(_, action)| action.lsp_action.title.chars().count()) + .map(|(ix, _)| ix), + ) .render(); if self.deployed_from_indicator { @@ -1613,78 +1620,6 @@ impl CodeActionsMenu { (cursor_position, element) } - // enum ActionTag {} - - // let container_style = style.autocomplete.container; - // let actions = self.actions.clone(); - // let selected_item = self.selected_item; - // let element = UniformList::new( - // self.list.clone(), - // actions.len(), - // cx, - // move |_, range, items, cx| { - // let start_ix = range.start; - // for (ix, action) in actions[range].iter().enumerate() { - // let item_ix = start_ix + ix; - // items.push( - // MouseEventHandler::new::(item_ix, cx, |state, _| { - // let item_style = if item_ix == selected_item { - // style.autocomplete.selected_item - // } else if state.hovered() { - // style.autocomplete.hovered_item - // } else { - // style.autocomplete.item - // }; - - // Text::new(action.lsp_action.title.clone(), style.text.clone()) - // .with_soft_wrap(false) - // .contained() - // .with_style(item_style) - // }) - // .with_cursor_style(CursorStyle::PointingHand) - // .on_down(MouseButton::Left, move |_, this, cx| { - // let workspace = this - // .workspace - // .as_ref() - // .and_then(|(workspace, _)| workspace.upgrade(cx)); - // cx.window_context().defer(move |cx| { - // if let Some(workspace) = workspace { - // workspace.update(cx, |workspace, cx| { - // if let Some(task) = Editor::confirm_code_action( - // workspace, - // &ConfirmCodeAction { - // item_ix: Some(item_ix), - // }, - // cx, - // ) { - // task.detach_and_log_err(cx); - // } - // }); - // } - // }); - // }) - // .into_any(), - // ); - // } - // }, - // ) - // .with_width_from_item( - // self.actions - // .iter() - // .enumerate() - // .max_by_key(|(_, action)| action.lsp_action.title.chars().count()) - // .map(|(ix, _)| ix), - // ) - // .contained() - // .with_style(container_style) - // .into_any(); - - // if self.deployed_from_indicator { - // *cursor_position.column_mut() = 0; - // } - - // (cursor_position, element) - // } } pub struct CopilotState { diff --git a/crates/gpui2/src/elements/uniform_list.rs b/crates/gpui2/src/elements/uniform_list.rs index 342cd05471..6687559d1c 100644 --- a/crates/gpui2/src/elements/uniform_list.rs +++ b/crates/gpui2/src/elements/uniform_list.rs @@ -30,6 +30,7 @@ where id: id.clone(), style, item_count, + item_to_measure_index: 0, render_items: Box::new(move |view, visible_range, cx| { f(view, visible_range, cx) .into_iter() @@ -45,6 +46,7 @@ pub struct UniformList { id: ElementId, style: StyleRefinement, item_count: usize, + item_to_measure_index: usize, render_items: Box< dyn for<'a> Fn( &'a mut V, @@ -112,7 +114,7 @@ impl Element for UniformList { cx: &mut ViewContext, ) -> Self::ElementState { element_state.unwrap_or_else(|| { - let item_size = self.measure_first_item(view_state, None, cx); + let item_size = self.measure_item(view_state, None, cx); UniformListState { interactive: InteractiveElementState::default(), item_size, @@ -174,7 +176,7 @@ impl Element for UniformList { let content_size; if self.item_count > 0 { let item_height = self - .measure_first_item(view_state, Some(padded_bounds.size.width), cx) + .measure_item(view_state, Some(padded_bounds.size.width), cx) .height; if let Some(scroll_handle) = self.scroll_handle.clone() { scroll_handle.0.lock().replace(ScrollHandleState { @@ -240,14 +242,23 @@ impl Element for UniformList { } impl UniformList { - fn measure_first_item( + pub fn with_width_from_item(mut self, item_index: Option) -> Self { + self.item_to_measure_index = item_index.unwrap_or(0); + self + } + + fn measure_item( &self, view_state: &mut V, list_width: Option, cx: &mut ViewContext, ) -> Size { - let mut items = (self.render_items)(view_state, 0..1, cx); - debug_assert_eq!(items.len(), 1); + if self.item_count == 0 { + return Size::default(); + } + + let item_ix = cmp::min(self.item_to_measure_index, self.item_count - 1); + let mut items = (self.render_items)(view_state, item_ix..item_ix + 1, cx); let mut item_to_measure = items.pop().unwrap(); let available_space = size( list_width.map_or(AvailableSpace::MinContent, |width| {