I'm trying to match the following code in the D language grammar:
static if (true) {}
void foo () { static if (true) {} }
The first static-if is correctly recognized as "keyword.control.conditional.d". But the static-if inside "foo" is recognized as a method "meta.definition.method.d". I managed to get the top level static-if correctly recognized by moving the pattern for the static-if before the pattern for a method. But I don't understand why that doesn't work inside "foo".
The full scope of the static-if inside "foo" is:
source.d meta.block.d meta.definition.method.d entity.name.function.d
The language grammar is available here [1]. Are the patterns evaluated in the wrong order or something like that?
Another thing I noticed is the "static if" on the top level seems to be recognized as a single word. When I use the hot keys for moving the cursor a word it jumps from the start of "static" to the end of "if", instead of to the end of "static".
[1] https://github.com/jacob-carlborg/d.tmbundle/blob/d2/Syntaxes/D.tmLanguage#L...
On 25 Mar 2015, at 22:12, Jacob Carlborg wrote:
I'm trying to match the following code in the D language grammar:
static if (true) {}
void foo () { static if (true) {} }
The first static-if is correctly recognized as "keyword.control.conditional.d". But the static-if inside "foo" is recognized as a method "meta.definition.method.d". I managed to get the top level static-if correctly recognized by moving the pattern for the static-if before the pattern for a method. But I don't understand why that doesn't work inside "foo".
This is because of the indent. The rule for ‘meta.definition.method.d’ will match from the start of the line (eating leading whitespace), so while the static keyword rule has precedence, this rule cannot match at the beginning of the line (where there is just whitespace), so TextMate will instead pick the rule that can match.
You could prefix the keyword.control.conditional.d pattern with (^\s+) so that this rule will also be a candidate when at the beginning of the line, though in general having rules match leading whitespace makes the grammar more difficult to work with (as you’ll get these unexpected issues).
Another thing I noticed is the "static if" on the top level seems to be recognized as a single word. When I use the hot keys for moving the cursor a word it jumps from the start of "static" to the end of "if", instead of to the end of "static".
This is because the whitespace between the two keywords are scoped as a keyword, so TextMate consider the entire thing a single unit for character movement (and word selection, etc.).
One way to fix this is by using captures for the non-whitespace and only assigning a scope name to the captures, e.g.:
{ match = '\b(?:(?<keyword>static)\s+)?(?<keyword>if|else|switch)\b'; captures = { keyword = { name = 'keyword.control.conditional.d'; }; }; },
For more info about character classes (which is used for word movement) see this blog post: http://blog.macromates.com/2012/clever-completion/
On 2015-04-28 17:30, Allan Odgaard wrote:
For more info about character classes (which is used for word movement) see this blog post: http://blog.macromates.com/2012/clever-completion/
Thanks, I already solved all these issues with help from Michael Sheets.