3

我终于回到充实我想添加到 YI 的 GitCommit 消息模式,但我似乎缺少一些基本的东西。我似乎无法匹配语法中的单个字符,我的所有规则只有在它们匹配整行时才有效。我知道这必须是可能的,因为 YI 中的其他语法显然会这样做,但做同样的事情似乎不起作用。

我想要一种最终看起来与 vim 中的非常相似的提交模式。在 vim 模式下有用的一件事是在注释中突出显示关键字。Git 在它所做的大多数事情(提交、变基等)中都将大量信息放在注释中,所以这很有用。我的想法是匹配 git 注释中的起始 '#' 字符并切换到将匹配关键字的不同上下文。但是,我似乎无法制定仅匹配“#”的规则,该规则在包含“#”的行上切换为注释样式,但在包含“#”之后的任何内容的行上,它不会切换样式。

我现在拥有的是:

<0> {
\#                             { m (const $ LineComment) Style.commentStyle }
$commitChars*$                 { c Style.defaultStyle }
}

<lineComment> {                                                                                                    
$nl                            { m (const Digest) Style.defaultStyle }                                               
·                              { c Style.regexStyle }                                                                
}      

细节明显省略。我们的想法是当我们看到“#”时切换到“lineComment”模式,并以不同的方式设置样式,直到我们看到行尾。根据文档和示例,应该有一种方法可以做我想做的事。我已经尝试了几乎所有我能想到的“#”模式的排列,但没有任何改变我所看到的行为。
我错过了什么明显的东西?

编辑:上面的代码来自我的 YI 分支中的实现。我有一个独立的解析器,在这里表现出同样的问题。如果您运行alex GitCommit.x && ghc --make GitCommit.hs && ./GitCommit < shortmsg,您将看到内容被解析为的MessageLine注释行和正确标记的空注释行CommentStart

4

1 回答 1

1

好吧,我终于想通了。看起来亚历克斯总是需要最长的匹配,而不是第一场匹配。匹配提交行的规则总是会更长,因为它匹配整行。这导致 Alex 总是选择该分支而不是评论分支。引用 Alex 文档

When the input stream matches more than one rule, the rule which matches the longest prefix of the input stream wins. If there are still several rules which match an equal number of characters, then the rule which appears earliest in the file wins.

我想我应该不止一次地阅读这些文档。解决方案是从$commitChars字符集中删除“#”。

于 2011-07-07T12:14:31.317 回答