Motto:
I have discovered a truly remarkable proof of this theorem which this margin is too small to contain.
Pierre de Fermat
During the development of editors it is often needed to display additional information next to the document, such as error markers, search results or various coverage metrics. However, it is not a good idea to hardcode the list of supported markers during development, as the best ideas will be introduced by others – who do not want to have anything to do with our editor.
Luckily, Eclipse provides a simple way to attach markers to documents without explicit support needed from the editor developer: the markers (and annotations) created by their corresponding extensions are stored independently from the document, so these additions can be made without disturbing any existing user of the files.
As I described it in my previous post about error markers, such markers can be defined creating an extension for the extension point org.eclipse.core.resources.marker
, and then using the IResource.createMarker()
method to create the marker instances as needed. Then using some magic it can be displayed as the yellow or red wriggly lines during the text.
Other markers (and annotations) can be created in similarly: we create our own marker type, and register an annotation type for it, and the platform manages the rest. In my case I wanted to represent a calculated set of program statements similar to the code coverage display used by the EclEmma tool: the covered statements are highlighted with the green background.
To support such a display, I created a new marker type, that is a text marker; and to make the lifecycle-management easier, I did not set it persistent. This has been reached using the following code:
<extension id="org.eclipse.viatra2.slicemarker" name="GTASM Slice" point="org.eclipse.core.resources.markers"> <super type="org.eclipse.core.resources.textmarker"> </super> </extension>
The most important difference between this marker and the one defined in the previous Markers and Annotations post is that the newly defined marker is not a problem marker, but a simple text marker. This means, the created marker will not show in the Problems view (that is nice – we don’t want to display problems now), and no default annotation is created (that will need fixing).
In theory it is possible to create annotations programmatically together with the markers, but in practice it is really a bad idea. First of all, annotations are created for the document model (thus assuming an open editor and a code dependency to that document model), are never persisted, and the resulting code fails indeterministically (I once debugged a code like that, every annotation creation code ran correctly, but some annotations were missing; re-running the code re-added the missing ones, but sometimes removed others), so this idea will not work.
Luckily, the platform provides two extension points that can be used to automatically assign annotations to marker instances. To define an automatically generated annotation type for the markers, the org.eclipse.ui.editors.annotationTypes
extension point is used: basically a marker and an annotation ID is stored this way.
<extension point="org.eclipse.ui.editors.annotationTypes"> <type markerType="org.eclipse.viatra2.slicemarker" name="org.eclipse.viatra2.slicemarker"> </type> </extension>
To define the appearance of the created annotation the org.eclipse.ui.editors.markerAnnotationSpecification
extension point can be used. In the extensions we have to specify the annotation display methods used together with color and formatting settings.
<extension point="org.eclipse.ui.editors.markerAnnotationSpecification"> <specification annotationType="org.eclipse.viatra2.slicemarker" colorPreferenceKey="org.eclipse.viatra2.slice.color" colorPreferenceValue="192,255,192" contributesToHeader="false" highlightPreferenceKey="org.eclipse.viatra2.slice.highlight" highlightPreferenceValue="true" includeOnPreferencePage="true" label="GTASM Slice Marker" overviewRulerPreferenceKey="org.eclipse.viatra2.slice.overview" overviewRulerPreferenceValue="true" presentationLayer="0" textPreferenceKey="org.eclipse.viatra2.slice.text" textPreferenceValue="true" textStylePreferenceValue="BOX" verticalRulerPreferenceKey="org.eclipse.viatra2.slice.ruler" verticalRulerPreferenceValue="true"> </specification> </extension>
Even better, by assigning preference keys to the various settings the platform also offers the users the possibility to configure the annotations: the General/Editors/Text Editors/Annotations preference page will list our annotation, and allows setting its preference values. If the preference keys are unique (that is our responsibility 🙂 ), then creating this extension ends our work: annotations will be generated automatically, and they will be displayed in the opened text editors.
The marker creation process is entirely the same as the creation of error markers: a new marker is initialized using the IResource.createMarker(String markerId) method, and the IMarker.CHAR_START and IMarker.CHAR_END markers are set for positioning the markers.
Alltogether, the markers and annotations provide an easy way to extend existing editors with meta-information (e.g. execution state, dependencies, coverage, etc.), that can be used with a very little amount of Java programming. Sadly, the content assists for extensions is not that discoverable as the Java APIs, so a lot of experimenting and/or documentation reading is needed. Luckily, documentation is available for these extension points, so knowing their name will be enough for most cases.
So, lets hope, Eclipse gives us a big enough margin to contain our proo metainformation.