[TxMt] Grammar injection. Main grammar taking priority?

Daniel Rodríguez Troitiño notzcoolx at yahoo.es
Mon May 16 15:29:23 UTC 2016


Hi,

I was trying to create a composed grammar for Gyb (https://github.com/apple/swift/blob/master/utils/gyb.py). Gyb is mostly Swift code, with some snippets of Python embedded. For embedding the Python code you surround the code with `%{ }%` or start the lines with `%`.

For parsing Swift or Python code I’m using the official bundles (https://github.com/textmate/swift.tmbundle and https://github.com/textmate/python.tmbundle). For the injection I based my grammar on HTML (Rails) (https://github.com/textmate/ruby-on-rails-tmbundle/blob/master/Syntaxes/HTML%20(Rails).plist) which is mostly the same idea.

The grammar almost works. The embedded blocks are marked and the syntax highlight works, but I need to include a space before the percent signs for it to work, which is not ideal. It looks like the percent sign are interpreted as keyword.operator.remainder.swift (https://github.com/textmate/swift.tmbundle/blob/master/Syntaxes/Swift.tmLanguage#L1282-L1287) before being able to be part of the injected grammar.

I found some references that “left scope match” (L:) might be able to help, but I cannot find a way to get it working.

A simple version of my grammar looks like this:

```
{ injections = {
'source.swift.gyb - (meta.embedded.block.gyb)' = {
patterns = (
{ begin = '(^|\s*)(?=%\{(?![^\}]*\}%))';
end = '(?!\G)(\s*$\n)?';
beginCaptures = { 0 = { name = 'punctuation.whitespace.embedded.leading.gyb'; }; };
endCaptures = { 0 = { name = 'punctuation.whitespace.embedded.trailing.gyb'; }; };
patterns = ( { include = '#tags'; } );
},
{ include = '#tags'; },
);
};
};
patterns = ( { include = 'source.swift'; } );
repository = {
tags = {
patterns = (
{ name = 'meta.embedded.block.gyb';
begin = '%\{';
end = '(\})%';
beginCaptures = { 0 = { name = 'punctuation.section.embedded.begin.gyb'; }; };
endCaptures = {
0 = { name = 'punctuation.section.embedded.end.gyb'; };
1 = { name = 'source.python'; };
};
contentName = 'source.python';
patterns = ( { include = 'source.python'; } );
},
},
},
}
```

A text like this will work:

```
class MyClass {
 %{
a = 1
}%
}
```

If I remove the space before the first percent sign, the grammar will not create the embedded block at all.

I tried using several scope selectors with `L:` to see if they work:
- `L:(source.swift.gyb - (meta.embedded.block.gyb))`
- `source.swift.gyb - (meta.embedded.block.gyb), L:source.swift.gyb`
- `source.swift.gyb - (meta.embedded.block.gyb), L:source.swift`
- `source.swift.gyb - (meta.embedded.block.gyb), L:source.swift keyword.operator.remainder.swift`
- `source.swift.gyb - (meta.embedded.block.gyb), L:keyword.operator.remainder.swift`

None of them seem to work.

Does someone has any tips about what should I try next?

Thanks!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macromates.com/textmate/attachments/20160516/981c6767/attachment.html>


More information about the textmate mailing list