如何使用 ”!” 作为注释指示符,但也不是语言语法中的运算符突出显示?

NAX*_*NAX 2 regex visual-studio-code tmlanguage vscode-extensions

我正在使用 VScode 并创建我自己的语言扩展来突出显示语法,我需要使用正则表达式来查找注释。

基本规则是后面的所有内容!都是注释,但是有一个特殊情况。当!在内部eval()命令时,它意味着 NOT。

例如,我的一些代码如下所示:

if condition=(eval(!DB_EXIST)) ! this is a comment
(eval( !DB_UPDATED && !DB_EXIST)) !---"!" inside eval() means NOT
!this is another comment
<some commands> ! this is also a comment
Run Code Online (Sandbox Code Playgroud)

!DB_EXIST1 行和第 2 行不应该被解释为注释,并且!后面会跟一个非空格。

注释中的空格无关紧要。

"comments": {
    "patterns" [{
        "match":"regex1",
        "name":"comment"
    }]
},
"operator": {
    "patterns" [{
        "match":"regex2",
        "name":"keyword.operator.NOT"
    }]
},
Run Code Online (Sandbox Code Playgroud)

我应该使用什么样的正则表达式 1 和 2 来显示不同的评论颜色而不是?

我不擅长这个扩展写作,所以如果有更好的方法来完成这项工作,我将不胜感激。谢谢!

更新

@Gama11 帮助了我,但我没有完全涵盖我的代码示例中的所有情况。“!”之后的任何非空格 也应该是注释,只要“!” 不在 eval() 内。

Gam*_*a11 5

这是一种方法:

{
    "$schema": "https://raw.githubusercontent.com/Septh/tmlanguage/master/tmLanguage.schema.json",
    "scopeName": "source.abc",
    "patterns": [
        {
            "begin": "(eval)\\(",
            "end": "\\)",
            "captures": {
                "1": {
                    "name": "entity.name.function"
                }
            },
            "patterns": [
                {
                    "include": "#parens"
                },
                {
                    "match": "!",
                    "name": "keyword"
                }
            ]
        },
        {
            "match": "!.*?$",
            "name": "comment"
        }
    ],
    "repository": {
        "parens": {
            "begin": "\\(",
            "end": "\\)",
            "patterns": [
                {
                    "include": "#parens"
                }
            ]
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我们将无评论的模式!放在第一位,因为它更具体,应该优先于另一个。此外,我使用了"keyword"范围而不是更合适的范围,"keyword.operator.NOT"因此它实际上在屏幕截图中显示了不同的颜色。

第一个正则表达式是begin-end模式,它允许我们仅对这两个匹配项之间的文本应用模式(在这种情况下是在eval()calll 中)。当我们在做的时候,我们不妨高亮显示eval一个具有entity.name.function作用域的函数。

如果我们在 a 内eval(),我们允许两种模式:

  • 一个递归begin-end模式(包括它自己)来平衡括号(你可能有类似的东西eval(foo() + !bar()),并且)infoo()不应该结束 -eval模式)
  • !我们首先感兴趣的运营商

第二个正则表达式只匹配!,然后是任何 ( .*?) 直到行 ( $)的结尾。

一般来说,我强烈建议使用像regex101.com这样的工具来处理 TM Grammar 文件的正则表达式。比在 VSCode 本身中迭代要容易得多,因为您可以获得即时反馈。