DocumentationProvider helps users by showing documentation for symbols like method calls inside the editor. For the custom language tutorial, we're implementing a version of this extension point (EP) for the Simple Language that shows the key/value, the file where it is defined, and any related documentation comment.
Implement DocumentationProvider and Register the EP
Make sure the class is registered in the plugin.xml between the
extensions tags, as shown below:
Ensure That the Correct PSI Element Is Used
For the Simple Language, we consider two use-cases:
A Simple key is used inside a Java string literal, and we would like to show documentation for the key/value right from the reference inside the Java file.
The cursor is already over a key/value definition inside a Simple file, in which case we would also like to show its documentation.
To ensure that the IntelliJ Platform chooses the correct element of type
SimpleProperty when is called, we create a dummy implementation of
Now, we set a breakpoint in our dummy implementation, debug the plugin, and callfor the Simple property both in the Java file and the Simple file. We do this by placing the cursor over the key and invoking for showing the documentation.
In both cases, we find that the element provided is
SimplePropertyImpl, which is exactly what we hoped for. However, there are two drawbacks: inside a Java string, your cursor needs to be directly over
key in the string
"simple:key" to make Quick Documentation work. Since the Simple Language only allows for one property per string, it would be nice if Quick Documentation worked no matter where your cursor was positioned in the string as long as the string contained a Simple property. Inside a Simple file, the situation is similar, and calling only works when the cursor is positioned on the key.
Please refer to the Addendum below, which explains how to improve on this situation by additionally overriding
Extract Documentation Comments from Key/Value Definitions
SimpleProperty elements will provide us with their key and value, we have no direct access to a possible comment that is preceding the key/value definition. Since we would like to show this comment in the documentation as well, we need a small helper function that extracts the text from the comment. This function will reside in the
SimpleUtil class and will find for instance the comment preceding
apikey in the following short example:
The following implementation will check if there is any comment preceding a
SimpleProperty, and if there is, it will collect all comment lines until it reaches either the previous key/value definition or the beginning of the file. One caveat is that since we're collecting the comment lines backwards, we need to reverse the list before joining them into a single string. A simple regex is used to remove the leading hash characters and whitespaces from each line.
Render the Documentation
With easy ways to access the key, the value, the file, and a possible documentation comment, we now have everything in place to provide a useful implementation of
The creation of the rendered documentation is done in a separate method for clarity. It uses
DocumentationMarkup to align and format the contents.
addKeyValueSection() method used is just a small helper function to reduce repetition.
After implementing all the steps above, the IDE will show the rendered documentation for a Simple key when called with.
Implement Additional Functionality
We can provide implementations for additional functionality that comes with a
DocumentationProvider. For instance, when simply hovering the mouse over the code, it also shows documentation after a short delay. It's not necessary that this popup show the exact same information as when calling Quick Documentation, but for the purpose of this tutorial, we'll do just that.
When the mouse hovers over code with Ctrl/Cmd pressed, the IDE shows navigation information of the symbol under the cursor, such as its namespace or package. The implementation below will show the Simple key and the file where it is defined.
SimpleProperty and no additional work needs to be done. In other circumstances, you can override
getDocumentationElementForLookupItem()and return the correct PSI element.
Addendum: Choosing a Better Target Element
To be able to callfor Simple properties in all places of a Java string literal, two steps are required:
The extension point needs to be changed from
documentationProviderbecause only then the Simple DocumentationProvider is called for PSI elements with a different language.
getCustomDocumentationElement()method needs to be implemented to find the correct target PSI element for creating the documentation.
Therefore, the current version of the code could be extended to check whether
PsiReference functionalities to determine the correct target element. This allows getting documentation for a Simple property no matter where it was called inside a Java string literal or a Simple property definition.