Skip to content

Commit

Permalink
completions: Add colors based on the LSP item kind
Browse files Browse the repository at this point in the history
  • Loading branch information
danyspin97 committed Mar 31, 2022
1 parent c8082a1 commit 45e5938
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 35 deletions.
77 changes: 47 additions & 30 deletions helix-term/src/ui/completion.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::compositor::{Component, Context, EventResult};
use crossterm::event::{Event, KeyCode, KeyEvent};
use helix_view::editor::CompleteAction;
use helix_view::theme::{Modifier, Style};
use helix_view::Theme;
use tui::buffer::Buffer as Surface;

use std::borrow::Cow;
Expand All @@ -27,38 +29,53 @@ impl menu::Item for CompletionItem {
self.label.as_str()
}

fn row(&self) -> menu::Row {
fn row(&self, theme: Option<&Theme>) -> menu::Row {
let (lsp_type_label, style) = match self.kind {
Some(lsp::CompletionItemKind::TEXT) => ("text", Some("ui.text")),
Some(lsp::CompletionItemKind::METHOD) => ("method", Some("function.method")),
Some(lsp::CompletionItemKind::FUNCTION) => ("function", Some("function")),
Some(lsp::CompletionItemKind::CONSTRUCTOR) => ("constructor", Some("constructor")),
Some(lsp::CompletionItemKind::FIELD) => ("field", Some("variable.other.member")),
Some(lsp::CompletionItemKind::VARIABLE) => ("variable", Some("variable")),
Some(lsp::CompletionItemKind::CLASS) => ("class", Some("type")),
Some(lsp::CompletionItemKind::INTERFACE) => ("interface", Some("type")),
Some(lsp::CompletionItemKind::MODULE) => ("module", Some("module")),
Some(lsp::CompletionItemKind::PROPERTY) => ("property", Some("attributes")),
Some(lsp::CompletionItemKind::UNIT) => ("unit", Some("constant")),
Some(lsp::CompletionItemKind::VALUE) => ("value", Some("string")),
Some(lsp::CompletionItemKind::ENUM) => ("enum", Some("type")),
Some(lsp::CompletionItemKind::KEYWORD) => ("keyword", Some("keyword")),
Some(lsp::CompletionItemKind::SNIPPET) => ("snippet", None),
Some(lsp::CompletionItemKind::COLOR) => ("color", None),
Some(lsp::CompletionItemKind::FILE) => ("file", None),
Some(lsp::CompletionItemKind::REFERENCE) => ("reference", None),
Some(lsp::CompletionItemKind::FOLDER) => ("folder", None),
Some(lsp::CompletionItemKind::ENUM_MEMBER) => {
("enum_member", Some("type.enum.variant"))
}
Some(lsp::CompletionItemKind::CONSTANT) => ("constant", Some("constant")),
Some(lsp::CompletionItemKind::STRUCT) => ("struct", Some("type")),
Some(lsp::CompletionItemKind::EVENT) => ("event", None),
Some(lsp::CompletionItemKind::OPERATOR) => ("operator", Some("operator")),
Some(lsp::CompletionItemKind::TYPE_PARAMETER) => {
("type_param", Some("function.parameter"))
}
Some(kind) => unimplemented!("{:?}", kind),
None => ("", None),
};

menu::Row::new(vec![
menu::Cell::from(self.label.as_str()),
menu::Cell::from(match self.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(kind) => unimplemented!("{:?}", kind),
None => "",
}),
menu::Cell::from(lsp_type_label).style(
theme
.and_then(|theme| style.and_then(|style| theme.try_get(style)))
.map_or(Style::default(), |mut style| {
style.bg = None;
style
.remove_modifier(Modifier::BOLD)
.add_modifier(Modifier::ITALIC)
}),
),
// self.detail.as_deref().unwrap_or("")
// self.label_details
// .as_ref()
Expand Down
10 changes: 5 additions & 5 deletions helix-term/src/ui/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub use tui::widgets::{Cell, Row};
use fuzzy_matcher::skim::SkimMatcherV2 as Matcher;
use fuzzy_matcher::FuzzyMatcher;

use helix_view::{graphics::Rect, Editor};
use helix_view::{graphics::Rect, Editor, Theme};
use tui::layout::Constraint;

pub trait Item {
Expand All @@ -23,7 +23,7 @@ pub trait Item {
self.label()
}

fn row(&self) -> Row {
fn row(&self, _theme: Option<&Theme>) -> Row {
Row::new(vec![Cell::from(self.label())])
}
}
Expand Down Expand Up @@ -125,10 +125,10 @@ impl<T: Item> Menu<T> {
let n = self
.options
.first()
.map(|option| option.row().cells.len())
.map(|option| option.row(None).cells.len())
.unwrap_or_default();
let max_lens = self.options.iter().fold(vec![0; n], |mut acc, option| {
let row = option.row();
let row = option.row(None);
// maintain max for each column
for (acc, cell) in acc.iter_mut().zip(row.cells.iter()) {
let width = cell.content.width();
Expand Down Expand Up @@ -296,7 +296,7 @@ impl<T: Item + 'static> Component for Menu<T> {
let scroll_line = (win_height - scroll_height) * scroll
/ std::cmp::max(1, len.saturating_sub(win_height));

let rows = options.iter().map(|option| option.row());
let rows = options.iter().map(|option| option.row(Some(theme)));
let table = Table::new(rows)
.style(style)
.highlight_style(selected)
Expand Down

0 comments on commit 45e5938

Please sign in to comment.