API to add custom syntax styles ?

2007-12-30
2013-05-28
  • Hi Robert,
       First of all, thanks for your great work.
       I am using Rtext's TextEditorPane in an open tool under development.
       The editor is needed to highlight the EJBQL syntax. It is similar to SQL syntax, but have some custom keywords ("FETCH", "SIZE", "ELEMENTS", etc ...). I created an EJBQLTokenMaker.flex and generated the EJBQLTokenMaker.java. But the problem is that there is no way to "register" a custom syntax style (the instantiation of TokenMakers are hard coded in the RSyntaxDocument's setSyntaxStyle).
       I don't know if it is the kind of feature you want into RText, but my sugestion is to make custom syntax style addition more flexible.
       There is how I solved my problem:
      
          public class EJBQLTextEditorPane extends TextEditorPane {
              private RSyntaxDocument customDocument;
             
              public EJBQLTextEditorPane() {
                  super(false, INSERT_MODE);
                  setSyntaxHighlightingColorScheme(new SyntaxHighlightingColorScheme(true));
                  setTabsEmulated(true);
              }
         
              @Override
              public void setSyntaxEditingStyle(int style) {
                 throw new UnsupportedOperationException("Operation Disabled");
              }
         
              @Override
              public Document getDocument() {
                  if (customDocument == null) {
                      customDocument = new RSyntaxDocument(0) {
                          @Override
                          public void setSyntaxStyle(int arg0) {
                              setSyntaxStyle(new EJBQLTokenMaker());
                          }
                      };
                  }
                  return customDocument;
              }
          }

    The project was hosted at java.net yesterday, so it's still in pending aproval. When it get aproved, you can check it at https://jpaquerytool.dev.java.net/.

    * I'm not a native english speaker. Sorry about the grammar and spelling errors

     
    • Robert Futrell
      Robert Futrell
      2007-12-31

      Hi Marcelo,

      You're right, RText's syntax highlighting is not very extendable, unfortunately.  The way highlighting is actually implemented is meant to be fast, but it also makes it difficult to externally define language definitions.  I'd love to have the user able to define language scanners via XML or properties files, but at the moment I don't see the need for such a feature.

      What if we met halfway?  What if you created a scanner, such as EJBQLTokenMaker.java, and had some way to "register" it with the application?  Then you could set it like any of the built-in languages.  Something like this (purely off the top of my head):

      In SyntaxConstants.java:

         public static final int MIN_USER_SYNTAX_STYLE = 1000;

      Add a new class to keep track of user-defined languages, something like UserSyntaxStyleManager.java (probably a singleton):

         public class UserSyntaxStyleManager {

            ...

            /**
             * @return The syntaxStyle constant for the given token maker class.
             */
            public int addSyntaxStyle(String tokenMakerClassName);

            /**
             * @return The token maker registered for the given syntax style.
             * @throws IllegalArgumentException If none is registered for syntaxStyle.
             */
            public TokenMaker getTokenMakerForStyle(int syntaxStyle);

         }

      In RSyntaxDocument.java:

         public void setSyntaxStyle(int syntaxStyle) {
            if (syntaxStyle<0) {
               throw new IllegalArgumentException("syntaxStyle cannot be negative");
            }
            else if (syntaxStyle<=MAX_BUILTIN_SYNTAX_STYLE_NUMBER) {
               // Code as it currently is.
            }
            else if (syntaxStyle>=MIN_USER_SYNTAX_STYLE) {
               // This will throw an exception if no token maker is registered
               // for the specified syntaxStyle.
               tokenMaker = UserSyntaxStyleManager.getTokenMakerForStyle(syntaxStyle);
            }
            else {
               throw new IllegalArgumentException("Unsupported syntaxStyle: " + syntaxStyle);
            }
         }

      Then all you'd need to do is include your custom token maker class(es) on your application's classpath.  You could register them doing something like this:

      int ejbqlStyle = UserSyntaxStyleManager.getIntance().addSyntaxStyle("com.mycompany.EJBQLTokenMaker");

      Here, ejbqlStyle is simply an int constant >= MIN_USER_SYNTAX_STYLE that the code uses to remember your syntax style.  And then just set the syntax highlighting mode like you currently would:

      textArea.setSyntaxEditingStyle(ejbqlStyle);

      Would this provide the functionality you need?  This is probably the simplest way to be able to add functionality to RSyntaxTextArea like this.  Let me know what you think about this; comments and feedback are welcome!

       
      • I think this is exactly what I need. Simple and useful.
        I will post another message here when the project get approved at java.net

        Now, just for fun, RText application at start-up could scan some directory searching and loading syntax class files (acting like a plugin loader). Then you could create a web page to let users download custom syntax styles class files :P