Syntax Highlighting and Error Highlighting
The class used to specify how a particular range of text should be highlighted is called
TextAttributesKey. An instance of this class is created for every distinct type of item that should be highlighted (keyword, number, string, etc.). The
TextAttributesKey defines the default attributes applied to items of the corresponding type (for example, keywords are bold, numbers are blue, strings are bold and green). Highlighting from multiple
TextAttributesKey items can be layered - for example, one key may define an item's boldness and another color.
The mapping of the
TextAttributesKey to specific attributes used in an editor is defined by the
EditorColorsScheme class. It can be configured by the user by providing an implementation of
ColorSettingPage registered in
com.intellij.colorSettingsPage extension point.
The Export to HTML feature uses the same syntax highlighting mechanism as the editor, so it will work automatically for custom languages, which provide a syntax highlighter.
- Custom Language Support Tutorial: Color Settings Page
The syntax and error highlighting are performed on multiple levels: Lexer, Parser, and (External) Annotator.
The first syntax highlighting level is based on the lexer output and is provided through the
SyntaxHighlighter interface. The syntax highlighter returns the
TextAttributesKey instances for each token type, which needs special highlighting. For highlighting lexer errors, the standard
TextAttributesKey for bad characters
HighlighterColors.BAD_CHARACTER can be used.
The second level of error highlighting happens during parsing. If a particular sequence of tokens is invalid according to the grammar of the language, the
PsiBuilder.error() method can highlight the invalid tokens and display an error message showing why they are not valid.
The third level of highlighting is performed through the
Annotator interface. A plugin can register one or more annotators in the
com.intellij.annotator extension point, and these annotators are called during the background highlighting pass to process the elements in the custom language's PSI tree.
Annotators can analyze not only the syntax, but also the semantics using PSI, and thus can provide much more complex syntax and error highlighting logic. The annotator can also provide quick fixes to problems it detects. When the file is changed, the annotator is called incrementally to process only changed elements in the PSI tree.
See Inspections topic in IntelliJ Platform UI Guidelines on how to write message texts for highlighting/quick fixes.
To highlight a region of text as a warning or error (2020.1 and later):
In previous versions, call
createErrorAnnotation() on the
AnnotationHolder, and optionally calls
registerFix() on the returned
Annotation object to add a quick fix for the error or warning.
To apply additional syntax highlighting (2020.1 and later):
In previous versions, call
AnnotationHolder.createInfoAnnotation() with an empty message and then
Finally, if the custom language employs external tools for validating files in the language (for example, uses the Xerces library for XML schema validation), it can provide an implementation of the
ExternalAnnotator interface and register it in
com.intellij.externalAnnotator extension point (
language attribute must be specified).
ExternalAnnotator highlighting has the lowest priority and is invoked only after all other background processing has completed. It uses the same
AnnotationHolder interface for converting the output of the external tool into editor highlighting.
To skip running specific
ExternalAnnotator for given file, register
ExternalAnnotatorsFilter extension in
com.intellij.daemon.externalAnnotatorsFilter extension point.