In yesterday’s e-mail we defined a selection listener to open the inspector when a particular node is selected. Today we will look at wiring up the listener so that it gets called by MPS.

We want to attach the listener to any already opened editor components. In addition, we need to find out when a new editor component is created. To avoid memory leaks, we also should detach the listener when the editor component is disposed.

MPS provides a mechanism that encapsulates these concerns and makes it easy to modify editor components at run time: editor extensions.

Editor extensions

An editor extension is an object implementing the following interface:

public interface EditorExtension {
  boolean isApplicable(@NotNull EditorComponent editorComponent);
  void install(@NotNull EditorComponent editorComponent);
  void uninstall(@NotNull EditorComponent editorComponent);
}

The isApplicable method is called to filter uninteresting editor components. In our case, for example, we don’t want to affect the editor component of the inspector itself, or of the MPS Console.

The install method is then called to let the extension attach itself to an applicable editor component. And of course, uninstall will be called to remove the extension from the component when it is being disposed of.

Editor extension registry

To be used, all editor extensions must be registered with an editor extension registry, a project-level component that implements the EditorExtensionsRegistry interface. The registry keeps track of editor extensions and will make sure that new extensions are installed both on already existing editor components and on those that will be created in the future.

The best place to register an editor extension with the registry is a project plugin. It provides two blocks, init and dispose, that will be called when the plugin is loaded and unloaded. These blocks are a natural place to put the code that registers and unregisters extensions:

Conclusion

The code is now complete. When MPS loads the solution, it will initialize the plugin for each currently open project. The plugin will register the extension. When an editor component is created, it will install all applicable extensions from the editor extension registry, including our extension. Our extension will add the selection listener that will open the inspector.

I have created a complete sample for this small series of articles and view it on GitHub.