Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove 'help-circle.svg' (question mark) icon from unknown autocompletions #50

Merged
merged 12 commits into from
Jun 23, 2019
Merged

Remove 'help-circle.svg' (question mark) icon from unknown autocompletions #50

merged 12 commits into from
Jun 23, 2019

Conversation

smolck
Copy link
Contributor

@smolck smolck commented Jun 4, 2019

This is an idea of how to remove the 'help-circle.svg' icon from autocompletions that are unknown to clean up the look for completions with unsupported or unimplemented kinds (like those of LanguageClient-Neovim):

image

Any feedback would be much appreciated! Currently this works by filling in an empty image in the popupmenu if there is an error with the icon's gdk_pixbuf (which is created from returning the "None" string in the get_icon_name_for_kind function).

See #47.

@badosu
Copy link
Contributor

badosu commented Jun 8, 2019

I think we should hide icons only when all are unknown, otherwise it will introduce visual inconsistency when a LSP plugin is supported but kinds are not matched due to a minor issue (customization, outdated handling on gnvim) or simply absent for that particular item.

@smolck
Copy link
Contributor Author

smolck commented Jun 8, 2019

Good point! So we find a different icon for text completions, and then if all of the completions are unknown, we show no icons. I actually got this functionality to work in a local clone of mine. It uses a boolean parameter in the create, get_icon_name_for_kind and get_icon_pixbuf functions in completion_item_widget.rs to tell get_icon_name_for_kind if other popupmenu items have images to determine if it should show images for 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).
@smolck smolck changed the title Remove 'help-circle.svg' (question mark) icon from unknown autocompletions [WIP] Remove 'help-circle.svg' (question mark) icon from unknown autocompletions Jun 8, 2019
@smolck
Copy link
Contributor Author

smolck commented Jun 8, 2019

Now the pmenu looks like this if any of the completions are known (note the bottom unknown one):
image

And this if none are known:
image

However, I used the help-circle icon for a placeholder. Any ideas for a different icon for text/unknown completions? (Or should we keep the help-circle?)

@vhakulinen
Copy link
Owner

Showing the help-circle when there are some known kinds is the way to go, so we avoid visual inconsistencies (just like @badosu noted). On a case when there are no icons shown (e.g. all kinds are unknown), remember to add some padding to the left side of the actual text. I would also avoid differing the code paths too much.

Regarding the issue that you are still facing: how to detect when a kind is known or not. I would try this: In nvim_bridge, make the completion item's kind be type of CompletionItemKind which would be an enum (that would look something like this):

pub enum CompletionItemKind {
    Function,
    Constructor,
    File,
    Folder,
    //...
    Unknown,
}

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

// Detecting if some of `items` is unknown/known:
items.iter().find(|item| !item.is_unkown()).is_some())

I didn't try this, so I'm not completely sure how it'll play out. We already have a "know set" of kinds, might has well make the type system aware of it.

I'll try to add some notes to other parts of the code some other day (its getting late here).

@smolck
Copy link
Contributor Author

smolck commented Jun 10, 2019

Thanks @vhakulinen for the info, I will try to get that working. If it goes well I’ll push a commit for review.

@smolck
Copy link
Contributor Author

smolck commented Jun 11, 2019

So, how does this look for nvim_bridge.rs? Is this at all like what you were thinking @vhakulinen?

diff --git a/src/nvim_bridge.rs b/src/nvim_bridge.rs
index 72a9777..fe0eec5 100644
--- a/src/nvim_bridge.rs
+++ b/src/nvim_bridge.rs
@@ -211,10 +211,79 @@ 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 CompletionItemKind {
+    pub fn new_from_str(kind: &str) -> Self {
+        match kind {
+            "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,
+        }
+    }
+   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 menu: String,
     pub info: String,
 }
@@ -679,7 +748,7 @@ 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::new_from_str(&unwrap_str!(item[1]).to_owned());
                         let menu = unwrap_str!(item[2]).to_owned();
                         let info = unwrap_str!(item[3]).to_owned();

