How do I implement code completion from strings without PSI?

Answered
I need to show autocomplete popup menu like this 
 
 
after the certain char pattern typed. I do not work with PSI and know what to show,
i.e. already have a list of strings for autocomplete menu for example A, B, C.
 
I tried to add the following
 
resultSet.addElement(LookupElementBuilder.create("A"));
resultSet.addElement(LookupElementBuilder.create("B"));
resultSet.addElement(LookupElementBuilder.create("C"));
 
into addCompletions fucntion of your sample class SimpleCompletionContributor, but no popup menu was shown, although the code was executed.
Also did the same thing as in MavenPropertyCompletionContributor overriding fillCompletionVariants and setting the same list there also gave me no popup shown, although the code was executed.
 
Of course one can extend TypedHandlerDelegate and show there smth like:
JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep<String>
But it won't generate the panel like in the screenshot.
 
Could anyone give a hint how it can be easily implemented without all that PSI stuff involved?
0
12 comments

Viacheslav,

In the Completion Contributor section in the IntelliJ SDK Docs, there is a demo completion contributor described, which implements such feature for the Simple example language.

I assume that you're trying to do the same but for the existing language, right? You'll need to alter the extend method's second argument, which is a place - context for your completion - to match your requirements. You can use the PsiViewer plugin to track the correct PSI elements.

 

0

Hi Jakub,

 
Yes, I'm working with the existing language (Json).
I've tried different code combinations using extend and never saw the popup.
 
For example in a json file after "abc": I would expect the popup.
In the PsiViewer it is a JsonProperty with name "abc",
 
 
so here is my code:
 
<completion.contributor language="JSON" implementationClass="my class here"/>
 
final String ABC_KEY = "abc";
extend(CompletionType.BASIC, psiElement(JsonProperty.class).withName(ABC_KEY).withLanguage(JsonLanguage.INSTANCE),
 
new CompletionProvider<CompletionParameters>() {
public void addCompletions(@NotNull CompletionParameters parameters, @NotNull ProcessingContext context, @NotNull CompletionResultSet resultSet) {
resultSet.addElement(LookupElementBuilder.create("Hello"));
 
0

Viacheslav,

Sorry for the late reply. Can I ask you to provide some repository with an example so I'll be able to debug it locally?

0

I prepared a simple IntelliJ Platform Plugin project here

0

Completion provided by your example works out of the box in the second scenario when I start typing H letter:

Just to sort it out - you expect to provide Hello/Hello2/Hello3 values as a value of the property abc, like:

{ "abc": "Hello" }

or to suggest the key

{ "abcHello": ... }

?

0

Yes, indeed, with typed char H it works! But what about the first case?

Expectation is that after "abc": is typed there is a popup shown with Hello* items to choose from (some items may not start with the same letter in general case).

Can it be implemented then?

0

Try with setting the following pattern as a second parameter for the extend method:

psiElement()
.afterLeaf(psiElement(JsonElementTypes.COLON).afterLeaf("\"abc\""))
.withSuperParent(2, JsonProperty.class);

1

Yes, it works as expected, thank you very much for assistance.

0
Seems like addCompletions is triggered only when a char or digit is typed, 
not a special char like # for example. Although extend pattern remains the same in both cases.
How can I force the contributor to accept # or any other special char?
 
Also if I type any char contained in the popup items it will be shown.
Should I use something like string().startsWith() to fix that or it is somehow configurable?
 
0

This is something that you may control inside of the addCompletions method. Test the elements that you're adding to the resultSet against the resultSet.getPrefixMatcher(), like:

List<String> elements = ContainerUtil.immutableList("Hello", "Hello2", "Hello3");


String prefix = resultSet.getPrefixMatcher().getPrefix().toLowerCase();
for (String element : elements) {
if (element.toLowerCase().startsWith(prefix)) {
resultSet.addElement(LookupElementBuilder.create(element));
}
}
0
Thanks, PrefixMatcher can solve the second issue.
However the contributor still doesn't accept special chars, can't trigger addCompletions
and even getPrefixMatcher().getPrefix() ignores #/.
Is there a way to configure it?
0

I found GroovyReferenceCharFilter example with acceptChar method.

Hope it is the solution.

0

Please sign in to leave a comment.