Style language server name in completion menu

Omit in buffers with one or zero running language servers with the
capability to provide completions

Co-Authored-By: Antonio Scandurra <antonio@zed.dev>
This commit is contained in:
Julia 2023-08-29 11:21:02 -04:00
parent 35b7787e02
commit 15628af04b
3 changed files with 96 additions and 28 deletions

View File

@ -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::<Vec<_>>()
});
let get_server_name = move |lookup_server_id: lsp::LanguageServerId| -> Option<String> {
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()

View File

@ -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)]

View File

@ -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),