Skip to content

Commit

Permalink
Colors for items in the completion menu (#12299)
Browse files Browse the repository at this point in the history
  • Loading branch information
NikitaRevenco authored Dec 20, 2024
1 parent a91263d commit ba6e6dc
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 43 deletions.
105 changes: 62 additions & 43 deletions helix-term/src/ui/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@ use helix_view::{
document::SavePoint,
editor::CompleteAction,
handlers::lsp::SignatureHelpInvoked,
theme::{Modifier, Style},
theme::{Color, Modifier, Style},
ViewId,
};
use tui::{buffer::Buffer as Surface, text::Span};
use tui::{
buffer::Buffer as Surface,
text::{Span, Spans},
};

use std::{borrow::Cow, sync::Arc};

Expand Down Expand Up @@ -64,53 +67,69 @@ impl menu::Item for CompletionItem {

let kind = match self {
CompletionItem::Lsp(LspCompletionItem { item, .. }) => match item.kind {
Some(lsp::CompletionItemKind::TEXT) => "text",
Some(lsp::CompletionItemKind::METHOD) => "method",
Some(lsp::CompletionItemKind::FUNCTION) => "function",
Some(lsp::CompletionItemKind::CONSTRUCTOR) => "constructor",
Some(lsp::CompletionItemKind::FIELD) => "field",
Some(lsp::CompletionItemKind::VARIABLE) => "variable",
Some(lsp::CompletionItemKind::CLASS) => "class",
Some(lsp::CompletionItemKind::INTERFACE) => "interface",
Some(lsp::CompletionItemKind::MODULE) => "module",
Some(lsp::CompletionItemKind::PROPERTY) => "property",
Some(lsp::CompletionItemKind::UNIT) => "unit",
Some(lsp::CompletionItemKind::VALUE) => "value",
Some(lsp::CompletionItemKind::ENUM) => "enum",
Some(lsp::CompletionItemKind::KEYWORD) => "keyword",
Some(lsp::CompletionItemKind::SNIPPET) => "snippet",
Some(lsp::CompletionItemKind::COLOR) => "color",
Some(lsp::CompletionItemKind::FILE) => "file",
Some(lsp::CompletionItemKind::REFERENCE) => "reference",
Some(lsp::CompletionItemKind::FOLDER) => "folder",
Some(lsp::CompletionItemKind::ENUM_MEMBER) => "enum_member",
Some(lsp::CompletionItemKind::CONSTANT) => "constant",
Some(lsp::CompletionItemKind::STRUCT) => "struct",
Some(lsp::CompletionItemKind::EVENT) => "event",
Some(lsp::CompletionItemKind::OPERATOR) => "operator",
Some(lsp::CompletionItemKind::TYPE_PARAMETER) => "type_param",
Some(lsp::CompletionItemKind::TEXT) => "text".into(),
Some(lsp::CompletionItemKind::METHOD) => "method".into(),
Some(lsp::CompletionItemKind::FUNCTION) => "function".into(),
Some(lsp::CompletionItemKind::CONSTRUCTOR) => "constructor".into(),
Some(lsp::CompletionItemKind::FIELD) => "field".into(),
Some(lsp::CompletionItemKind::VARIABLE) => "variable".into(),
Some(lsp::CompletionItemKind::CLASS) => "class".into(),
Some(lsp::CompletionItemKind::INTERFACE) => "interface".into(),
Some(lsp::CompletionItemKind::MODULE) => "module".into(),
Some(lsp::CompletionItemKind::PROPERTY) => "property".into(),
Some(lsp::CompletionItemKind::UNIT) => "unit".into(),
Some(lsp::CompletionItemKind::VALUE) => "value".into(),
Some(lsp::CompletionItemKind::ENUM) => "enum".into(),
Some(lsp::CompletionItemKind::KEYWORD) => "keyword".into(),
Some(lsp::CompletionItemKind::SNIPPET) => "snippet".into(),
Some(lsp::CompletionItemKind::COLOR) => item
.documentation
.as_ref()
.and_then(|docs| {
let text = match docs {
lsp::Documentation::String(text) => text,
lsp::Documentation::MarkupContent(lsp::MarkupContent {
value, ..
}) => value,
};
Color::from_hex(text)
})
.map_or("color".into(), |color| {
Spans::from(vec![
Span::raw("color "),
Span::styled("■", Style::default().fg(color)),
])
}),
Some(lsp::CompletionItemKind::FILE) => "file".into(),
Some(lsp::CompletionItemKind::REFERENCE) => "reference".into(),
Some(lsp::CompletionItemKind::FOLDER) => "folder".into(),
Some(lsp::CompletionItemKind::ENUM_MEMBER) => "enum_member".into(),
Some(lsp::CompletionItemKind::CONSTANT) => "constant".into(),
Some(lsp::CompletionItemKind::STRUCT) => "struct".into(),
Some(lsp::CompletionItemKind::EVENT) => "event".into(),
Some(lsp::CompletionItemKind::OPERATOR) => "operator".into(),
Some(lsp::CompletionItemKind::TYPE_PARAMETER) => "type_param".into(),
Some(kind) => {
log::error!("Received unknown completion item kind: {:?}", kind);
""
"".into()
}
None => "",
None => "".into(),
},
CompletionItem::Other(core::CompletionItem { kind, .. }) => kind,
CompletionItem::Other(core::CompletionItem { kind, .. }) => kind.as_ref().into(),
};

menu::Row::new([
menu::Cell::from(Span::styled(
label,
if deprecated {
Style::default().add_modifier(Modifier::CROSSED_OUT)
} else if kind == "folder" {
*dir_style
} else {
Style::default()
},
)),
menu::Cell::from(kind),
])
let label = Span::styled(
label,
if deprecated {
Style::default().add_modifier(Modifier::CROSSED_OUT)
} else if kind.0[0].content == "folder" {
*dir_style
} else {
Style::default()
},
);

menu::Row::new([menu::Cell::from(label), menu::Cell::from(kind)])
}
}

Expand Down
25 changes: 25 additions & 0 deletions helix-view/src/graphics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,31 @@ pub enum Color {
Indexed(u8),
}

impl Color {
/// Creates a `Color` from a hex string
///
/// # Examples
///
/// ```rust
/// use helix_view::theme::Color;
///
/// let color1 = Color::from_hex("#c0ffee").unwrap();
/// let color2 = Color::Rgb(192, 255, 238);
///
/// assert_eq!(color1, color2);
/// ```
pub fn from_hex(hex: &str) -> Option<Self> {
if !(hex.starts_with('#') && hex.len() == 7) {
return None;
}
match [1..=2, 3..=4, 5..=6].map(|i| hex.get(i).and_then(|c| u8::from_str_radix(c, 16).ok()))
{
[Some(r), Some(g), Some(b)] => Some(Self::Rgb(r, g, b)),
_ => None,
}
}
}

#[cfg(feature = "term")]
impl From<Color> for crossterm::style::Color {
fn from(color: Color) -> Self {
Expand Down

0 comments on commit ba6e6dc

Please sign in to comment.