我正在尝试修改 CSharp 语言的语法突出显示,因此我将在 C# 字符串中获得 SQL 的语法突出显示。TextMate 支持嵌入式语言,所以这似乎是可能的。
我建立在csharp.tmLanguage.json 之上,我希望能够在字符串之前启用带有特殊注释的嵌入式 SQL
string query = /*SQL*/ $@"SELECT something FROM ..."
感谢 TextMate 的Language Grammars and Introduction to scopes我想出了这个 JSON 规则
"repository": {
"embeded-sql": {
"contentName": "source.sql",
"begin": "/\\*\\s*SQL\\s*\\*/\\s*\\$?@?\"",
"end": "\";",
"patterns": [
{
"include": "source.sql"
}
]
},
...
}
并且感谢 VSCode 的主题、片段和着色器以及运行和调试您的扩展,我能够测试,这个规则有效。
但是我有一个问题,我无法解决。
我的语法规则仅在 csharp 规则的重要部分被禁用时才有效,如果我禁用所有#declarations
and #script-top-level
,则嵌入的 SQL 有效:
否则,我的规则会被 csharp 规则覆盖,例如
- 标点符号.definition.comment.cs
- string.quoted.double.cs
- 评论块
- 等等
问题是,我的规则适用于几种语言元素,而 csharp 定义在针对这些元素时获胜。
在什么基础上标记元素?如何编写我的规则,以便在其他语言规则之前胜出并标记该语法?有没有计算规则权重的算法?
解决方案
如果您无法在 csharp 中劫持注释语法,让我们在 SQL 中使用注释。我制定了一条通过-- SQL
评论启用的规则,并将其应用于逐字字符串。现在它可以工作了,但样式有时会与字符串混合。需要一些额外的改进,但看起来很有希望。
证明有效的规则是这样的
"embeded-sql": {
"contentName": "source.sql",
"begin": "--\\s*SQL",
"end": "(?:\\b|^)(?=\"\\s*;)",
"patterns": [
{
"include": "source.sql"
}
]
},