Tracking file and document editors
Last updated:
Joachim Ansorg

Abstract. This post introduces the different kinds of editors and explains how open and close events can be tracked.

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 type Editor. This class should be sufficient for most tasks. com.intellij.openapi.fileEditor.ex.FileEditorManagerEx extends FileEditorManager 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 the FileEditor interface above and links it to the corresponding Editor instance. Editor does not extend the FileEditor 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 editor, 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)