Fix AI Context menu text wrapping causing overlap (#21438)

Jason Lee and Danilo Leal created

Closes https://github.com/zed-industries/zed/issues/20678

| Before | After |
| --- | --- |
| <img width="672" alt="SCR-20241203-jreb"
src="https://github.com/user-attachments/assets/411ba2a6-712f-4ab7-a320-12ac9a35c1e1">
| <img width="771" alt="SCR-20241203-jwhe"
src="https://github.com/user-attachments/assets/022c8ee9-4089-4c09-aa4b-12a0f5528822">
|

Release Notes:

- Fixed AI Context menu text wrapping causing overlap.

Also cc #21409 @WeetHet @osiewicz to use `Label`, this PR has been fixed
`Label` to ensure `whitespace_nowrap` when use `single_line`.

---------

Co-authored-by: Danilo Leal <daniloleal09@gmail.com>

Change summary

crates/assistant/src/slash_command_picker.rs | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)

Detailed changes

crates/assistant/src/slash_command_picker.rs 🔗

@@ -2,7 +2,7 @@ use std::sync::Arc;
 
 use gpui::{AnyElement, DismissEvent, SharedString, Task, WeakView};
 use picker::{Picker, PickerDelegate, PickerEditorPosition};
-use ui::{prelude::*, ListItem, ListItemSpacing, PopoverMenu, PopoverTrigger};
+use ui::{prelude::*, ListItem, ListItemSpacing, PopoverMenu, PopoverTrigger, Tooltip};
 
 use crate::assistant_panel::ContextEditor;
 use crate::SlashCommandWorkingSet;
@@ -177,11 +177,17 @@ impl PickerDelegate for SlashCommandDelegate {
                     .inset(true)
                     .spacing(ListItemSpacing::Dense)
                     .selected(selected)
+                    .tooltip({
+                        let description = info.description.clone();
+                        move |cx| cx.new_view(|_| Tooltip::new(description.clone())).into()
+                    })
                     .child(
                         v_flex()
                             .group(format!("command-entry-label-{ix}"))
                             .w_full()
+                            .py_0p5()
                             .min_w(px(250.))
+                            .max_w(px(400.))
                             .child(
                                 h_flex()
                                     .gap_1p5()
@@ -192,7 +198,7 @@ impl PickerDelegate for SlashCommandDelegate {
                                         {
                                             label.push_str(&args);
                                         }
-                                        Label::new(label).size(LabelSize::Small)
+                                        Label::new(label).single_line().size(LabelSize::Small)
                                     }))
                                     .children(info.args.clone().filter(|_| !selected).map(
                                         |args| {
@@ -200,6 +206,7 @@ impl PickerDelegate for SlashCommandDelegate {
                                                 .font_buffer(cx)
                                                 .child(
                                                     Label::new(args)
+                                                        .single_line()
                                                         .size(LabelSize::Small)
                                                         .color(Color::Muted),
                                                 )
@@ -210,9 +217,11 @@ impl PickerDelegate for SlashCommandDelegate {
                                     )),
                             )
                             .child(
-                                Label::new(info.description.clone())
-                                    .size(LabelSize::Small)
-                                    .color(Color::Muted),
+                                div().overflow_hidden().text_ellipsis().child(
+                                    Label::new(info.description.clone())
+                                        .size(LabelSize::Small)
+                                        .color(Color::Muted),
+                                ),
                             ),
                     ),
             ),