Completion EditorTextField with PsiElement and unique text structure

Answered

Hi,
I have two text fields in a dialog for which I want auto-completion based on the context of the parent editor. I've been digging into TextFieldWithAutoCompletion and TextFieldWithCompletion but couldn't find a way to implement what I need.

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...

I also have another text field with a similar requirement however it should show an expression like this:

this text shouldn't be completed {thisIsJavaCode.showCompletion()} this is no longer Java code and shouldn't show completion.

Is it possible to create a text field like that and if so how?

Thanks!

7 comments
Comment actions Permalink

BTW I also tried this which should work according to the docs but I get no code completion:

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);
format = new EditorTextField(PsiDocumentManager.getInstance(currentEditor.getProject()).getDocument(fragment),
currentEditor.getProject(),
FileTypes.PLAIN_TEXT, false, true);
condition = new EditorTextField(PsiDocumentManager.getInstance(currentEditor.getProject()).getDocument(fragment),
currentEditor.getProject(),
FileTypes.PLAIN_TEXT, false, true);
1
Comment actions Permalink

FYI there's a partial answer for this here. It seems I misses the type of the document (stupid) and the last value for the expression code fragment argument. The question about the {} expression is still on the table as well as new followups. Since I have two fields how do I give them different values with this strategy?

Can a document be cloned?

How do I initialize the field with a value?

0
Comment actions Permalink

I'm still stuck on this second one. I tried stack overflow too and have a bounty there: https://stackoverflow.com/questions/59476930/limit-text-field-completion-to-a-specific-set-of-segments-within-intellij-plugin

Should I create a new language implementation for this?

Do I need to use grammar-kit to do that or just look at it for reference. I'm not really sure where to begin.

0
Comment actions Permalink

You could create a very simple "dummy" language that has special elements for text "{...}" that will use Java instead of your dummy (plain text) language.

0
Comment actions Permalink

The "very simple" part is the part that stumps me here. I'm guessing this would be trivial since I can probably just use the pre-existing Java syntax support but I'm not sure how to do this "simply". In this answer https://stackoverflow.com/questions/59443789/text-field-with-standard-psielement-auto-completion-in-intellij-plugin the person who answered indicated that it's simple too but I must be looking in a completely wrong direction here...

0
Comment actions Permalink

Sorry for delay. You could inject existing Java Language in the "{...}" part of your custom language via com.intellij.lang.injection.MultiHostInjector

0
Comment actions Permalink

Thanks!

This looks perfect but I can't understand how this fits with the text field code I have. Specifically:

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);

Here I have a field that points to a specific line of code. The expression shouldn't just be "Java" but rather Java that would fit in the context of that Java file.

0

Please sign in to leave a comment.