CodeCompletion not execute after set language of LanguageTextField

Answered

Please see the following code,  if I set PlainTextLanguage.INSTANCE as the language, codeCompletion will work, but if I set Json5Language.INSTANCE, codeCompletion not work. It always show no suggestions.

So how to make codeCompletion work even I set Json5Language.INSTANCE as the language

TextFieldWithAutoCompletion.StringsCompletionProvider completionProvider = new com.intellij.ui.TextFieldWithAutoCompletion.StringsCompletionProvider(Lists.newArrayList("a", "b"), AllIcons.Nodes.Method);

new com.intellij.ui.LanguageTextField(Json5Language.INSTANCE,project,"",completionProvider,false);

IDEA: 2023.3

1
5 comments
Official comment

What happens is that the StringsCompletionProvider that you create works only in files that are plain text. More specifically, when you hit completion in your text field, the framework collects all completion contributors that would be appropriate in the current context. This happens here and the “parameters” can take the language into account.

So, when you define your StringsCompletionProvider and use it in a JSON field, your completion is just not taken into account at the above point and your completions will not be suggested. I'm not sure if there is a way to fix this within this framework right now. All examples I checked use plain text when they have completion and don't have (additional) completion defined when they use a different language than plain text.

It also means that when you use LanguageTextField with any other language than PlainText, you will run into the same problem. However, all other completions for these languages work. This leads me to a possible solution if you really need additional completion in this text field. You can define just a regular completion provider and try to restrict it so it is only invoked in your text field.

Your text field:

override fun createCenterPanel(): JComponent {
    return LanguageTextField(
        Json5Language.INSTANCE, project, "", false
    )
}

The completion provider and contributor

class MyJsonCompletion : CompletionContributor(), DumbAware {
    init {
        // Here, you could use an ElementPattern that tries to restrict completion
        // to your text field by e.g., making it only work in a virtual file with the name "Dummy.json5"
        val matchTextFieldFileOnly = psiElement().inVirtualFile(virtualFile().withName("Dummy.json5"))

        extend(CompletionType.BASIC, matchTextFieldFileOnly,
            object : CompletionProvider<CompletionParameters>() {
                override fun addCompletions(
                    parameters: CompletionParameters,
                    context: ProcessingContext,
                    result: CompletionResultSet
                ) {
                    val completions = arrayOf("aGoodCompletion", "betterCompletion")
                    for (completion in completions) {
                        result.addElement(LookupElementBuilder.create(completion).bold())
                    }
                }
            }
        )
    }
}

Register the contributor in your plugin.xml

<completion.contributor
        id="MyJsonCompletion"
        implementationClass="XXX.YYY.MyJsonCompletion"
        language="JSON"/>

The code doesn't compile. Please post the actual working snippet of your issue.
About missing completion, it might be that builtin JSON completion providers interfere here.

0

Full  demo code

import com.google.common.collect.Lists;
import com.intellij.icons.AllIcons;
import com.intellij.json.json5.Json5Language;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.ui.TextFieldWithAutoCompletion;
import com.intellij.util.textCompletion.TextCompletionUtil;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;

public class DemoDialogWrapper extends DialogWrapper {
    private final Project project;

    public DemoDialogWrapper(@Nullable Project project) {
        super(project, false);
        this.project = project;
        init();
        setSize(400, 300);
        setTitle("demo");
    }


    @Override
    protected @Nullable JComponent createCenterPanel() {
        TextFieldWithAutoCompletion.StringsCompletionProvider completionProvider = new TextFieldWithAutoCompletion.StringsCompletionProvider(Lists.newArrayList("a", "b"), AllIcons.Nodes.Method);
        TextCompletionUtil.DocumentWithCompletionCreator documentWithCompletionCreator = new TextCompletionUtil.DocumentWithCompletionCreator(completionProvider, false, false);
        return new com.intellij.ui.LanguageTextField(com.intellij.json.json5.Json5Language.INSTANCE, project, "", documentWithCompletionCreator, false);
        
        //Change Json5Language.INSTANCE to com.intellij.openapi.fileTypes.PlainTextLanguage 
        //CodeCompletion works

    }
}

 

 

 

 

0

Sorry for delay, investigating.

0

A few days ago, I finally used your solution, which meets my current needs.

Still thank you very much. @Patrick Scheibe

0

Please sign in to leave a comment.