Introduction
Editor handing in IntelliJ can be confusing at times. There are several different types of editors and several layers of abstraction to handle the content of files. An editor is one of them.
A plugin might want to enhance an editor’s UI and needs to attach to newly created editors. Resources are usually released when an editor is closed and a plugin needs a way to track this, as well.
This post introduces the basic editor concepts and lists the different ways to track open and close events of the different types of editors.
Concepts & classes
com.intellij.openapi.fileEditor.FileEditor
(Link to github.com)- The fundamental interface which is implemented to provide an editor for a VirtualFile.
com.intellij.openapi.fileEditor.FileEditorManager
(Link to github.com)- The class to work with editors . Use it to retrieve, open, close, track and modify editors. It mostly uses
FileEditor
but also offers access to text editors of typeEditor
. This class should be sufficient for most tasks.com.intellij.openapi.fileEditor.ex.FileEditorManagerEx
extendsFileEditorManager
and provides ways to work with splitted editors and editor tabs, among other things. com.intellij.openapi.editor.Editor
(Link to github.com)- An interface which specializes for text files. The interface
com.intellij.openapi.fileEditor.TextEditor
extends theFileEditor
interface above and links it to the correspondingEditor
instance.Editor
does not extend theFileEditor
interface. com.intellij.openapi.editor.Document
(Link to github.com)- A document provides high-level access to the content of a VirtualFile. An
Editor
displays and modifies a document and provides
Tracking editors
There are several types of editors and several ways to track them. More basic handling could be done by tracking FileEditors, more advanced features can be added to instances of Editor after tracking them.
Tracking file editors of type FileEditor
Open and close events are tracked using the message bus, the corresponding topic is FileEditorManagerListener.FILE_EDITOR_MANAGER
.
The used listener class is com.intellij.openapi.fileEditor.FileEditorManagerListener
. If you just want to track newly opened and closed editors then just implement the methods fileOpened(...)
and fileClosed(...)
.
More advanced tracking is available by implementing the method selectionChanged(...)
. It allows you to react to newly created editors, closed editors and changes of the currently active editor. If you use it then you don’t have to implement fileOpened(...)
and fileClosed(...)
because both are called in addition to selectionChanged(...)
.
A sample component which tracks editors using the message bus is available as EditorStatusComponent on github.com.
Tracking text editors of type Editor
Document editors, i.e. instances of Editor
, are created by com.intellij.openapi.editor.EditorFactory
. This factory offers a listener to be notified when a new editor was created or an existing editor was released. Use addEditorFactoryListener()
to register your listener.
Listeners implement com.intellij.openapi.editor.event.EditorFactoryListener
. If you need to track properties of an editor, e.g. the caret position of the current selection, then add your editor listeners in EditorFactoryListener#editorCreated(...)
.
The generic editor event multicaster com.intellij.openapi.editor.event.EditorEventMulticaster
is a central place to track the variours kinds of Editor events. An instance is returned by EditorFactory#getEventMulticaster()
.
Accessing an editor’s Document
Please remember that a document is only available for text files. Instances of Document
and PsiFile
are not available for binary files like images.
Use com.intellij.openapi.fileEditor.FileDocumentManager
to retrieve the document which belongs to a VirtualFile
which is shown in the currently visible FileEditor
.
Instances of PsiFile
are managed by com.intellij.psi.PsiDocumentManager
, use it to the PsiFile
for a given Document
.
Accessing an editor’s VirtualFile
The VirtualFile
of a FileEditor
can be retrieved by calling FileEditorManagerEx#getFile(FileEditor)
.
The VirtualFile
of Editor
is returned by FileDocumentManager#getFile(Document)
, the document is available as a property of the editor.
Links
- Sample plugin to demonstrate editor handling
- intellij-editor-open-close (github.com)
- High-level overview of IntelliJ’s editor architecture
- Architectural overview (jetbrains.org)