CompletionContributor vs. PsiReference

in my plugin i was using implementation of PsiReference to create auto-complete variants and navigation between code part.
Now we have CompletionContributor. What is preferred way to solve my task and in which case one should use each of options mentioned above.

10 comments
Comment actions Permalink

Hello Evgeny,

in my plugin i was using implementation of PsiReference to create
auto-complete variants and navigation between code part.

Now we have CompletionContributor. What is preferred way to solve my
task and in which case one should use each of options mentioned above.


CompletionContributor is the preferred way to implement completion for something
which is not a reference (for example, language keywords). If you have implemented
references in a meaningful way, there's no need to rewrite them to a different
API.

--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0
Comment actions Permalink

Thnx for helpful and brief explanation

0
Comment actions Permalink

may I add to the above question:

PsiReference.getVariants
vs
CompletionProvider.addCompletions

both produce LookupElements


what is the main purpose of each?
did I understand Dmitry's answer correctly:

  •   getVariants are for symbols (variables, function names etc)
  •   addCompletions are for non-symbols (keywords)


however addCompletions passes CompletionParameters which gives context allowing to fine-tune the output.

It is tempting to always use addCompletions and override getVariants to return an empty array. Are there reasons not to do this?


when are getVariants and addCompletions called:
    a) always at the same time?
    b) sometimes one but not the other.
    c) always one but not the other.

if b) or c):  When, which is called?


Thank you very much!!

0
Comment actions Permalink

To put things simple, the answer to your question is a).

If you need the additional data passed to CompletionProvider.addCompletions(), then, by all means, use that interface. There is no reason not to do this.

0
Comment actions Permalink

actually, in this case (a) I would switch to Completion Contributor and getVariants() would return Object[0];

the context allows to filter out unlikely items. It is easier to prepare the list in one place: addCompletions


Thank you Dmitry!!

0
Comment actions Permalink

Hi,

I want to share 2 features about the completion API that I love and that are worth mentioning:

First, there are languages that have a lot of built-in functions. In my case the system comes with over 5000 functions that my completion contributor needs to handle. One of the most awesome things is, that you can give your completion entries a "Priority". So when you have a statistic, how often a function is used (for Mathematica this can easily be extracted from several hundred packages) you can use this priority in your completion contributor:

LookupElementBuilder elm = LookupElementBuilder
    .create(name)
    .withInsertHandler(MathematicaBracketInsertHandler.getInstance())
    .withTypeText(symbol.context + "`")
    .withPresentableText(symbol.nameWithoutContext);
result2.addElement(PrioritizedLookupElement.withPriority(elm, symbol.importance));


Look at the last line. With this, when you start typing and there are several hundret functions that start with the same letter, it is just unbelievable how cool it is when you have to top-priority entries on the top.

Second, please don't forget that we have smart completion. So although you can specify with the PsiElementPattern when a specific contributor should be called, always remember that you can use CompletionType.SMART when you think a completion should only work in specific scenarios. Additionally, note that IDEA often does some extra stuff when Ctrl+Space is pressed more than once. All those things can be tested by using the provided CompletionParameters:

if (parameters.getCompletionType() == CompletionType.SMART && parameters.getInvocationCount() == 2) {
  result.runRemainingContributors(parameters.withInvocationCount(3), true);
}


Cheers
Patrick

1
Comment actions Permalink

Thank you very much for sharing this, Patrick!!


> you can use CompletionType.SMART

how is CompletionType.SMART different from CompletionType.BASIC?

is CompletionType.SMART customizable in code?

0
Comment actions Permalink

IntelliJ IDEA has separate actions for regular completion (Ctrl-Space) and smart-type completion (Ctrl-Shift-Space). By regsitering contributors for each of the completion types, you can control how the corresponding action works in your language.

1
Comment actions Permalink

Thank you Dmitry.

I was not aware of Ctrl-Shift-Space.

0
Comment actions Permalink

Hi,

I have created a custom javascript editor. I want to add code assist to it, I am able to add code assist for keywords and static expressions. I have to add code assistance for Identifiers e.g. in following code:

var myidentifier = 4;

In some other line if I have use that identifier, then the editor should provide the code assistance to the identifier. Can anyone tell me, how I can achieve this functionality.

 

Thanks

Ishan Jain

 

0

Please sign in to leave a comment.