Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--helix-term/src/ui/completion.rs105
-rw-r--r--helix-view/src/graphics.rs25
2 files changed, 87 insertions, 43 deletions
diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs
index ad317e39..adacfad3 100644
--- a/helix-term/src/ui/completion.rs
+++ b/helix-term/src/ui/completion.rs
@@ -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};
@@ -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)])
}
}
diff --git a/helix-view/src/graphics.rs b/helix-view/src/graphics.rs
index a26823b9..fcc037ed 100644
--- a/helix-view/src/graphics.rs
+++ b/helix-view/src/graphics.rs
@@ -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 {