Skip to content

Commit

Permalink
render completion options by language server priority
Browse files Browse the repository at this point in the history
  • Loading branch information
estin committed Aug 5, 2023
1 parent 80d2599 commit 7a85d52
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 9 deletions.
21 changes: 16 additions & 5 deletions helix-term/src/ui/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,25 @@ use helix_view::{graphics::Rect, Document, Editor};
use crate::commands;
use crate::ui::{menu, Markdown, Menu, Popup, PromptEvent};

use fuzzy_matcher::skim::SkimMatcherV2 as Matcher;
use fuzzy_matcher::FuzzyMatcher;
use helix_lsp::{lsp, util, OffsetEncoding};

const MAX_LANGUAGE_SERVERS: i64 = 100;
const SCORE_MULTIPLIER: i64 = 1_000_000;

impl menu::Item for CompletionItem {
type Data = ();

#[inline]
fn score(&self, data: &Self::Data, matcher: &Matcher, pattern: &str) -> Option<i64> {
// increase items weight by language server declaration priority
let weight = (MAX_LANGUAGE_SERVERS - self.language_server_id as i64) * SCORE_MULTIPLIER;
matcher
.fuzzy_match(&self.filter_text(data), pattern)
.map(|score| score + weight)
}

fn sort_text(&self, data: &Self::Data) -> Cow<str> {
self.filter_text(data)
}
Expand Down Expand Up @@ -279,11 +294,6 @@ impl Completion {
let language_server = language_server!(item);
let offset_encoding = language_server.offset_encoding();

let language_server = editor
.language_servers
.get_by_id(item.language_server_id)
.unwrap();

// resolve item if not yet resolved
if !item.resolved {
if let Some(resolved) =
Expand Down Expand Up @@ -326,6 +336,7 @@ impl Completion {
}
};
});

let popup = Popup::new(Self::ID, menu)
.with_scrollbar(false)
.ignore_escape_key(true);
Expand Down
11 changes: 7 additions & 4 deletions helix-term/src/ui/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ pub trait Item {

fn format(&self, data: &Self::Data) -> Row;

fn score(&self, data: &Self::Data, matcher: &Matcher, pattern: &str) -> Option<i64> {
let label: String = self.format(data).cell_text().collect();
matcher.fuzzy_match(&label, pattern)
}

fn sort_text(&self, data: &Self::Data) -> Cow<str> {
let label: String = self.format(data).cell_text().collect();
label.into()
Expand Down Expand Up @@ -99,14 +104,12 @@ impl<T: Item> Menu<T> {
.iter()
.enumerate()
.filter_map(|(index, option)| {
let text = option.filter_text(&self.editor_data);
// TODO: using fuzzy_indices could give us the char idx for match highlighting
self.matcher
.fuzzy_match(&text, pattern)
option
.score(&self.editor_data, &self.matcher, pattern)
.map(|score| (index, score))
}),
);
// Order of equal elements needs to be preserved as LSP preselected items come in order of high to low priority
self.matches.sort_by_key(|(_, score)| -score);

// reset cursor position
Expand Down

0 comments on commit 7a85d52

Please sign in to comment.