VS Code for Raku 中的多行注释

Multiline comments in VS Code for Raku

我使用 VS Code 编写 Raku 代码。

它正确显示单行注释。

# this is single-line comment!

但是,嵌入评论、多行评论和pod评论就不一样了。请参阅以下片段:

Raku,

嵌入的评论是

if #`( This is an inline comment here? ) True {
    say "Raku is awesome";
}

多行注释为

#`[
And this is how a multiline comment would work.
That says why we do what we do below.
]
say "Raku is awesome";

播客评论是

=begin comment
 
Here are several
lines
of comment
 
=end comment

say "Hello";

问题是一旦 VS 代码看到 #,它就会注释掉整行,这在嵌入式注释中不应该是这种情况。 更多详情 here.

为了理解,我看到了 Raku https://github.com/microsoft/vscode/blob/main/extensions/perl/perl6.language-configuration.json 的源配置文件(~2 年未更新!)。尝试了一些修改

"comments": {
        // symbol used for single line comment. Remove this entry if your language does not support line comments
        "lineComment": "#",
        // symbols used for start and end a block comment. Remove this entry if your language does not support block comments
        "blockComment": [
           [ "/*", "*/" ],
           ["#`(", ")"],
           ["#`[", "]"],
           ["#`{", "}"],
           ["#`<", ">"],
           ["=begin", "=end"]
        ]

但似乎不起作用。

如何让它以正确的方式工作?

TL;DR 如果我们真的很幸运,我已经解决了您的问题。更有可能我只是提供了思考的食物。

我最擅长解决问题中的问题

首先,让我尝试tackle/discuss您所写的具体两个问题。

        // symbol used for single line comment.
        "lineComment": "#",

浏览了 VS Code 文档后,我初步猜测字符串 "#" 是 VS Code 文档中提到的 Textmate grammars 支持的方言中的正则表达式。这表明,如果使用 PCRE 正则表达式方言:

        // symbol used for single line comment.
        "lineComment": "#(?!`[(\[{<])"

这里的重点是确保“符号”正则表达式(假设它是正则表达式)匹配以#`(或您允许的其他变体开头的代码for 在您的块评论配置中。

继续:

        // symbols used for start and end a block comment.
       "blockComment": [
           [ "/*", "*/" ],
           ["#`(", ")"],
           ["#`[", "]"],
           ["#`{", "}"],
           ["#`<", ">"],
           ["=begin", "=end"]
        ]

首先,我认为应该删除 [ "/*", "*/" ], 行。 Raku 不支持这种块评论形式。

接下来,浏览了上面链接的 Textmate 页面后,这似乎可以用于最后一点 =begin foo:

           ["^=begin\s+(\w+)", "\n=end\s+"]

这里的重点是:

  1. 捕获评论标识符之后=begin。 (我使用语法 (...) 因为这是正则表达式方言中最常见的捕获语法,就像它在 Raku 正则表达式中一样。)我写的模式只是 \w+ ,它只会匹配简单的标识符,但这是一个开始,假设,如前所述,这些 VS 代码“符号”字符串确实是正则表达式。

  2. =end 之后插入捕获的内容 。 (</code> 是最常见的语法,在正则表达式方言中,用于插入第一个编号的捕获。这对应于将在 Raku 正则表达式中使用的语法 <code>[=23=]。)

我还添加了:

  • =begin 之前的 ^ 将匹配限制在行的开头。但也许应该删除此正则表达式才能与 VS Code 一起使用。

  • 一个\n=end之前也是一样的道理。 (但我的猜测是 ^ 适合 =begin\n 适合 =end。)

下一个最佳镜头

如果这些更改 起作用,即使它们起作用,那么也可以尝试摆弄它们,and/or 尝试使用正则表达式测试工具(例如 regex101.com), and/or 阅读 Textmate 技术支持的正则表达式方言(VS Code 文档中有链接;我在准备上述建议时阅读了一些 Language Grammars)。

我必须说我很难理解 Textmate 文档(轻描淡写!)。因此,如果以上方法不起作用,并且您也无法弄清楚,那么也许我们应该在您的 Q 中添加一个 [textmate] 标签,以引起了解这种正则表达式方言/方面的 SO 人的注意VS 代码。


即使你解决了这两个问题,至少对于简单的情况,还会有很多其他问题。 Raku 的语法很复杂!

这个答案的其余部分涵盖了更大的图景,不是专门针对使用语法高亮器解决这些特定问题,而是使工具正确、高效和可维护地高亮显示 Raku 代码的整体问题。

大局

How do I make it work the right way?

如果是我,我会看看其他工具在语法高亮方面取得的成就。其中任何一个都可以正确突出你的例子吗?如果是这样,他们是如何管理的?他们使用哪些正则表达式方言以及哪些正则表达式模式?

具体来说:

  • 逗号IDE 是否处理您的示例?如果是这样,那么无论它是使用方法 1 还是方法 2,如果可以的话,对 VS Code 使用相同的方法或类似的方法可能是有意义的。

  • emacs 或 vi 呢?如果其中任何一个有效,它们使用什么正则表达式 dialects/engines,您可以在 VS Code 中使用相同的正则表达式吗?

两种方法

无论编辑器/IDE 被定制的是 VS 代码还是其他任何东西,都需要弄清楚以下两种不同的方法来做这种事情:

  1. 创建 Raku 语法和动作 class,并将 Rakudo 和此语法插入工具。

  2. 在某些正则表达式引擎中创建(非 Raku)正则表达式并将其插入到工具中。

根据使用这些方法中的哪一种,存在不同的挑战:

  1. Raku 的语法具有挑战性

    我们知道可以编写一个 Raku 语法,它将以 完美 保真度解析它——因为这正是 Rakudo 解析 Raku 代码的方式。如果一个工具允许将该语法和 Rakudo 插入该工具,那么这将是“最简单”的解决方案——除非它只有在克服下一个挑战的情况下才是解决方案,即即使一个工具 是否支持插入Rakudo -- 最合适的标准方法是LSP[1] -- 你会遇到性能问题:

    1.1 Rakudo 总体来说很慢尤其是它的语法引擎

    1.2 需要(至少在原则上)语法高亮等功能,以便在每次插入或删除字符时重新处理所有正在编辑的代码,以便知道如何解析它。

    许多 PL grammars/compilers 是这样的,这很容易处理,性能可以接受。一些现代解析技术 and/or 编译器特别专注于 增量 解析,它从根本上加快了重新处理代码的速度,并且在解析之间对代码进行了微小的更改。

    就目前的 Raku(do) 而言(至少在这十年的剩余时间里,这很有可能)这是一个大问题。事情 可能 显着改变 if/when 语法引擎被重写,我认为 可能 发生在 2023-2025 时间范围内,但在同时,Rakudo 的解析速度不够快,无法成为使用 LSP 或类似工具的语法高亮解决方案,这在某种程度上是合理的。

    (这就是为什么 CommaIDE 而不是 使用 Rakudo 进行语法高亮,而是使用一个单独的解析器更快/更多增量。)

这导致第二种方法,即您当前尝试使用的方法:

  1. 在工具中用于语法高亮代码的主要其他方法是用给定编辑器或其他编辑器支持的某些非 Raku 正则表达式方言编写正则表达式为此目的的工具。 这种方法引入了它自己的一系列挑战:

    2.1 该工具与正则表达式的交互方式是否使它们有匹配 元素的机会要突出显示?

    2.2 如果这个机会存在,工具支持的给定正则表达式方言是否有足够的能力来正确匹配?

    2.3 如果一种方言具有足够的力量,那么这种力量是否可以由具有足够技能和决心的人使用,并且高亮足够完整和快速?写一个通常明显减慢打字速度的荧光笔是没有意义的。

    2.4 如果 VS Code 提供了足够的机会来挂钩正则表达式,并且正则表达式方言具有足够的力量,并且应用了足够的技巧和决心,然后维护,那么就可以了是个好消息。

VS Code 中的两种方法

在我的评论中穿插来自 the Syntax Highlight Guide 的引述:

VS Code's tokenization engine is powered by TextMate grammars. TextMate grammars are a structured collection of regular expressions...

所以这是上面列表中的解决方案 2——“用一些非 Raku 正则表达式方言编写正则表达式”。这导致了我列出的子问题。

VS Code also allows extensions to provide tokenization through a Semantic Token Provider.

听起来很像可能是第一种方法,在 Raku 特定语言服务器中使用 Rakudo。我认为至少在短期内,基本语法高亮的速度几乎不可能快到这一点,但也许我错了。

Semantic providers are typically implemented by language servers that have a deeper understanding of the source file ... Semantic highlighting goes on top of the syntax highlighting. And as language servers can take a while to load and analyze a project, semantic token highlighting may appear after a short delay.

两期注意事项:

  • 他们说他们的设计是这样的,这种方法“在之上”方法2,有延迟。所以,再一次,即使 Rakudo 快,这种方法似乎 而不是 用于大多数 PL 的基本突出显示。

  • 他们将延迟描述为“短”。这显然有点含糊——允许带有 fast/incremental 解析器的 PL,但也允许没有它们的 PL——但我怀疑他们没有考虑 Raku(do) 解析有多慢,尤其是乐码!

脚注

[1] LSP = Language Server Protocol.