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.
Sir i need the full code to create the annotation…..as I want to create a new annotation and show it on the preferences(Annotation type). Please Help me..
I am not sure whether the annotationTypes or the markerAnnotationSpecification extension causes my annotation type to appear in the preferences (I think, the annotationTypes).
If you have the annotation type defined, you could create such annotations by attaching them to the document model; or if you also have markerAnnotationSpecification, you could simply create a marker for the file, and the corresponding annotation would be created automatically.
Hi. Could you help me, please? Where I need to create a marker? I’ve created all extension points, and marker, but it does not displayed.
If you do not inherit from a specific marker type, by default it is not displayed. Otherwise, you have to make sure that all required attributes for the presentation are set.
E.g. if you have a problem marker, you have to set the severity, marker and line number; if you want to format your text editor according to the marker, you have to set the number of the first and last characters from its character stream.
I hope, I have helped something, otherwise please clarify your question.
Oh, I get it. Thanks)
Thanks for the nice and clean write-up. This really helped me alot.
Awesome, I struggled with that for quite a time, but this got me onto the right way. I would also love to see a “HowTo add text to a second column of the Vertical ruler using annotations”, like I have seen in Subeclipse Quick Diff to add information about the editor or the version.
@Paul Ehrlich: I’m glad the article helped you a little bit. About adding a second column, I never needed to do that, but maybe I will look into it in the future and post my findings. However, you should not expect this too soon, as nowadays I do a bit different things.
Hello,
the post wasvery helpful. Ca you tell me if it is possible to add 3 different markers(same marker icon but different color) I specify the colors in the AnnotationSpecification. I tried setting different colors in the ColorPreferenceValue but they are not showing up different colors.
another post on a similar problem
http://www.eclipse.org/forums/index.php/t/14077/
Thanks
Sadly, I don’t know of any such way to assign multiple markers to the same annotation type using extension points. The method shown here is not capable of that, as the extension points used here explicitly define a one-to-one correspondence between marker and annotation types.
However, if you create the annotations programmatically (the JFace Document API has methods for that), you might be able to reuse the annotation type definition between various markers.
Thanks!! It helped me a lot!!!
Thanks for your article, I have created one marker and attached an annotationtype to it. I can create a new marker, and the editor display the marker text has a colored box. However, If I close my file and open it again, the colored box disappear.
Do I need to set any property so that while opening a new file, the editor automatically displays the marker selection? BTW, My marker extends TextMarker.
Thanks in advance,
@agrawal In general, as long as markers exist, their corresponding annotations should appear automatically. However, if you restart your Eclipse instance, the persistent property of the marker governs whether the marker is saved or not (and thus might result in the removal of the annotation as well).
If this is not the case, I would look at the marker lifecycle (e.g. can the opening or the closing of an editor remove markers – if yes, it is a fishy design, and can cause such issues).
@Ujhelyi, thanks for your reply. In my case, the markers are persistent. If I close file/eclipse and open it again, I can see the markers in marker view. However, the problem is with annotations, somehow the editor won’t display the annotation associated with the markers after restart.
thanks,
I’m sorry then, but I have no idea what might have gone wrong. However, if you find out what the issue was, I am interested in it.
I would like to thank you. Without this tutorial I probably would be able to make. Thanks again.
Thanks for your article; it’s been very useful. I have manage to create my own marker/annotation that is displayed in the property page. When I change the display attributes and apply the changes the view is not updated: I need to close the editor and reopen it to see the marker with the new attributes. I don’t know what/where refresh the editors when the apply button is clicked.
@Joaquin I am sorry, but I don’t know how exactly to update the marker/annotation display in the Property sheet, but I guess, some manual refresh is required (e.g. by listening to the appearance of annotations).