bobbylight / RSyntaxTextArea

A syntax highlighting, code folding text editor for Java Swing applications.
BSD 3-Clause "New" or "Revised" License
1.12k stars 259 forks source link

Better support for non-standard syntax based on a custom TokenMaker #548

Open ptorngren opened 5 months ago

ptorngren commented 5 months ago

Describe the solution you'd like I'd like to set the syntax based on a custom TokenMaker with a specific syntax style key that is assigned both to the RSyntaxTextArea and the RSyntaxDocument.

Are there any workarounds? Not really. RSyntaxDocument.setSyntaxStyle(TokenMaker) always assigns the style key text/unknown and RSyntaxDocument.setSyntaxStyle(String) always assigns a TokenMaker that is fetched from the tokenMakerFactoryusing the style key only.

Additional context As stated in the javadoc for RSyntaxDocument.setSyntaxStyle(TokenMaker), this is the recommended method to call if you've created a custom token maker for a language not normally supported by RSyntaxTextArea.

Alas, there is no way to call the recommended method AND register a style key on the document, and there is no way to set the style key on the editor without also calling RSyntaxDocument.setSyntaxStyle(styleKey) and consequently setting a registered TokenMaker on the document. There is no way to call the recommended method without making the text area and the document hold different style keys, which effectively invalidates any items registered for a specific style in the editor (eg the FoldParserManager).

A simple fix would be to add a method that sets a TokenMaker and a style key to both the RSyntaxTextArea and RSyntaxDocument

Sample code

RSyntaxDocument

public void setSyntaxStyle(TokenMaker tokenMaker, String styleKey) {
   this.tokenMaker = tokenMaker;
   updateSyntaxHighlightingInformation();
   this.syntaxStyle = styleKey;
}

RSyntaxTextArea

public void setSyntax(TokenMaker tm, String styleKey) {
   getDocument().setSyntaxStyle(tm, styleKey);

   if (!styleKey.equals(syntaxStyleKey)) {
      String oldStyle = syntaxStyleKey;
      syntaxStyleKey = styleKey;
      firePropertyChange(SYNTAX_STYLE_PROPERTY, oldStyle, styleKey);
   }
}
ptorngren commented 5 months ago

I just created a Pull Request with the desired changes.

bobbylight commented 5 months ago

@ptorngren Could you do something like this? I think this was my original idea, updating the TokenMakerFactory:

AbstractTokenMakerFactory atmf = (AbstractTokenMakerFactory)TokenMakerFactory.getDfeaultInstance();
atmf.putMapping("text/myLanguage", "com.ptorngeren.MyTokenMaker");

Or, if you don't feel great about the casting, create a custom TokenMakerFactory that delegates to the original default if its set of keys don't match the input.

ptorngren commented 4 months ago

@ptorngren Could you do something like this? I think this was my original idea, updating the TokenMakerFactory:

AbstractTokenMakerFactory atmf = (AbstractTokenMakerFactory)TokenMakerFactory.getDfeaultInstance();
atmf.putMapping("text/myLanguage", "com.ptorngeren.MyTokenMaker");

Sorry for late answer ....

Not sure, but I don't think it will do the trick. Don't remember the exact details, but we ended up calling the method I referenced for some reason. Still, even if the ATMF approach you suggest would work for us, it would still render the referenced method more or less unusable since I can never assign a style with the TokenMaker I set. It might also be the case that you need different TokenMakers for the same style, eg to handle different dialects of the same language (eg SQL).

PS: I also found a glitch in the PR I created: RSyntaxTextArea.setSyntaxEditingStyle(TokenMaker, String) only checks if the style key has changed and suppresses syntax highlighting updates if the key is unchanged. It should also check if the TokenMaker is changed; if we assign a new TokenMaker using the same style key, we still want the syntax highlighting to be updated, which the current code won't do.