Completion Provider with Priority/Sort

Hi, what is the best way to show my items first with completion provider?

And also is possible to make a custom sort on that list? it seems to be sorted alphabetically but I want some items to show first

 

Thanks !

1
9 comments
Official comment

PrioritizedLookupElement.withPriority will most likely help.

Yes I've tried that but is not working.

I have an extension point on 

completion.contributor language="PHP"

inside "addCompletions" method I'm adding the autocomplete option for the "namespace":

double priority = 1000;     // why this is not working!
result.addElement(
PrioritizedLookupElement.withPriority(
LookupElementBuilder
.create(namespace+";")
.withIcon(ICON_16x16),
priority
)
);

 

Code Completion works fine, the element is added to the list when using CTRL+SPACE, but is always on the bottom and is not visible at first sight

Is there any way to make it appear first?

 

0

Please try specifying "order="first"" for your contributor declaration in plugin.xml.

1

Thanks Peter! that did the trick

0

Hi

I'm able to present my completions at the top, but what if I'd like to insert them somewhere in the middle (e.g. after variables names but before methods)?

I tried adding a weigher, but that seemed to only change the order of my suggestions and they were all still at the top. Also the java doc here: https://github.com/JetBrains/intellij-community/blob/210e0ed138627926e10094bb9c76026319cec178/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionContributor.java#L108-L112 

suggests this is not the way to do it.

Is there a way to sort all completions (from all contributors and providers) using my specific sorter?

Thanks

Shai

1

The java doc suggests it's exactly the way to do it. See com.intellij.codeInsight.completion.PreferByKindWeigher for an example.

0

Hi Peter

Thanks for the quick reply. This is really appreciated.

We've been looking at this the whole day but we just can't seem to figure this out. I don't understand what the PreferByKindWeigher does that we don't. 

We're adding completions to the basic auto complete (i.e. ctrl+space action) so the completions contains IJ's completions and ours.

We added a dummy weigher which, based on the LookupElement type, just returns some int value. This enables us to change the order of all completions except for our own. Our completions remain at the top no matter what weigh we give them. We tried changing the order of the weigher and contributor in the plugin.xml but no combination managed to do the trick.

This is how we added the weigher in the plugin.xml (as I said, we also tried other order values):

<weigher id="YahaveWeigher"
implementationClass="com.codota.intellij.lean.assistant.completion.local.YahaveWeigher"
key="completion" order="LAST"/>

I can see in the weights log dump (see below) that our completions our "frozen".

Any suggestions for us?

