EditorActionManager is not getting hit in between auto-closed parantheses


In my plugin I've registered an action handler to do something when the tab key is hit:

editorActionManager.setActionHandler(ACTION_EDITOR_TAB, EditorActionTabHandler(oldTabHandler))

This works well in most circumstances, but I noticed that if my caret is between two auto-closed characters (like quotes, parentheses, or braces), hitting tab simply moves my caret past the closed character and doesn't ever hit my action handler. 

For example, suppose I type (where | represents my caret / cursor)

x = (|

My IDE automatically inserts a closing parenthesis:

x = (|)

Now when I hit tab, the caret is moved to the right of the parenthesis:

x = ()|

but my action handler is never called. Any idea why?


I guess I handled this by also registering an action handler for ACTION_BRACE_OR_QUOTE_OUT



Could you please clarify the last message? Did you solve the problem? If so, how did you do it with ACTION_BRACE_OR_QUOTE_OUT?


I did solve the problem. I now have two action handlers, one that responds to ACTION_EDITOR_TAB and one that responds to ACTION_BRACE_OR_QUOTE_OUT.

editorActionManager.setActionHandler(ACTION_EDITOR_TAB, EditorActionTabHandler(oldTabHandler))
editorActionManager.setActionHandler(ACTION_BRACE_OR_QUOTE_OUT, EditorActionTabOutHandler(oldBraceOrQuoteOutHandler))

The EditorActionTabOutHandler looks like this:

class EditorActionTabOutHandler(old: EditorActionHandler) : EditorActionHandler() {
    private val oldHandler = old
    override fun doExecute(editor: Editor, caret: Caret?, dataContext: DataContext?) {
      if (/* plugin specific logic */) {
/* handle TAB command */
        oldHandler.execute(editor, caret, dataContext)

    override fun isEnabledForCaret(
        editor: Editor,
        caret: Caret,
        dataContext: DataContext?
    ): Boolean {
        val caretOffset: Int = caret.offset
        val isTabOut = TabOutScopesTracker.getInstance().hasScopeEndingAt(editor, caretOffset)
      val shouldHandleTabCommand = /* plugin specific logic */
      return isTabOut || shouldHandleTabCommand

So now when a user hits Tab in a situation where it would normally invoke the ACTION_BRACE_OR_QUOTE_OUT handler, it hits this handler instead which checks if my plugin should handle the tab. If it shouldn't, it lets the Tab Out action happen. Hopefully that makes sense.


Please sign in to leave a comment.