From bd3bffaf67bcb69ec2dedf22339adcde0921c04b Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Wed, 24 Sep 2025 11:43:59 +0800 Subject: [PATCH] editor: Fix completion width align to longest item. (#1281) --- .../examples/fixtures/completion_items.json | 2 ++ crates/ui/src/input/popovers/code_action_menu.rs | 16 ++-------------- crates/ui/src/input/popovers/completion_menu.rs | 10 ++++++---- crates/ui/src/input/popovers/hover_popover.rs | 8 ++------ crates/ui/src/input/popovers/mod.rs | 14 +++++--------- crates/ui/src/styled.rs | 3 ++- 6 files changed, 19 insertions(+), 34 deletions(-) diff --git a/crates/story/examples/fixtures/completion_items.json b/crates/story/examples/fixtures/completion_items.json index 2bea7477..7ff6cc19 100644 --- a/crates/story/examples/fixtures/completion_items.json +++ b/crates/story/examples/fixtures/completion_items.json @@ -1,6 +1,7 @@ [ { "label": "as", + "detail": "as TYPE", "documentation": "Perform a safe type cast.\n\n## Example:\n```rust\nlet x: u32 = 42;\nlet y: u64 = x as u64;\n```" }, { @@ -9,6 +10,7 @@ }, { "label": "const", + "detail": "const NAME: Type = ..;", "documentation": "Define a constant value.\n\n**Note:** Constants are immutable and must have their type explicitly declared." }, { diff --git a/crates/ui/src/input/popovers/code_action_menu.rs b/crates/ui/src/input/popovers/code_action_menu.rs index cd411b0d..07eb1225 100644 --- a/crates/ui/src/input/popovers/code_action_menu.rs +++ b/crates/ui/src/input/popovers/code_action_menu.rs @@ -13,7 +13,7 @@ const MAX_MENU_HEIGHT: Pixels = px(480.); use crate::{ actions, h_flex, - input::{self, InputState}, + input::{self, popovers::editor_popover, InputState}, list::{List, ListDelegate, ListEvent}, ActiveTheme, IndexPath, Selectable, }; @@ -330,21 +330,9 @@ impl Render for CodeActionMenu { let max_width = MAX_MENU_WIDTH.min(window.bounds().size.width - pos.x); deferred( - div() - .id("code-action-menu") - .absolute() + editor_popover("code-action-menu", cx) .left(pos.x) .top(pos.y) - .flex_none() - .occlude() - .p_1() - .text_xs() - .text_color(cx.theme().popover_foreground) - .bg(cx.theme().popover) - .border_1() - .border_color(cx.theme().border) - .rounded(cx.theme().radius) - .shadow_md() .max_w(max_width) .min_w(px(120.)) .child(self.list.clone()) diff --git a/crates/ui/src/input/popovers/completion_menu.rs b/crates/ui/src/input/popovers/completion_menu.rs index 3785a7c1..b72f6959 100644 --- a/crates/ui/src/input/popovers/completion_menu.rs +++ b/crates/ui/src/input/popovers/completion_menu.rs @@ -16,7 +16,7 @@ use crate::{ actions, h_flex, input::{ self, - popovers::{popover, render_markdown}, + popovers::{editor_popover, render_markdown}, InputState, RopeExt, }, label::Label, @@ -360,7 +360,9 @@ impl CompletionMenu { let longest_ix = items .iter() .enumerate() - .max_by_key(|(_, item)| item.label.len()) + .max_by_key(|(_, item)| { + item.label.len() + item.detail.as_ref().map(|d| d.len()).unwrap_or(0) + }) .map(|(ix, _)| ix) .unwrap_or(0); @@ -432,7 +434,7 @@ impl Render for CompletionMenu { .items_start() .when(vertical_layout, |this| this.flex_col()) .child( - popover("completion-menu", cx) + editor_popover("completion-menu", cx) .max_w(max_width) .min_w(px(120.)) .child(self.list.clone()) @@ -456,7 +458,7 @@ impl Render for CompletionMenu { this.child( div().child( - popover("completion-menu", cx) + editor_popover("completion-menu", cx) .w(MAX_MENU_WIDTH) .px_2() .child(render_markdown("doc", doc, window, cx)), diff --git a/crates/ui/src/input/popovers/hover_popover.rs b/crates/ui/src/input/popovers/hover_popover.rs index e486f8dd..5cf9c872 100644 --- a/crates/ui/src/input/popovers/hover_popover.rs +++ b/crates/ui/src/input/popovers/hover_popover.rs @@ -8,7 +8,7 @@ use gpui::{ use crate::{ input::{popovers::render_markdown, InputState}, - ActiveTheme as _, StyledExt, + StyledExt, }; pub struct HoverPopover { @@ -194,11 +194,7 @@ impl Element for Popover { .occlude() .p_1() .text_xs() - .text_color(cx.theme().popover_foreground) - .bg(cx.theme().popover) - .border_1() - .border_color(cx.theme().border) - .rounded(cx.theme().radius) + .popover_style(cx) .shadow_md() .max_w(max_width) .refine_style(&self.style) diff --git a/crates/ui/src/input/popovers/mod.rs b/crates/ui/src/input/popovers/mod.rs index 78752012..8887d7cd 100644 --- a/crates/ui/src/input/popovers/mod.rs +++ b/crates/ui/src/input/popovers/mod.rs @@ -17,7 +17,7 @@ use gpui::{ use crate::{ text::{TextView, TextViewStyle}, - ActiveTheme as _, + StyledExt as _, }; pub(crate) enum ContextMenu { @@ -63,17 +63,13 @@ pub(super) fn render_markdown( .selectable() } -pub(super) fn popover(id: impl Into, cx: &App) -> Stateful
{ +pub(super) fn editor_popover(id: impl Into, cx: &App) -> Stateful
{ div() .id(id) .flex_none() .occlude() - .p_1() - .text_xs() - .text_color(cx.theme().popover_foreground) - .bg(cx.theme().popover) - .border_1() - .border_color(cx.theme().border) - .rounded(cx.theme().radius) + .popover_style(cx) .shadow_md() + .text_xs() + .p_1() } diff --git a/crates/ui/src/styled.rs b/crates/ui/src/styled.rs index 1fdd08a0..2c8b8a5d 100644 --- a/crates/ui/src/styled.rs +++ b/crates/ui/src/styled.rs @@ -190,8 +190,9 @@ pub trait StyledExt: Styled + Sized { /// Set as Popover style #[inline] - fn popover_style(self, cx: &mut App) -> Self { + fn popover_style(self, cx: &App) -> Self { self.bg(cx.theme().popover) + .text_color(cx.theme().popover_foreground) .border_1() .border_color(cx.theme().border) .shadow_lg()