-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
render completion options by language server priority #7349
Conversation
LGTM, though what is |
It may have to be a config option, but I'm unsure about that, let's wait for maintainers :) |
@poliorcetics it's https://github.com/estin/simple-completion-language-server |
Thank you very much, I'll have a look! |
helix-term/src/ui/completion.rs
Outdated
#[inline] | ||
fn group(&self, _data: &Self::Data) -> usize { | ||
self.language_server_id | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't think of other places we would want to re-use this group
concept. Ideally I'd like to see this built in to the sort_text
function: something like fn sort_key(&self, data: &Self::Data) -> impl Ord
and then CompletionItem
's Item
implementation would contain the logic for using self.language_server_id
. That depends on either rust-lang/rust#91611 to return an impl Ord
, or rust-lang/rust#29661 so that we wouldn't have to explicitly implement sort_key
in every Item:
pub trait Item {
type Data;
type SortKey: Ord = Cow<str>;
// ...
fn sort_key(&self, data: &Self::Data) -> Self::SortKey {
self.filter_text()
}
// ...
}
Maybe there's a clever way around the language features here that I'm not seeing though?
There was a similar thread of this idea in #2705 (comment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While making this an assoc type would be annoying I think it's not the worst thing having to explicitly specify a type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- removed group concept.
- introduced
Item.score
function to control score and sorting
helix-term/src/ui/completion.rs
Outdated
#[inline] | ||
fn group(&self, _data: &Self::Data) -> usize { | ||
self.language_server_id | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While making this an assoc type would be annoying I think it's not the worst thing having to explicitly specify a type
I dont think this needs a config option since it only acts as a tie breaker where the order is semi random right now |
a29de2c
to
08b39a2
Compare
bb8c355
to
7a85d52
Compare
7a85d52
to
754b66b
Compare
a87489a
to
3b4aa5b
Compare
3b4aa5b
to
90ae281
Compare
90ae281
to
411a655
Compare
0397c6b
to
c6525d0
Compare
c6525d0
to
56e4302
Compare
helix-term/src/ui/menu.rs
Outdated
/// Second ordering rule on equals items score | ||
type TieBreaker; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you should be able to add a default value here so we don't have to define it in every single implementation.
helix-term/src/ui/menu.rs
Outdated
@@ -29,30 +32,36 @@ pub trait Item: Sync + Send + 'static { | |||
let label: String = self.format(data).cell_text().collect(); | |||
label.into() | |||
} | |||
|
|||
fn tie_breaker(&self, _data: &Self::Data) -> Self::TieBreaker; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But I don't like having this extra function, it should be unnecessary because this is the intent of sort_text
(should really be renamed as sort_key).
Let's try modifying the return value of sort_text
as K: Ord
, and use a default that uses Cow<str>
. Then for your one specific implementation you can instead return (label, language_server_id)
((Cow<str>, usize)
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree we don't want an extra method. I am not sure what the right API is here though.
A couple points:
- for the picker the concept of sort text does not make sense IMO. In general I think the needs of the picker and of the menu keep diverging (some of mikes colum related work for example) so I think we will likely just endup with two traits (or even something totally different for the picker)
- for the menu I am not sure how much sense all of this actually makes. It feels wrong to me to sort by language server first since fuzzy matching is not very selective so you would see all the "bad" completions from one server before those from a second server. A score bonus is not a good solution because it's hard to implement (how large should the bonuss shpuld be is subjctive and would depend on word length/content) and ultimately not feel predictable. I proposed making it a tie breaker but exactly identicsl fuzzy scores are not as common as you would think fue to the fairly complex bpnus system. It's probably the least bad option right now.
- all of this doesn't even take into account yet that we do not actually want to sort for a lot of servers. With incomplete completion request support we have to rerequest completions on every keypress and are not supposed to do filtering and scoring ourself. The question then becomes how to mix those servers with other completion options. The server sorts internslly according to their own criteria and scoring system which we are unaware of and also not comparable. This feature has a really large impact and is very commonly used (and the capability is not respected, for example by RA) so I see it as fairly high priority so such an obvious conflict here is a concern for me.
This makes it hard for me to review since I dont understand the full problem space yet. We may endup needing a very different solution and changing the trait before we have figured that out feels premature. Perhaphs sorting by server first works after all if we filter items with a score below 50% of the top score or something. Ideally we should study what other ides (primarily vscode) do here. There is also a whole can of worms of super long LSP issue trackers where it was discussed how filtering and sorting should work exactly (which can sometimes not have a clear co conclusion, I need to read trough all that carefully again).
One thing I am fairly sure about is that we want this to be (language_server, label) and not the other way around. Score ties are already rare (which is the only situation where sort_text matters) and when they do occur we want to group by language sever first (otherwise the language sever comparison basically never matters anyway).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing I am fairly sure about is that we want this to be (language_server, label)
I was assuming that too, but that probably doesn't make sense either since you could have very weak matches from your priority server that would now appear before better matches from a second one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah no that actually would not happen (currently). Sort text is not used for fuzzy matching. It's only used as a tie breaker if the fuzzy match score is equal.
So sorting would be (fuzzy_score, language_server, label)
so the order of these two only takes effect when the score is the same (which is already pretty rare)
56e4302
to
59bc4ad
Compare
59bc4ad
to
83242b7
Compare
Now PR makes next changes:
|
rethink on #9590 |
Hi!
On multi ls with completion items rendered without any priority.
This PR groups completion items by language server id.
And in future allows to do some visualization to separate groups
For my use case (on python) with follow config
on master, I expects items from
pylsp
on top of the list, for me it primary ls for completionon this PR, all as I expected, on top items from
pylsp
and on bottom fromsimple-completion-language-server
Don't sure about it's nature behavior for other users.
Feel free to close this PR.
Sorry for my poor English.