-
Notifications
You must be signed in to change notification settings - Fork 258
Adding Code Folding for a new Language
The RSyntaxTextArea library includes a FoldParserManager class. The FoldParserManager
is a singleton that maps identifiers for syntax styles (e.g. from SyntaxConstants to FoldParsers). To add or modify code folding logic for a language, simply call FoldParserManager.get().addFoldParserMapping()
with the appropriate arguments.
Let's say you're adding support for a custom language called "Foo
". You've already added syntax highlighting for Foo
, as described in the previous section. To recap:
AbstractTokenMakerFactory atmf = (AbstractTokenMakerFactory)TokenMakerFactory.getDefaultInstance();
atmf.putMapping("text/foo", "org.mycompany.rsta.FooTokenMaker");
textArea.setSyntaxEditingStyle("text/foo");
Say that the Foo
language has the same basic structure as C-like languages - curly braces denote code blocks, and block comments are denoted by /* ... */
. In that case, you can simply use the built-in CurlyFoldParser class. It handles code folding for such languages, and provides a few configuration options as well. You would register it with the FoldParserManager
to be used whenever an editor is editing Foo
code like so:
FoldParserManager.get().addFoldParserMapping("text/foo", new CurlyFoldParser());
After doing this, any instance of RSyntaxTextArea
configured to syntax highlight Foo
will also provide code folding (assuming code folding is enabled, of course).
There are also built-in fold parsers for HTML, JSON, Latex, Lisp, Python, XML, and YAML. To learn more, check the Javadoc for the folding
package.
If your language has a unique syntax, you may need to create a custom FoldParser
implementation for it. The difficulty of doing this is in proportion to how complex your language's syntax is (actually, how difficult it is to identify "foldable regions" of code).
The FoldParser interface only declares 1 method, getFolds()
, which returns all foldable regions in the text area's content. This method is called each time the editor's content is modified (after a small delay, so many quick edits don't cause many re-parsings for folds). In this method, your class should simply scan the RSyntaxTextArea
's entire document and return a list of Folds that denotes the top-level foldable regions. RSTA is smart enough to remember the state of folds between parsings, so if you return the same set multiple times, regions that are folded stay folded, and those that are expanded stay expanded. Also, if a collapsed foldable region is removed by an edit, the corresponding content in the editor is expanded automatically. All you care about is returning the list of folds, not determining their state.
There are built-in FoldParser
implementations for C-style languages, HTML/JSP/PHP, JSON, XML, and more. You can use any of these as examples for the basis for your custom fold parser.