3. Handling Editor Events
The previous tutorial Editor Coordinate Systems described working with caret coordinate systems in an editor window. Caret position was discussed in terms of Logical Position, Visual Position, and Offset. This tutorial introduces the Editor Action system, which handles actions activated by keystroke events in the editor. Two classes from the editor_basics code sample are used to illustrate:
Using an IntelliJ Platform
EditorActionHandlerto manipulate a caret.
Creating and registering a custom
TypedActionHandlerto intercept keystrokes and change the document.
Using an IntelliJ Platform EditorActionHandler
In this portion of the tutorial, the editor_basics code sample is used to demonstrate cloning an existing caret. A custom action class will use
EditorActionManager to access a specific
EditorActionHandler for caret cloning. The
editor_basics code sample adds an Editor Add Caret menu item to the editor context menu:
Creating the Menu Action Class
The source code for the Java action class is EditorHandlerIllustration, a subclass of
AnAction. For more information about creating action classes, see the Actions Tutorial which covers the topic in depth.
EditorHandlerIllustration action is registered in the editor_basic
plugin.xml file. Note that this action class is registered to appear on the Editor context menu.
Setting Visibility for the Action Menu Entry
Under what conditions should the
EditorHandlerIllustration action be capable of cloning a caret? Only if the following conditions are met in the
A project is open,
An editor is available,
There is at least one caret active in the editor.
After ensuring that
Editor objects are available, the
Editor object is used to verify there is at least one caret:
Acquiring the Correct EditorActionHandler
EditorHandlerIllustration.actionPerformed() method clones the caret, it should use the appropriate IntelliJ Platform
EditorActionHandler. An instance of
EditorActionManager is required to obtain the correct
EditorActionManager class provides a static method to do this.
To request the correct
EditorActionManager, consult the
IdeActions interface for the correct constant to pass into the
EditorActionManager.getActionHandler() method. For cloning a caret below the primary caret, the constant is
ACTION_EDITOR_CLONE_CARET_BELOW. Based on that constant, the
EditorActionManager returns an instance of
CloneCaretActionHandler, a subclass of
Using an EditorActionHandler to Clone the Caret
To clone the caret requires only calling the
EditorActionHandler.execute() method and passing in the appropriate context.
Creating a Custom TypedActionHandler
TypedActionHandler interface is the basis for classes that handle keystroke events from the editor. Custom implementations of the class are registered to handle editor keystroke events, and receive a callback for each keystroke. The steps below explain how to use
TypedActionHandler to customize the behavior of the editor when keystroke events are received.
Implementing a Custom TypedActionHandler Class
First, a subclass such as
MyTypedHandler is created based on
TypedActionHandler. The class overrides the method
TypedActionHandler.execute(), which is the callback for editor keystroke events.
Implementing the Keystroke Event Handling Logic
TypedActionHandler.execute() method in
MyTypedHandler to implement the logic for handling keystroke events. This method is called every time a key is pressed when the Editor Tool Window has focus.
In the following example, the
MyTypedHandler.execute() method inserts "editor_basics\n" at the zero caret Offset position when a keystroke event occurs. As explained in Working with Text, safe modifications to the document must be in the context of a write action. So although a method on the
Document interface does the
String insertion, the write action ensures a stable context.
Registering a Custom TypedActionHandler
A custom implementation of
TypedActionHandler must be registered to replace the existing typing handler to receive editor keystroke events. The registration is done through the
As is shown in the snippet below, the
EditorActionManager is used to get access to the
TypedAction class. The method
TypedAction.setupHandler() is used to register the custom
Placing the registration code in the
EditorHandlerIllustration class is somewhat arbitrary in the sense that the registration of
MyTypedHandler has nothing to do with the
EditorHandlerIllustration class. However, the
EditorHandlerIllustration class is convenient because as an action it gets instantiated at application startup. On instantiation, the
static block of code in
EditorHandlerIllustration gets evaluated. In the
editor_basics code sample any of the
AnAction derived classes would work for registering