-
Notifications
You must be signed in to change notification settings - Fork 28
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
feat: Improved completion sorting that takes into account the current word and prefix (strict then camel-hump) #705
base: main
Are you sure you want to change the base?
feat: Improved completion sorting that takes into account the current word and prefix (strict then camel-hump) #705
Conversation
…se/camel-hump checks.
…pefully this does it.
…ng completion offerings. Removed current word "contains" checks because they could short-circuit more accurate prefix checks.
@angelozerr mentioned that sorting should be using You expressly don't want to do that because it defeats the entire point of the changes I made. The problem you're solving is that you're trying to insert some word of some sort, typically a keyword. If you sort by the sort text -- which is often something like an integer value as shown in the image below (being sorted as text which has its own issues) -- the resulting sort order doesn't take into account insertion context at all, e..g: If you look at how IntelliJ IDEA and other JetBrains IDEs sort completions, they take into account the same things I am here, but also things like assignability and declaration proximity which we don't have (easily) from LSP, and of course also machine learning statistics around previously-selected completions in a given context. With this change it now tries to sort by the keyword/identifier you're trying to insert by looking at the word that already exists at the point of insertion and/or the partial word prefix that's already been typed. And if none of that applies, it degrades gracefully to the previous sorting logic, albeit now with proper consideration of language grammar case-sensitivity. The best way to get a feel for what this change does is to try it. Try completions with and without this change and see the difference in accuracy in terms of what you're actually trying to insert at the caret. I think you'll find that, with these changes, it's quite accurate, and without, you have to type more characters before the |
…iguration option that defaults to disabled. Note that even when disabled, this still includes the changes to use the configured language case-sensitivity when comparing completions as that should likely have been included in the original changes for code completions using language case-sensitivity.
@angelozerr after the holidays (i.e., "don't even look at this anytime soon while you should be spending time with family and friends"), I'd love to start working this one toward a merge. I've (hopefully) removed any concerns about behavioral regressions by making this an opt-in client-side configuration option aside from the case-sensitivty sorting improvements that likely should have been included with the prior code completion case-sensitivity work. I'll add some additional unit test cases for the comparator changes and that should make this whole. |
@@ -97,7 +97,7 @@ public boolean isCompletionSupported(@NotNull PsiFile file) { | |||
* @param file the file. | |||
* @return true the file associated with a language server can support resolve completion and false otherwise. | |||
*/ | |||
public boolean isResolveCompletionSupported(@Nullable PsiFile file) { | |||
public boolean isResolveCompletionSupported(@NotNull PsiFile file) { |
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.
All callers were passing non-null values and the isResolveCompletionSupported()
expects a non-null argument, so I changed the nullability annotation to match reality.
LSPClientFeatures clientFeatures = languageServer.getClientFeatures(); | ||
|
||
// Sort the completions as appropriate based on client configuration | ||
boolean useContextAwareSorting = clientFeatures.getCompletionFeature().useContextAwareSorting(originalFile); |
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.
The new features are now opt-in. When disabled (which is the default), the only difference vs. prior behavior should be properly respecting the language case-sensitivity config setting.
/** | ||
* Whether or not client-side context-aware completion sorting should be used. Defaults to false. | ||
*/ | ||
public boolean useContextAwareSorting = false; |
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.
The opt-in config option.
|
||
public class CompletionItemComparatorTest { | ||
private final CompletionItemComparator comparator = new CompletionItemComparator(); | ||
private final CompletionItemComparator comparator = new CompletionItemComparator(null, null, false); |
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'll add more test cases here to confirm proper behavior of the new context-aware features of this comparator.
@SCWells72 I promise you that I will review your PR after my holiday. A thing that it would be very nice is to improve the compute of the prefix (when textedit is nul, if I remember the prefix is computed for each completion item which is very badl) and to provide an api to customize it to fix #447 (comment) |
Opening this initially as a draft PR, but this brings over some of the completion ordering enhancements that I've added to the completion contributors in my own plugin. The idea is that the initial offered completions should be as close to what the user is wanting as possible given the available information at the time that completions are triggered.
First, completion sorting now takes into account configured language case sensitivity.
Next, if completions are triggered in the context of an existing identifier, any matches for that identifier should be listed first with exact matches (again, taking into account case-sensitivity) before starts-with matches:
Next, the prefix is considered with exact prefix matches listed before camel-hump prefix matches:
Exact match
Camel-hump match
Here's another example from CSS since all of the above are from TypeScript:
If this looks good -- taking into account feedback, of course -- I'll update
CompletionItemComparatorTest
with comprehensive unit tests for the new comparator logic.