This is the weights dump log (I hope it's pasted in a readable format). YahaveWeigher is our dummy weigher. The "Calendar", "Date", "DateFormat", "SimpleDateFormat" and "TimeZone" are the elements that our provider added to the list. In this case, we'd like them to appear after the "gc" element.

2018-07-31 17:01:30,153 [6720675] INFO - ernal.DumpLookupElementWeights - selected: LookupElementBuilder: string=Calendar; handler=com.codota.intellij.lean.assistant.completion.local.newline.NewLineCompletionProvider$$Lambda$2005/1108325618@53a3c431
prefix:
weights:
Calendar frozen=true, sorter=1, stats=10000
Date frozen=true, sorter=1, stats=9999
DateFormat frozen=true, sorter=1, stats=0
SimpleDateFormat frozen=true, sorter=1, stats=0
TimeZone frozen=true, sorter=1, stats=0
f frozen=false, sorter=2, liftShorter=false, stats=0, kind=variable, statics=0, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=2, scalaExplicitlyImportedWeigher=0, explicitlyImported=300, openedInEditor=true, sameDirectory=true, javaInheritance=null, sameLogicalRoot=true, sameModule=2, knownElement=0, inResolveScope=true, sdkOrLibrary=false], YahaveWeigher=1000000000
gc frozen=false, sorter=2, liftShorter=false, stats=0, kind=variable, statics=0, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=2, scalaExplicitlyImportedWeigher=0, explicitlyImported=300, openedInEditor=true, sameDirectory=true, javaInheritance=null, sameLogicalRoot=true, sameModule=2, knownElement=0, inResolveScope=true, sdkOrLibrary=false], YahaveWeigher=1000000000
GregorianCalendar frozen=false, sorter=2, liftShorter=false, stats=10000, kind=classNameOrGlobalStatic, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=100, openedInEditor=false, sameDirectory=false, javaInheritance=false, sameLogicalRoot=false, sameModule=0, knownElement=7, inResolveScope=true, sdkOrLibrary=true], YahaveWeigher=-300000000
String frozen=false, sorter=2, liftShorter=false, stats=9994, kind=classNameOrGlobalStatic, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=100, openedInEditor=false, sameDirectory=false, javaInheritance=false, sameLogicalRoot=false, sameModule=0, knownElement=8, inResolveScope=true, sdkOrLibrary=true], YahaveWeigher=-300000000
main frozen=false, sorter=2, liftShorter=false, stats=0, kind=normal, statics=-5, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=2, scalaExplicitlyImportedWeigher=0, explicitlyImported=300, openedInEditor=true, sameDirectory=true, javaInheritance=null, sameLogicalRoot=true, sameModule=2, knownElement=0, inResolveScope=true, sdkOrLibrary=false], YahaveWeigher=500
assert frozen=false, sorter=2, liftShorter=false, stats=0, kind=normal, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=0, openedInEditor=false, sameDirectory=false, javaInheritance=null, sameLogicalRoot=false, sameModule=0, knownElement=0, inResolveScope=false, sdkOrLibrary=false], YahaveWeigher=-2000000
boolean frozen=false, sorter=2, liftShorter=false, stats=0, kind=normal, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=0, openedInEditor=false, sameDirectory=false, javaInheritance=null, sameLogicalRoot=false, sameModule=0, knownElement=0, inResolveScope=false, sdkOrLibrary=false], YahaveWeigher=-2000000
byte frozen=false, sorter=2, liftShorter=false, stats=0, kind=normal, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=0, openedInEditor=false, sameDirectory=false, javaInheritance=null, sameLogicalRoot=false, sameModule=0, knownElement=0, inResolveScope=false, sdkOrLibrary=false], YahaveWeigher=-2000000
char frozen=false, sorter=2, liftShorter=false, stats=0, kind=normal, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=0, openedInEditor=false, sameDirectory=false, javaInheritance=null, sameLogicalRoot=false, sameModule=0, knownElement=0, inResolveScope=false, sdkOrLibrary=false], YahaveWeigher=-2000000
class frozen=false, sorter=2, liftShorter=false, stats=0, kind=normal, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=0, openedInEditor=false, sameDirectory=false, javaInheritance=null, sameLogicalRoot=false, sameModule=0, knownElement=0, inResolveScope=false, sdkOrLibrary=false], YahaveWeigher=-2000000
do frozen=false, sorter=2, liftShorter=false, stats=0, kind=normal, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=0, openedInEditor=false, sameDirectory=false, javaInheritance=null, sameLogicalRoot=false, sameModule=0, knownElement=0, inResolveScope=false, sdkOrLibrary=false], YahaveWeigher=-2000000
double frozen=false, sorter=2, liftShorter=false, stats=0, kind=normal, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=0, openedInEditor=false, sameDirectory=false, javaInheritance=null, sameLogicalRoot=false, sameModule=0, knownElement=0, inResolveScope=false, sdkOrLibrary=false], YahaveWeigher=-2000000
final frozen=false, sorter=2, liftShorter=false, stats=0, kind=normal, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=0, openedInEditor=false, sameDirectory=false, javaInheritance=null, sameLogicalRoot=false, sameModule=0, knownElement=0, inResolveScope=false, sdkOrLibrary=false], YahaveWeigher=-2000000
float frozen=false, sorter=2, liftShorter=false, stats=0, kind=normal, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=0, openedInEditor=false, sameDirectory=false, javaInheritance=null, sameLogicalRoot=false, sameModule=0, knownElement=0, inResolveScope=false, sdkOrLibrary=false], YahaveWeigher=-2000000
for frozen=false, sorter=2, liftShorter=false, stats=0, kind=normal, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=0, openedInEditor=false, sameDirectory=false, javaInheritance=null, sameLogicalRoot=false, sameModule=0, knownElement=0, inResolveScope=false, sdkOrLibrary=false], YahaveWeigher=-2000000
if frozen=false, sorter=2, liftShorter=false, stats=0, kind=normal, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=0, openedInEditor=false, sameDirectory=false, javaInheritance=null, sameLogicalRoot=false, sameModule=0, knownElement=0, inResolveScope=false, sdkOrLibrary=false], YahaveWeigher=-2000000
int frozen=false, sorter=2, liftShorter=false, stats=0, kind=normal, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=0, openedInEditor=false, sameDirectory=false, javaInheritance=null, sameLogicalRoot=false, sameModule=0, knownElement=0, inResolveScope=false, sdkOrLibrary=false], YahaveWeigher=-2000000
long frozen=false, sorter=2, liftShorter=false, stats=0, kind=normal, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=0, openedInEditor=false, sameDirectory=false, javaInheritance=null, sameLogicalRoot=false, sameModule=0, knownElement=0, inResolveScope=false, sdkOrLibrary=false], YahaveWeigher=-2000000
new frozen=false, sorter=2, liftShorter=false, stats=0, kind=normal, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=0, openedInEditor=false, sameDirectory=false, javaInheritance=null, sameLogicalRoot=false, sameModule=0, knownElement=0, inResolveScope=false, sdkOrLibrary=false], YahaveWeigher=-2000000
return frozen=false, sorter=2, liftShorter=false, stats=0, kind=normal, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=0, openedInEditor=false, sameDirectory=false, javaInheritance=null, sameLogicalRoot=false, sameModule=0, knownElement=0, inResolveScope=false, sdkOrLibrary=false], YahaveWeigher=-2000000
short frozen=false, sorter=2, liftShorter=false, stats=0, kind=normal, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=0, openedInEditor=false, sameDirectory=false, javaInheritance=null, sameLogicalRoot=false, sameModule=0, knownElement=0, inResolveScope=false, sdkOrLibrary=false], YahaveWeigher=-2000000
switch frozen=false, sorter=2, liftShorter=false, stats=0, kind=normal, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=0, openedInEditor=false, sameDirectory=false, javaInheritance=null, sameLogicalRoot=false, sameModule=0, knownElement=0, inResolveScope=false, sdkOrLibrary=false], YahaveWeigher=-2000000
synchronized frozen=false, sorter=2, liftShorter=false, stats=0, kind=normal, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=0, openedInEditor=false, sameDirectory=false, javaInheritance=null, sameLogicalRoot=false, sameModule=0, knownElement=0, inResolveScope=false, sdkOrLibrary=false], YahaveWeigher=-2000000
throw frozen=false, sorter=2, liftShorter=false, stats=0, kind=normal, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=0, openedInEditor=false, sameDirectory=false, javaInheritance=null, sameLogicalRoot=false, sameModule=0, knownElement=0, inResolveScope=false, sdkOrLibrary=false], YahaveWeigher=-2000000
try frozen=false, sorter=2, liftShorter=false, stats=0, kind=normal, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=0, openedInEditor=false, sameDirectory=false, javaInheritance=null, sameLogicalRoot=false, sameModule=0, knownElement=0, inResolveScope=false, sdkOrLibrary=false], YahaveWeigher=-2000000
while frozen=false, sorter=2, liftShorter=false, stats=0, kind=normal, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=0, openedInEditor=false, sameDirectory=false, javaInheritance=null, sameLogicalRoot=false, sameModule=0, knownElement=0, inResolveScope=false, sdkOrLibrary=false], YahaveWeigher=-2000000
ReadXMLFile frozen=false, sorter=2, liftShorter=false, stats=0, kind=classNameOrGlobalStatic, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=1, scalaExplicitlyImportedWeigher=0, explicitlyImported=300, openedInEditor=true, sameDirectory=true, javaInheritance=true, sameLogicalRoot=true, sameModule=2, knownElement=0, inResolveScope=true, sdkOrLibrary=false], YahaveWeigher=-300000000
ShaiTest frozen=false, sorter=2, liftShorter=false, stats=0, kind=classNameOrGlobalStatic, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=200, openedInEditor=true, sameDirectory=true, javaInheritance=false, sameLogicalRoot=true, sameModule=2, knownElement=0, inResolveScope=true, sdkOrLibrary=false], YahaveWeigher=-300000000
Class frozen=false, sorter=2, liftShorter=false, stats=0, kind=classNameOrGlobalStatic, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=100, openedInEditor=false, sameDirectory=false, javaInheritance=false, sameLogicalRoot=false, sameModule=0, knownElement=8, inResolveScope=true, sdkOrLibrary=true], YahaveWeigher=-300000000
Exception frozen=false, sorter=2, liftShorter=false, stats=0, kind=classNameOrGlobalStatic, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=100, openedInEditor=false, sameDirectory=false, javaInheritance=false, sameLogicalRoot=false, sameModule=0, knownElement=8, inResolveScope=true, sdkOrLibrary=true], YahaveWeigher=-300000000
Runnable frozen=false, sorter=2, liftShorter=false, stats=0, kind=classNameOrGlobalStatic, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=100, openedInEditor=false, sameDirectory=false, javaInheritance=false, sameLogicalRoot=false, sameModule=0, knownElement=8, inResolveScope=true, sdkOrLibrary=true], YahaveWeigher=-300000000
RuntimeException frozen=false, sorter=2, liftShorter=false, stats=0, kind=classNameOrGlobalStatic, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=100, openedInEditor=false, sameDirectory=false, javaInheritance=false, sameLogicalRoot=false, sameModule=0, knownElement=8, inResolveScope=true, sdkOrLibrary=true], YahaveWeigher=-300000000
Runtime frozen=false, sorter=2, liftShorter=true, stats=0, kind=classNameOrGlobalStatic, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=100, openedInEditor=false, sameDirectory=false, javaInheritance=false, sameLogicalRoot=false, sameModule=0, knownElement=6, inResolveScope=true, sdkOrLibrary=true], YahaveWeigher=-300000000
System frozen=false, sorter=2, liftShorter=false, stats=0, kind=classNameOrGlobalStatic, statics=-3, proximity=[referenceList=unknown, groovyReferenceListWeigher=unknown, scalaClassObjectWeigher=0, samePsiMember=0, scalaExplicitlyImportedWeigher=0, explicitlyImported=100, openedInEditor=false, sameDirectory=false, javaInheritance=false, sameLogicalRoot=false, sameModule=0, knownElement=8, inResolveScope=true, sdkOrLibrary=true], YahaveWeigher=-300000000

 

