Reputation: 4825
I'm trying modify syntax highlighting for CSharp language, so I will get syntax highlighting for SQL in C# string. TextMate has support for embeded languages, so this seems possible.
I build on csharp.tmLanguage.json and I would like to be able to enable embeded SQL with special comment before string like
string query = /*SQL*/ $@"SELECT something FROM ..."
Thanks to TextMate's Language Grammars and Introduction to scopes I came up with this JSON rule
"repository": {
"embeded-sql": {
"contentName": "source.sql",
"begin": "/\\*\\s*SQL\\s*\\*/\\s*\\$?@?\"",
"end": "\";",
"patterns": [
{
"include": "source.sql"
}
]
},
...
}
And thanks to VSCode's Themes, Snippets and Colorizers and Running and Debugging Your Extension I was able to test, that this rule works.
But I have one problem, which I'm unable to solve.
My grammar rule works only if signifficant portion of csharp rules are disabled, If I disable all #declarations
and #script-top-level
, embeded SQL works:
Otherwise, my rule is overridden by csharp rules like
The problem is, that my rule works on several language elements and the csharp definition wins on targeting these elements.
On which basis are the elements tagged? How to write my rule, so it will win and tag that syntax before other language rules? Is there any algorithm for calculating weight of rules?
If you cannot hijack comment syntax in csharp, lets us work with comment in SQL. I made a rule enabled by -- SQL
comment and I applied this to verbatim string. Now it works but the styles are sometimes mixed with string. Needs some additional improvements, but looks promising.
The rule that proves to work goes like this
"embeded-sql": {
"contentName": "source.sql",
"begin": "--\\s*SQL",
"end": "(?:\\b|^)(?=\"\\s*;)",
"patterns": [
{
"include": "source.sql"
}
]
},
Now I would like to enable Intellisense and error checking in such embedded language.
Upvotes: 4
Views: 4415
Reputation: 21727
The rules in the patterns list are matched in order.
Your rule appears like a specialisation of comment, so you can put it just before the comment.block.cs
"comment": {
"patterns": [
{
"contentName": "source.sql",
"begin": "(/\\*\\s*SQL\\s*\\*/)\\s*\\$?@?\"",
"beginCaptures": {
"1": {
"patterns": [
{
"include": "#comment"
}
]
}
},
"end": "\";",
"patterns": [
{
"include": "source.sql"
}
]
},
{
"name": "comment.block.cs",
"begin": "/\\*",
"beginCaptures": {
"0": {
"name": "punctuation.definition.comment.cs"
}
},
"end": "\\*/",
"endCaptures": {
"0": {
"name": "punctuation.definition.comment.cs"
}
}
},
...
The snapshot is done on a language my
which is just a copy of c#
json plus your sql
embedding.
Upvotes: 3