在PlainNotes包中为Sublime Text添加其他注释语法

时间:2019-07-16 11:48:03

标签: sublimetext3

我使用的是PlainNotes软件包及其语法,而不是纯文本。我想为注释添加一些其他语法,例如JS注释(由//触发)。我正在尝试使用演示中的建议代码(工具>开发人员>新语法)来编辑this file

...
contexts:
  main:
    ......
    # Comments begin with a '//' and finish at the end of the line
    - match: '//'
      scope: punctuation.definition.comment.example-c
      push: line_comment

  line_comment:
    - meta_scope: comment.line.example-c
    - match: $
      pop: true

可能的问题之一是我不知道如何设置范围。选择HTML注释时,我尝试使用Ctrl + Alt + Shift + P快捷键中的作用域,并且我也查看了tmLanguage文件,但仍然遇到问题

1 个答案:

答案 0 :(得分:1)

出于此答案的目的,我们将假定要应用于语法的匹配规则为以下规则:

- match: '//'
  scope: punctuation.definition.comment.begin.html
  push:
    - meta_scope: comment.line.double-slash.html
    - match: $\n?
      pop: true

这是来自示例语法模板的版本的更紧凑的版本,因为它使用anonymous context而不是context的命名push。范围已作了微调(请参阅standard scope names用于类似操作),并且我们还可以选择在注释行的末尾匹配换行符,以确保当光标位于注释中时也不会发生这种情况光标在注释行的末尾不会发生这种情况。

我们还将假定要测试的示例note文件包含以下文本:

This is a single line

This is a paragraph of
text that is spread over
several lines.

顺便说一句,您可能会遇到一些潜在的陷阱;其中一些通常是语法通用的,其中一些特定于PlainNotes软件包:

陷阱1:匹配规则的位置很重要

matchcontext语句的顺序指定了语法匹配的优先级。一般来说,context中与文本匹配的第一个匹配项是选定的匹配项。

如果您将match规则作为main上下文中的最后一条规则插入,则无论您尝试注释什么,都不会发生任何事情。相反,所有文本行的范围将保留为text.html.markdown.note meta.paragraph.markdown

这是因为检测文本段落的语法规则比注释main更靠近match上下文的顶部,因此在注释规则可以匹配之前,段落规则已经匹配并消耗了该文本。

match规则作为main中的第一项显示相反的问题。如果这样做,您将看到,如果您尝试注释掉单行,则范围将更改为在该行中有注释(尽管在视觉上您无法分辨;下面更多内容)。同样,如果您尝试注释掉该段的第一行,其范围也会改变。

但是,尝试注释掉该段的第二行或第三行无效;范围保持不变。原因直接进入陷阱2。

陷阱2:语法上下文不同

在语法中,存在一个或多个contexts语法规则。始终存在一个名为main的上下文,在该上下文中语法“开始”其匹配。对于我们的注释规则,还有另一个anonymous上下文,其中包含一个匹配规则,该规则表示注释结束。

每个上下文都是不同的;它们具有匹配的规则,但是仅考虑活动上下文中的规则,而忽略所有其他规则;上下文是distinct

我们的问题是main上下文中的最后一条规则检测到它认为是段落的开头,并且当发生这种情况时,它会像匿名上下文一样push进入匿名上下文我们的评论规则确实如此。

一旦发生这种情况,语法就会认为它位于文本的一段之内,并且会应用其他全部规则,其中之一不是与注释匹配的规则。这使我们可以注释第一行,因为它还不是一个段落,但是在该段落开始时,只有在该段落退出后才能进行注释。

要解决此问题,您还需要在段落规则中包括注释规则,以便它也可以在其中应用。

为此,我们可以定义一个自己的上下文,该上下文仅包含匹配注释的规则:

  comments:
    - match: '//'
      scope: punctuation.definition.comment.begin.html
      push:
        - meta_scope: comment.line.double-slash.html
        - match: $\n?
          pop: true

现在,作为main中的第一个匹配项,我们可以包含来自comments上下文的规则,以便将其应用于此处:

  main:
    - include: comments
    ...

然后,我们还搜索语法以找到应用meta.paragraph.markdown范围的位置,以找到匹配段落的位置,并在其中进行include,以便在此处插入我们的注释规则好。牢记第一个陷阱,我们将其作为匿名context中的第一条规则,以便它可以在其他任何内容之前使用注释:

    - match: '^(?=\S|[ ]{1,3})(?![=-]{3,}(?=$))'
      push:
        - meta_scope: meta.paragraph.markdown
        - include: comments
        ...

现在,我们可以对段落的行进行注释,并且范围将表明它是我们想要的注释。

但是,我们仍然看不到有任何注释的视觉指示,这使我们进入了第三个陷阱。

陷阱3:语法和配色方案协同工作

使用中的语法和使用中的配色方案需要一起工作,以便提供我们期望看到的语法突出显示。该语法将范围应用于文本,并且配色方案具有将颜色应用于范围的规则。

如果语法没有用配色方案匹配的规则来限制某些内容,则不能应用任何样式;这就是这里发生的事情。

从技术上讲,按照上述链接,我们的规则适用的范围是正确和标准的。在这种特殊情况下,当前的问题是PlainNotes软件包不仅包含其自身的语法,还包含其自身的配色方案。

它所应用的配色方案在我们使用的标准范围上不匹配,因为根据包作者的定义,语法不会生成该范围。

PlainNotes提供的配色方案具有注释规则,但仅适用于块注释而不适用于此处使用的行注释。您可以通过在注释文件中使用HTML注释并在视觉上看到它的变化来看到它。

最方便的修复方法是修改注释规则所应用的范围,以便它们应用PlainNotes期望的范围:

  comments:
    - match: '//'
      scope: punctuation.definition.comment.begin.html
      push:
        - meta_scope: comment.block.html
        - match: $\n?
          pop: true

有了这些,我们可以注释段落中的单行或内行,并获得我们期望的语法突出显示:

Sample comments

根据您的用例,这可能不足以允许在您想要的所有位置发表评论。

例如,标题中没有注释,因为存在match规则将标题作为完整行进行匹配,该规则会在任何注释匹配之前消耗注释令牌。

修复该问题可能需要修改标题的匹配规则,以使其类似于注释(例如,推送context,以便您可以include注释),这可能不值得。