Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Text Field with Standard PsiElement Auto Completion in IntelliJ Plugin

I'm trying to create a simple text field with auto completion for my IntelliJ plugin. I think this should be pretty simple but so far I've run into dead ends...

E.g. this should work as far as I understand:

EditorTextField format = new TextFieldWithCompletion(currentEditor.getProject(),
                provider,
                "",
                true,
                true,
                true);

The problem is the provider. I'd expect to see a provider that isn't a list provider. I just want to show the completion matching the current line in the editor cursor so I'd like the full completion dialog and not just a short list of options.

I also looked at TextFieldWithAutoCompletion but it seems to be designed for hardcoded string values instead of free form completion.

I just want the standard Java/Kotlin completion. Not a custom list or anything like that. I saw some discussion with replacing the document of the text field but I couldn't get that to work either. I have a PsiExpressionCodeFragment and would expect there to be a completion provider that accepts that but I can't find it.

For reference what I want to do is something very similar to the conditional statement in the breakpoint dialog.

Another approach illustrated here is:

JavaCodeFragmentFactory jcff = JavaCodeFragmentFactory.getInstance(currentEditor.getProject());
PsiFile pf = PsiDocumentManager.getInstance(currentEditor.getProject()).getPsiFile(currentEditor.getDocument());
PsiElement psiElement = pf.findElementAt(currentEditor.getCaretModel().getOffset());
PsiExpressionCodeFragment fragment = jcff.createExpressionCodeFragment("", psiElement,null, false);
EditorTextField f = new EditorTextField(PsiDocumentManager.getInstance(currentEditor.getProject()).getDocument(fragment),
        currentEditor.getProject(),
        FileTypes.PLAIN_TEXT, false, true);

This loads the UI but doesn't popup code completion no matter what I type.

like image 237
Shai Almog Avatar asked Nov 07 '22 11:11

Shai Almog


1 Answers

The trick is to create an editor that contains an instance of the Document. And this document refers to a language and a psi element context:

JPanel panel = new JPanel();

// Just detect an element under caret for context
PsiFile psiFile = PsiDocumentManager.getInstance(editor.getProject()).getPsiFile(editor.getDocument());
PsiElement element = psiFile.findElementAt(editor.getCaretModel().getOffset());

PsiExpressionCodeFragment code = JavaCodeFragmentFactory.getInstance(editor.getProject()).createExpressionCodeFragment("", element, null, true);
Document document = PsiDocumentManager.getInstance(editor.getProject()).getDocument(code);

EditorTextField myInput = new EditorTextField(document, editor.getProject(), JavaFileType.INSTANCE);
myInput.setPreferredWidth(300);

panel.add(myInput);

return panel;

Here the caret used to be located on dsa5, so the dsa5 variable is not yet visible for the completion.

enter image description here

like image 103
Feedforward Avatar answered Nov 30 '22 11:11

Feedforward