Sunday August 26, 2007
How to Write a Groovy Editor (Part 3)
First, a thousand words:
So, here, apart from some obvious syntax coloring, there are two other interesting things going on. First, there's a code fold for classes:
And also for the body of classes:
I found that it is easier to create code folds before creating syntax colors. Syntax coloring can be extremely tricky, because the order in which you define TOKEN declarations is important. When the IDE parses the NBS file, it reads from top to bottom and so if the text in the editor applies to more than one TOKEN declaration, one TOKEN declaration's color may end up overwriting another TOKEN declaration's color. So, to take that factor out of the equation, it makes sense to first make sure that the grammar rules make sense. If you have a grammar rule for a class definition, there's no better way of assessing whether it is defined correctly than to assign a code fold to it, as below:
FOLD:ClassDeclaration: {
expand_type_action_name:"LBL_ExpandComments";
collapse_type_action_name:"LBL_CollapseComments";
fold_display_name:"Groovy class";
}
(Note that the 'expand_type_action_name' and the 'collapse_type_action_name' resolve to labels that appear on two menu items that magically appear in the editor's popup menu, for expanding and collapsing the editor's code folds.)
Another issue that's problematic is coming to a stable set of grammar rules in the first place. The "hit and miss" approach I used in the first part of this series cannot be the ultimate solution. Better to have the GroovyRecognizer.html and GroovyLexer.html close by. The absolute purist approach, which would be to stick religiously to these two HTML documents, is not likely to work either. For one thing, it's hard to figure out exactly how to translate these definitions to Schliemann. I had a very good start, thanks to some work that Jim Clarke did some months ago, but even that (i.e., generated draft NBS from the above HTML documents) isn't the final answer. Some common sense, I guess, is the bridge between the "hit and miss" (i.e., starting with another NBS and tuning it to your own needs) and the purist (i.e., be religious and do not deviate from the official ANTLR definition) approach.
Also note that I have the Navigator working, for the first time for Groovy. Not perfect yet, but a clear start. As an example, this is how the class ends up in the Navigator:
NAVIGATOR:ClassDeclaration: {
display_name: org.netbeans.modules.mygroovyeditor.Groovy.className;
icon: "/org/netbeans/modules/languages/resources/class.gif";
isLeaf: "false";
}
The above should be put in the Groovy.nbs file. (By the way, the 'isLeaf' key doesn't seem to make a difference, currently, whether you put true or false, but I think it does need to be there anyway.) And then here, in my Grovvy.java class, I have the className method:
public static String className(SyntaxContext context) {
ASTPath path = context.getASTPath();
ASTItem functionClause = (ASTNode) path.getLeaf();
ASTItem name = null;
for (ASTItem item : functionClause.getChildren()) {
name = item;
}
if (name != null) {
String nameStr = ((ASTNode) name).getAsText();
return "Class: " + nameStr.substring(0, nameStr.indexOf("{"));
}
return "?";
}
The string manipulation is a bit messy, I'm pretty sure it should be a cleaner solution than that, but it gets the job done.
But the coloring is a long way from done. I'm only just beginning to understand how the grammar rules work. In between, I'm working on the hyperlinks in the Output window, which appear there when Groovy returns error messages when a script is run. Some of the error messages are convenient in that they include the line number where the error occurred. It is then very easy to create the hyperlink such that the user can click it to jump to the erroneous line. Other errors, especially those coming from javax.script.ScriptException, give no indication of where the error took place. This is a pretty big problem, one that may not be possible to solve. Adding annotations to the other error lines, i.e., those that can be identified, will be easy. Just the same old annotation approach as done for all editors, just attach the annotation to the line and you're done, like so:
It's pretty cool that Schliemann gives lots of room for incorporating the standard NetBeans API classes. (By the way, the 'Groovy error' message in the screenshot above, which pops up when the mouse hovers over the red error mark, is a bit truncated, that's not how it is in real life, just how my screenshot ended up.)
Well, that's where things are right now. Way too soon to release all this in any form, but if things continue in this way, maybe by the end of the week. The grammar rules are going to continue being a problem, though. To get an absolutely reliable editor may take quite some time in tweaking and so on. And then there's also code completion to look at, of course...
A final happy picture, of some SwingBuilder code:

Aug 26 2007, 08:26:51 AM PDT Permalink


