Skip to content

Commit

Permalink
Remove 'help-circle.svg' (question mark) icon from unknown autocomple…
Browse files Browse the repository at this point in the history
…tions (#50)

* remove 'help-circle' icon for unknown completion items in popupmenu

* Remove unnecessary comments

* Remove (more) unnecessary comments

* This commit changes the behavior of unknown completions.

Unknown completions in the pmenu now show icons if one or more completions' kinds in the pmenu are known (to gnvim). This is done by iterating throughout the items in the pmenu when necessary to check if their completion kind is known (to gnvim).

* Refactor previous changes

Some notable changes in this commit include the additoin of the
'CompletionItemKind' enum to nvim_bridge.rs per vhakulinen's
suggestion, in addition to changing the 'CompletionItemWidgetWrap::create'
function to take a reference to the other items in the popupmenu.
That function then checks whether or not any other items in the
pmenu have icons to determine if it should use an icon
for the created 'CompletionItemWidgetWrap' object if it's kind is
unknown.

I have also refactored `get_icon_pixbuf` and `get_icon_name_for_kind`
to take a reference to a 'CompletionItemKind' instead of a 'str'.

* Refactor to use  variable

* Refactor to use `show_kind` variable

* Refactor with changes requested by @vhakulinen

* Add less padding when all completion items are unknown.

* Avoid unnecessary clone

* Add padding to `info` when kind is not shown
  • Loading branch information
smolck authored and vhakulinen committed Jun 23, 2019
1 parent b357176 commit ed21346
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 51 deletions.
80 changes: 78 additions & 2 deletions src/nvim_bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,83 @@ pub enum OptionSet {
NotSupported(String),
}

#[derive(Clone)]
pub enum CompletionItemKind {
Class,
Color,
Constant,
Constructor,
Enum,
EnumMember,
Event,
Function,
File,
Folder,
Field,
Interface,
Keyword,
Method,
Module,
Operator,
Property,
Reference,
Snippet,
Struct,
Text,
TypeParameter,
Unit,
Unknown,
Value,
Variable,
}

impl From<&str> for CompletionItemKind {
fn from(from: &str) -> Self {
match from {
"class" => CompletionItemKind::Class,
"color" => CompletionItemKind::Color,
"constant" => CompletionItemKind::Constant,
"constructor" => CompletionItemKind::Constructor,
"enum" => CompletionItemKind::Enum,
"enum member" => CompletionItemKind::EnumMember,
"event" => CompletionItemKind::Event,
"function" => CompletionItemKind::Function,
"file" => CompletionItemKind::File,
"folder" => CompletionItemKind::Folder,
"field" => CompletionItemKind::Field,
"interface" => CompletionItemKind::Interface,
"keyword" => CompletionItemKind::Keyword,
"method" => CompletionItemKind::Method,
"module" => CompletionItemKind::Module,
"operator" => CompletionItemKind::Operator,
"property" => CompletionItemKind::Property,
"reference" => CompletionItemKind::Reference,
"snippet" => CompletionItemKind::Snippet,
"struct" => CompletionItemKind::Struct,
"text" => CompletionItemKind::Text,
"type parameter" => CompletionItemKind::TypeParameter,
"unit" => CompletionItemKind::Unit,
"value" => CompletionItemKind::Value,
"variable" => CompletionItemKind::Variable,
_ => CompletionItemKind::Unknown,
}
}
}

impl CompletionItemKind {
pub fn is_unknown(&self) -> bool {
match self {
CompletionItemKind::Unknown => true,
_ => false,
}
}
}

#[derive(Clone)]
pub struct CompletionItem {
pub word: String,
pub kind: String,
pub kind: CompletionItemKind,
pub kind_raw: String,
pub menu: String,
pub info: String,
}
Expand Down Expand Up @@ -679,7 +752,9 @@ fn parse_redraw_event(args: Vec<Value>) -> Vec<RedrawEvent> {
for item in unwrap_array!(args[0]) {
let item = unwrap_array!(item);
let word = unwrap_str!(item[0]).to_owned();
let kind = unwrap_str!(item[1]).to_owned();
let kind =
CompletionItemKind::from(unwrap_str!(item[1]));
let kind_raw = unwrap_str!(item[1]).to_owned();
let menu = unwrap_str!(item[2]).to_owned();
let info = unwrap_str!(item[3]).to_owned();

Expand All @@ -688,6 +763,7 @@ fn parse_redraw_event(args: Vec<Value>) -> Vec<RedrawEvent> {
kind,
menu,
info,
kind_raw,
});
}

Expand Down
97 changes: 55 additions & 42 deletions src/ui/popupmenu/completion_item_widget.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use gtk;
use gtk::prelude::*;

use nvim_bridge::CompletionItem;
use nvim_bridge::{CompletionItem, CompletionItemKind};
use ui::color::Color;

macro_rules! icon {
Expand All @@ -20,14 +20,17 @@ pub struct CompletionItemWidgetWrap {
/// Label displaying `menu` for this item in the list.
pub menu: gtk::Label,
/// Image of the item in the row.
pub kind: gtk::Image,
pub image: gtk::Image,
/// Kind of the item
pub kind: CompletionItemKind,
/// Root container.
pub row: gtk::ListBoxRow,
}

impl CompletionItemWidgetWrap {
pub fn create(
item: CompletionItem,
show_kind: bool,
css_provider: &gtk::CssProvider,
icon_fg: &Color,
size: f64,
Expand All @@ -37,11 +40,16 @@ impl CompletionItemWidgetWrap {
let grid = gtk::Grid::new();
grid.set_column_spacing(10);

let buf = get_icon_pixbuf(&item.kind.as_str(), icon_fg, size);
let kind = gtk::Image::new_from_pixbuf(&buf);
kind.set_tooltip_text(format!("kind: '{}'", item.kind).as_str());
kind.set_margin_start(margin);
grid.attach(&kind, 0, 0, 1, 1);
let image = gtk::Image::new();
if show_kind {
let buf = get_icon_pixbuf(&item.kind, icon_fg, size);
image.set_from_pixbuf(&buf);
image.set_tooltip_text(
format!("kind: '{}'", item.kind_raw).as_str(),
);
image.set_margin_start(margin);
grid.attach(&image, 0, 0, 1, 1);
}

let menu = gtk::Label::new(item.menu.as_str());
menu.set_halign(gtk::Align::End);
Expand All @@ -58,6 +66,11 @@ impl CompletionItemWidgetWrap {
info.set_halign(gtk::Align::Start);
info.set_ellipsize(pango::EllipsizeMode::End);

if !show_kind {
word.set_margin_start(5);
info.set_margin_start(5);
}

info.connect_realize(|info| {
info.hide();
});
Expand All @@ -72,12 +85,14 @@ impl CompletionItemWidgetWrap {
let row = gtk::ListBoxRow::new();
row.add(&grid);

add_css_provider!(css_provider, grid, kind, word, info, row, menu);
add_css_provider!(css_provider, grid, word, image, info, row, menu);

let kind = item.kind.clone();
CompletionItemWidgetWrap {
item,
info,
row,
image,
kind,
menu,
}
Expand All @@ -92,7 +107,7 @@ fn shorten_info(info: &String) -> String {
}

pub fn get_icon_pixbuf(
kind: &str,
kind: &CompletionItemKind,
color: &Color,
size: f64,
) -> gdk_pixbuf::Pixbuf {
Expand All @@ -105,44 +120,42 @@ pub fn get_icon_pixbuf(
buf
}

fn get_icon_name_for_kind(kind: &str, color: &Color, size: f64) -> String {
fn get_icon_name_for_kind(
kind: &CompletionItemKind,
color: &Color,
size: f64,
) -> String {
let color = color.to_hex();

let size = size * 1.1;

use self::CompletionItemKind::*;
match kind {
"method" | "function" | "constructor" => {
icon!("../../../assets/icons/box.svg", color, size)
}
"field" => {
icon!("../../../assets/icons/chevrons-right.svg", color, size)
}
"event" => icon!("../../../assets/icons/zap.svg", color, size),
"operator" => icon!("../../../assets/icons/sliders.svg", color, size),
"variable" => icon!("../../../assets/icons/disc.svg", color, size),
"class" => icon!("../../../assets/icons/share-2.svg", color, size),
"interface" => {
icon!("../../../assets/icons/book-open.svg", color, size)
}
"struct" => icon!("../../../assets/icons/align-left.svg", color, size),
"type parameter" => {
icon!("../../../assets/icons/type.svg", color, size)
}
"module" => icon!("../../../assets/icons/code.svg", color, size),
"property" => icon!("../../../assets/icons/key.svg", color, size),
"unit" => icon!("../../../assets/icons/compass.svg", color, size),
"constant" => icon!("../../../assets/icons/shield.svg", color, size),
"value" | "enum" => {
icon!("../../../assets/icons/database.svg", color, size)
}
"enum member" => icon!("../../../assets/icons/tag.svg", color, size),
"keyword" => icon!("../../../assets/icons/link-2.svg", color, size),
"text" => icon!("../../../assets/icons/at-sign.svg", color, size),
"color" => icon!("../../../assets/icons/aperture.svg", color, size),
"file" => icon!("../../../assets/icons/file.svg", color, size),
"reference" => icon!("../../../assets/icons/link.svg", color, size),
"snippet" => icon!("../../../assets/icons/file-text.svg", color, size),
"folder" => icon!("../../../assets/icons/folder.svg", color, size),
Constructor => icon!("../../../assets/icons/box.svg", color, size),
Method => icon!("../../../assets/icons/box.svg", color, size),
Function => icon!("../../../assets/icons/box.svg", color, size),
Field => icon!("../../../assets/icons/chevrons-right.svg", color, size),
Event => icon!("../../../assets/icons/zap.svg", color, size),
Operator => icon!("../../../assets/icons/sliders.svg", color, size),
Variable => icon!("../../../assets/icons/disc.svg", color, size),
Class => icon!("../../../assets/icons/share-2.svg", color, size),
Interface => icon!("../../../assets/icons/book-open.svg", color, size),
Struct => icon!("../../../assets/icons/align-left.svg", color, size),
TypeParameter => icon!("../../../assets/icons/type.svg", color, size),
Module => icon!("../../../assets/icons/code.svg", color, size),
Property => icon!("../../../assets/icons/key.svg", color, size),
Unit => icon!("../../../assets/icons/compass.svg", color, size),
Constant => icon!("../../../assets/icons/shield.svg", color, size),
Value => icon!("../../../assets/icons/database.svg", color, size),
Enum => icon!("../../../assets/icons/database.svg", color, size),
EnumMember => icon!("../../../assets/icons/tag.svg", color, size),
Keyword => icon!("../../../assets/icons/link-2.svg", color, size),
Text => icon!("../../../assets/icons/at-sign.svg", color, size),
Color => icon!("../../../assets/icons/aperture.svg", color, size),
File => icon!("../../../assets/icons/file.svg", color, size),
Reference => icon!("../../../assets/icons/link.svg", color, size),
Snippet => icon!("../../../assets/icons/file-text.svg", color, size),
Folder => icon!("../../../assets/icons/folder.svg", color, size),

_ => icon!("../../../assets/icons/help-circle.svg", color, size),
}
Expand Down
8 changes: 8 additions & 0 deletions src/ui/popupmenu/lazy_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use ui::popupmenu::CompletionItemWidgetWrap;
struct State {
items: Vec<CompletionItemWidgetWrap>,
items_to_load: Vec<CompletionItem>,
show_kind: bool,

source_id: Option<glib::SourceId>,

Expand Down Expand Up @@ -43,6 +44,7 @@ impl State {
source_id: None,
list,
css_provider,
show_kind: false,
}
}
}
Expand All @@ -58,6 +60,10 @@ impl LazyLoader {
}
}

pub fn get_show_kind(&self) -> bool {
self.state.borrow().show_kind
}

pub fn set_items(
&mut self,
items: Vec<CompletionItem>,
Expand All @@ -67,6 +73,7 @@ impl LazyLoader {
let mut state = self.state.borrow_mut();
state.clear();

state.show_kind = items.iter().any(|item| !item.kind.is_unknown());
state.items_to_load = items;

let state_ref = self.state.clone();
Expand All @@ -89,6 +96,7 @@ impl LazyLoader {
let item = state.items_to_load.remove(0);
let widget = CompletionItemWidgetWrap::create(
item,
state.show_kind,
&state.css_provider,
&icon_fg,
size,
Expand Down
21 changes: 14 additions & 7 deletions src/ui/popupmenu/popupmenu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ impl Popupmenu {
let list = self.list.clone();
let info_label = self.info_label.clone();
let info_shown = self.info_shown;
let show_kind = self.items.get_show_kind();

self.items.once_loaded(Some(item_num), move |items| {
let mut state = state.borrow_mut();
Expand All @@ -388,9 +389,12 @@ impl Popupmenu {
prev.info.set_visible(false);
prev.menu.set_visible(false);

// Update the `kind` icon with default fg color.
let buf = get_icon_pixbuf(&prev.item.kind, &fg, font_height);
prev.kind.set_from_pixbuf(&buf);
if show_kind {
// Update the `kind` icon with default fg color.
let buf =
get_icon_pixbuf(&prev.item.kind, &fg, font_height);
prev.image.set_from_pixbuf(&buf);
}
}

state.selected = item_num;
Expand Down Expand Up @@ -442,10 +446,13 @@ impl Popupmenu {
*id.borrow_mut() = Some(sig_id);
}

// Update the `kind` icon with "selected" fg color.
let buf =
get_icon_pixbuf(&item.item.kind, &fg_sel, font_height);
item.kind.set_from_pixbuf(&buf);
if show_kind {
// Update the `kind` icon with "selected" fg color.
let buf =
get_icon_pixbuf(&item.item.kind, &fg_sel, font_height);
item.image.set_from_pixbuf(&buf);
}

let newline =
if item.item.menu.len() > 0 && item.item.info.len() > 0 {
"\n"
Expand Down

0 comments on commit ed21346

Please sign in to comment.