TextFieldWithAutoCompletion intercepting completion event

Answered

How can I intercept the user hitting the "enter" or "tab" key to finish the auto-completion event?

Thanks

 

0
6 comments

Normally it's done with LookupElement.handleInsert (or LookupElementBuilder.withInsertHandler). Unfortunately TextFieldWithAutoCompletionListProvider doesn't offer an easy possibility to customize that. We can provide it, or you can use a more general API (TextCompletionProvider or the most general CompletionContributor) instead, and construct lookup elements yourself.

0
Avatar
Permanently deleted user

Thanks. That sounds like a bit of work. I wonder if I can intercept the "OnFocus" event of the TextFieldWithAutoCompletion after the completion popup closes (the user hits enter/escape, etc). That would suffice for my use-case.

 

0

You could try, but be aware that focus events in IDEA/Swing are sometimes very surprising. I'd avoid them if possible. "A bit of work" is true, but it's not much. The usual way is to put some user data into your text field's editor, and then in your TextCompletionProvider/CompletionContributor check if CompletionParameters#getEditor has that user data, and add some variants.

0
Avatar
Permanently deleted user

Also, is there an example illustrating how to derive from the TextCompletionProvider in the API samples? Thanks!

 

0

I use LookupManager.addPropertyChangeListener() to monitor active lookups

import com.intellij.codeInsight.lookup.LookupListener;
import com.intellij.openapi.editor.Editor;

class LookupMonitor implements LookupListener {
    private Editor myEditor;

    private void propertyChange(PropertyChangeEvent evt) {
        if (LookupManager.PROP_ACTIVE_LOOKUP.equals(evt.getPropertyName())) {
            Editor newEditor = null;
            Editor oldEditor = null;
            if (evt.getNewValue() instanceof LookupImpl) {
                LookupImpl lookup = (LookupImpl) evt.getNewValue();
                newEditor = lookup.getEditor();
            }
            if (evt.getOldValue() instanceof LookupImpl) {
                LookupImpl lookup = (LookupImpl) evt.getOldValue();
                oldEditor = lookup.getEditor();
            }

            if (oldEditor != newEditor) {
                if (newEditor == myEditor) {
                    // lookup activated
                }
                
                if (oldEditor == myEditor) {
                    // lookup deactivated
                }
            }
        }
    }
    
    public void initComponent() {
        LookupManager.getInstance(myProject).addPropertyChangeListener(this);
    }
    
    public void disposeComponent() {
        LookupManager.getInstance(myProject).removePropertyChangeListener(this);
    }
}

You will need to add code to check whether lookup was closed on ENTER, TAB or ESCAPE. Probably the easiest way to detect this is to compare text field content when lookup is activated and after it is closed. If the content did not changed then it is ESCAPE.

0

I'm not aware of any such API samples. There are some usages in the source that you could adapt to your case. For example, here's a quite simple one: https://github.com/JetBrains/intellij-community/blob/306d705e1829bd3c74afc2489bfb7ed59d686b84/java/execution/impl/src/com/intellij/execution/MethodBrowser.java#L76

LookupListener approach can work, too, but it'll be much wordier and error-prone. BTW there's LookupListener#itemSelected which is invoked when a user pressed Enter/Tab/etc, and the key pressed can be obtained from LookupEvent#getCompletionChar.

0

Please sign in to leave a comment.