Adding to java auto-complete options in the relevant context and at the correct position.

Hello,

I am writing a CompletionContributor for java. The contributor will contribute Class names. I had some questions around that.

1. How can I make sure that the contributor is only invoked when typing inside a class and not when typing import statements?
2. What is the difference between the different CompletionTypes - smart, basic, class_name?
3. How can I make sure that my extensions are added after all existing java completions?

The following does not seem to work

  • order="last" -> contributor not loaded
  • order="first, after javaClassName" -> throws an exception about loading order
  • order="last, before default -> contributor not loaded
  • order="last, before legacy, before default, before javaClassName" -> contributor not loaded


The following works

  • order="first" -> but all other contributors come afterward, which is undesirable


thanks
Siddharth

3 comments
Comment actions Permalink

May I ask what the purpose of the plugin is? Perhaps that's something we could add on our side.

To your questions:

1. You should check the context in your contributor yourself using CompletionParameters.getPosition() and writing a condition on the PSI tree. Simple conditions may be written using PsiJavaPatterns class.

2. Those are just different completion actions in Code | Completion menu. Most probably you need Basic.

3. You may register your contributor as "first", then invoke all other contributors:

resultSet.runRemainingContributors(parameters, true);
resultSet.stopHere();

and finally add your own items (if the context is correct). Wrap the items into PrioritizedLookupElement.withPriority(yourItem, someLowValue) so that they have low priority and are put to the end of the list.

0
Comment actions Permalink

Hi Peter,

This plugin provides class name completion options for classes not yet added to the project. We have a use case for this.

The PrioritizedLookupElement object seems to expect that one has control over all the elements in the lookup list, which is not the case - How big/small a value guarantees expected position. Also if I want an element in the beginning should I have negative values or positive values.
I experimented with Weighers too. What is the different between relevance and sorting weighers?

I want that all java completions given by IntelliJ comes first and then all of my completions should come. Both should be sorted lexicographically.

The following code does not seem to work

public class LightProjectWeigher extends CompletionWeigher {


  @Override
  public Comparable weigh(@NotNull LookupElement element, @NotNull CompletionLocation location) {
    if (element instanceof LookupItem) { // My elements do not inherit LookupItem
      return 1;
    } else {
      return -1;
    }
  }

}


Thanks
Siddharth
0
Comment actions Permalink

Which IDEA version are you targeting? 10.5, 11 or 12?

If it's for your internal purposes, then you don't need universality. And I'm sure that priority like -1000 will fulfil your needs. OTOH if you want this plugin to work in every possible case, then creating a weigher is a more effective solution. It should be a relevance weigher since IDEA >11, or sorting for 10.5. So your items may implement a special interface and in the weigher you may check the instanceof and return different values for your and all other items. Checking for our LookupItem is not universal, as there are other items.

Your sorting requirements embarrass me. We have two sorting modes: by relevance and lexicographically. Your requirement doesn't entirely fit in any of these categories. In IDEA before 11 this was literally not possible. Now it is possible in relevance sorting mode, but it's quite complicated and will destroy the fine-grained relevance sorting policy we have in Java. So I'm not sure you should go that way.

0

Please sign in to leave a comment.