I am trying to create a plugin which monitors the change in a document.
I am interested in adding a marker in the text editor when the document is changed.
I observed that for the class - IDocumentListener the method documentChanged is getting called whenever there is a change.
However, I am unable to implement this as plugin as this interface does not have an extension point.
Can you help me with extending IDocumentListener ?
It's instructive to look at an existing open-source plugin to see how it does a similar task. Let's look at Bracketeer as an example.
The starting point is a class that implements org.eclipse.core.runtime.Plugin
. For plugins that have a UI, it's useful to implement org.eclipse.ui.plugin.AbstractUIPlugin
which provides additional functionality. This class is commonly called the "activator", and indeed in Bracketeer it's called Activator
. It's registered as the plugin's activator class in the MANIFEST.MF
file using a line like:
Bundle-Activator: com.chookapp.org.bracketeer.Activator
The Activator
class overrides Plugin.start()
, which will be called by the runtime when the plugin is loaded. The overridden start()
method sets up a part listener.
The part listener is a class that implements the IPartListener2
interface. In Bracketeer, it's called PartListener
. On setup, it calls PlatformUI.getWorkbench()
to get a hold of the IWorkbench
, and IWorkbench.getWorkbenchWindows()
to get a list of currently open windows (at the time the plugin starts). It then registers itself with each window via IWorkbenchWindow.getPartService().addPartListener()
.
In addition, to handle new windows being opened after the plugin is loaded, PartListener
also implements IWindowListener
, and registers itself as a window listener via IWorkbench.addWindowListener()
. This allows the PartListener
to handle new windows opening by overriding IWindowListener.windowOpened()
, and register itself as a part listener for the new windows.
As a part listener, PartListener
overrides IPartListener2.partActivated()
and partOpened()
to handle workbench parts (which include editors) being opened or activated. In those methods, it checks whether the part is an IEditorPart
; if so, it gets a hold of the editor part's document (see PartListener.getPartDocument()
), which is an IDocument
.
Finally, having an IDocument
, it can register any IDocumentListener
it wants via IDocument.addDocumentListener(IDocumentListener)
.
(There are some details I'm glossing over, such as manually calling partActivated()
for every workbench part that's already open at the time the plugin is started. See the Bracketeer code for the full details.)
All of these are public APIs, and none of this requires any extension point to be implemented.