TextMate Grammar ― precedence of rules

匿名 (未验证) 提交于 2019-12-03 01:05:01

问题:

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

  • punctuation.definition.comment.cs
  • string.quoted.double.cs
  • comment.block
  • etc.

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?


Solution

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.

回答1:

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.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!