Thanks very much

Shai

0

When you're trying to add completion suggestions in the middle of Java's ones, things get more complicated. Because your items have a different set of weighers (sorter) than the Java's ones. You can get Java's sorter if you feed your lookup elements to the result of "JavaCompletionSorting.addJavaSorting", and you'd need to trick PreferByKindWeigher to put your items where you need them. It might be non-easy, and the behavior of PreferByKindWeigher might be changed in future as a result of any minor bugfix.

There's no convenient API to modify Java completion sorting, sorry. You might try the following workaround though: put your contributor before everything else, intercept all items ("result.runRemainingContributors"), and add them into your own "CompletionResultSet" together with your items. But then you'd have to define your own completion sorter, which should know how to sort both yours and standard Java's completion items.

0

Indeed it sounds like there's no perfect solution for our requirement. Like you said, relying on the Java sorter is sensitive to future changes or even differences between existing versions. Sorting all of the items by ourselves means we will have to duplicate the current sophisticated logic.

What we ended up doing is add our elements and all other elements to the same java sorter by overriding fillCompletionVariants in our contributor like so:

@Override
public void fillCompletionVariants(@NotNull CompletionParameters parameters,
@NotNull CompletionResultSet result) {
final CompletionResultSet r = JavaCompletionSorting.addJavaSorting(parameters, result);
super.fillCompletionVariants(parameters, r);
}

In addition, we added our own weigher which runs first and gives our own LookupElement type a "medium" priority.

Thanks very much for your help Peter.

 

0

Please sign in to leave a comment.