I made changes in other files to accommodate this diff, but this is the core of the change, so I want to make sure this is solid before I settle on my other diffs (and put them up for review).

@smolck
Copy link
Contributor Author

smolck commented Jun 11, 2019

One question: should I implement a get_kind function (in the enum) that returns the corresponding string of a CompletionItemKind? The reason I ask is because of the set_tooltip_text function called in the CompletionItemWidgetWrap::create in completion_item_widget.rs (set_tooltip_text needs the kind as a string). The thing is, I don’t want to put needless logic in that function, but I also don’t want to do the same for the enum if it will only be used once. Should I make a function that does that in completion_item_widget.rs, or do something else entirely?

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'.
@smolck
Copy link
Contributor Author

smolck commented Jun 12, 2019

Changes have been pushed for review; any suggestions are welcome and much appreciated. Also, note that I have commented out the set_tooltip_text function in CompletionItemWidgetWrap::create for now, until I know what we want to do there.

src/ui/popupmenu/completion_item_widget.rs Outdated Show resolved Hide resolved
src/ui/popupmenu/completion_item_widget.rs Outdated Show resolved Hide resolved
src/ui/popupmenu/completion_item_widget.rs Show resolved Hide resolved
src/ui/popupmenu/lazy_loader.rs Outdated Show resolved Hide resolved
src/ui/popupmenu/popupmenu.rs Outdated Show resolved Hide resolved
src/ui/popupmenu/popupmenu.rs Outdated Show resolved Hide resolved
@vhakulinen
Copy link
Owner

Remember to run cargo fmt.

src/nvim_bridge.rs Outdated Show resolved Hide resolved
@smolck
Copy link
Contributor Author

smolck commented Jun 15, 2019

Changes have been pushed for review.

(Removed WIP from title since this only needs maybe a bit more polish.)

@smolck smolck changed the title [WIP] Remove 'help-circle.svg' (question mark) icon from unknown autocompletions Remove 'help-circle.svg' (question mark) icon from unknown autocompletions Jun 15, 2019
src/nvim_bridge.rs Outdated Show resolved Hide resolved
src/ui/popupmenu/completion_item_widget.rs Outdated Show resolved Hide resolved
src/ui/popupmenu/popupmenu.rs Outdated Show resolved Hide resolved
src/ui/popupmenu/popupmenu.rs Show resolved Hide resolved
@vhakulinen
Copy link
Owner

Looking good! Just couple minor things that need to be fixed.

@smolck
Copy link
Contributor Author

smolck commented Jun 17, 2019

@vhakulinen I’ve pushed the changes you requested. If there is anything left that needs fixing/changing please let me know.

As a side note, thank you for all of your help with this PR and my previous one. Taught (and still teaching) me valuable information about Rust, in addition to better, more efficient and idiomatic ways of doing things.

@smolck
Copy link
Contributor Author

smolck commented Jun 18, 2019

This is a little strange to me. In the below case (Python completions), the behavior is as expected:
image
in that the bottom, unknown completion text is in line with the others.

However, here (C++ completions) that is not the case:
image
Notice how the bottom (unknown) completion text is out of line with the others. I don't know if this is important enough to need fixing, but wanted to point it out nonetheless. If anyone knows how to fix this or what's causing it, please let me know.

Also, here is how it looks when all completions are unknown, just as an FYI:
image

@badosu
Copy link
Contributor

badosu commented Jun 18, 2019

Try adding a dbg!(item.menu) and seeing if the text itself coming from the LSP is padded (for the 1st issue).

@badosu
Copy link
Contributor

badosu commented Jun 21, 2019

LGTM 👍

@vhakulinen vhakulinen merged commit ed21346 into vhakulinen:master Jun 23, 2019
@vhakulinen
Copy link
Owner

Merged! Thanks for your efforts!

I made couple small changes: other was to remove unnecessary clone (effectively a copy) and added missing padding on info item when the icon is not shown.

@smolck smolck deleted the no-icon-for-unknown-completion-items branch June 23, 2019 16:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants