diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index a188a47e350393b54dfb92daddb0470dbe505892..ab2be13a25366643b9904b67407fdc9af514fd34 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -44,7 +44,7 @@ use gpui::{ elements::*, executor, fonts::{self, HighlightStyle, TextStyle}, - geometry::vector::Vector2F, + geometry::vector::{vec2f, Vector2F}, impl_actions, keymap_matcher::KeymapContext, platform::{CursorStyle, MouseButton}, @@ -858,21 +858,43 @@ impl CompletionsMenu { project .read(cx) .language_servers_for_buffer(self.buffer.read(cx), cx) - .map(|(adapter, server)| (server.server_id(), format!("{}: ", adapter.short_name))) + .filter(|(_, server)| server.capabilities().completion_provider.is_some()) + .map(|(adapter, server)| (server.server_id(), adapter.short_name)) .collect::>() }); - let get_server_name = move |lookup_server_id: lsp::LanguageServerId| -> Option { - language_servers - .iter() - .flatten() - .find_map(|(server_id, server_name)| { - if *server_id == lookup_server_id { - Some(server_name.clone()) - } else { - None - } - }) - }; + let needs_server_name = language_servers + .as_ref() + .map_or(false, |servers| servers.len() > 1); + + let get_server_name = + move |lookup_server_id: lsp::LanguageServerId| -> Option<&'static str> { + language_servers + .iter() + .flatten() + .find_map(|(server_id, server_name)| { + if *server_id == lookup_server_id { + Some(*server_name) + } else { + None + } + }) + }; + + let widest_completion_ix = self + .matches + .iter() + .enumerate() + .max_by_key(|(_, mat)| { + let completion = &self.completions[mat.candidate_id]; + let mut len = completion.label.text.chars().count(); + + if let Some(server_name) = get_server_name(completion.server_id) { + len += server_name.chars().count(); + } + + len + }) + .map(|(ix, _)| ix); let completions = self.completions.clone(); let matches = self.matches.clone(); @@ -917,14 +939,66 @@ impl CompletionsMenu { if let Some(server_name) = get_server_name(completion.server_id) { Flex::row() - .with_child(Text::new(server_name, style.text.clone())) .with_child(completion_label) + .with_children((|| { + if !needs_server_name { + return None; + } + + let text_style = TextStyle { + color: style.autocomplete.server_name_color, + font_size: style.text.font_size + * style.autocomplete.server_name_size_percent, + ..style.text.clone() + }; + + let label = Text::new(server_name, text_style) + .aligned() + .constrained() + .dynamically(move |constraint, _, _| { + gpui::SizeConstraint { + min: constraint.min, + max: vec2f( + constraint.max.x(), + constraint.min.y(), + ), + } + }); + + if Some(item_ix) == widest_completion_ix { + Some( + label + .contained() + .with_style( + style + .autocomplete + .server_name_container, + ) + .into_any(), + ) + } else { + Some(label.flex_float().into_any()) + } + })()) .into_any() } else { completion_label.into_any() } .contained() .with_style(item_style) + .constrained() + .dynamically( + move |constraint, _, _| { + if Some(item_ix) == widest_completion_ix { + constraint + } else { + gpui::SizeConstraint { + min: constraint.min, + max: constraint.min, + } + } + }, + ) }, ) .with_cursor_style(CursorStyle::PointingHand) @@ -941,19 +1015,7 @@ impl CompletionsMenu { } }, ) - .with_width_from_item( - self.matches - .iter() - .enumerate() - .max_by_key(|(_, mat)| { - self.completions[mat.candidate_id] - .label - .text - .chars() - .count() - }) - .map(|(ix, _)| ix), - ) + .with_width_from_item(widest_completion_ix) .contained() .with_style(container_style) .into_any() diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index 4766f636f37bbef734e364eaff95e0fb63e152ac..d692660738e3c446ab5416fdb723bfc07f3737a3 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -775,6 +775,9 @@ pub struct AutocompleteStyle { pub selected_item: ContainerStyle, pub hovered_item: ContainerStyle, pub match_highlight: HighlightStyle, + pub server_name_container: ContainerStyle, + pub server_name_color: Color, + pub server_name_size_percent: f32, } #[derive(Clone, Copy, Default, Deserialize, JsonSchema)] diff --git a/styles/src/style_tree/editor.ts b/styles/src/style_tree/editor.ts index 9ad008f38d4dd928af5b49c46b148df575b1c6a3..0b99b6fba6e15dc3afd127375e5a58b702ad8e40 100644 --- a/styles/src/style_tree/editor.ts +++ b/styles/src/style_tree/editor.ts @@ -205,6 +205,9 @@ export default function editor(): any { match_highlight: foreground(theme.middle, "accent", "active"), background: background(theme.middle, "active"), }, + server_name_container: { padding: { left: 40 } }, + server_name_color: text(theme.middle, "sans", "disabled", {}).color, + server_name_size_percent: 0.75, }, diagnostic_header: { background: background(theme.middle),