Vimscript编程指南

高级语法高亮

到现在为止,我们已经给Potion文件定义了keyword和function这两个简单的语法高亮。

如果你没有做上一章的练习的话,你需要回到上一章去完成它们,因为这一节里我会假设你已经完成了上一节的练习。

事实上,你需要会过头把你所跳过的所有练习都补上。即使你认为它们是没有用的,但是为了高效地学习本书你需要完成他们。这个问题上请相信我。

高亮注释

一个很明显需要高亮的部分就是注释了。但是问题在于Potion的注视是以#开始的,而#绝大大多数情况下并不是在iskeyword里。

如果你不知道iskeyword代表什么的话,说明你没有听我的话。会过头去把那该死的练习给做了。我给每章加上练习并不是为了给你添加没用的外加作业,你确实需要完成它们来理解这本书的内容。

因为“#”不是一个关键词,所以我们需要用正则表达式来匹配它以及注释的内容。我们用syntax match代替syntax keyword来完成这个工作。把下面的内容加入到你的语法文件里:


     syntax match potionComment "\v#.*$"
     highlight link potionComment Comment

我不会再告诉你这些代码该放到哪个位置了,你是个程序员,你自己可以判断。

关闭再打开factorial.pn。在文件里随便哪个位置添加一些注释,你会发现它会被高亮显示。

第二行命令比较简单:它告诉Vim把potionComment这个语法组里的内容作为Comment来高亮。

第一行里有些新的内容。我们用syntax match来告诉vim去匹配正则表达式,而非原始的字符串。

注意我们的正则表达式是以\v开始的,这个是在告诉vim用“very magic”模式。如果你不是很确定它的作用的话,你可以重新阅读基本正则表达式那一章节。

在这个特别的列子里,“very magic”模式并不是必须的。但是在后面我们可能会改变这个正则表达式,然后会奇怪这个正则表达式为什么不正常工作了,所以我们推荐为了保持一致,使用“very magic”模式。

对于正则本身,它表示的意义比较简单:注释是由#开始的,包含所有的字符一直到当前行的结尾。

如果你需要一个完整的正则表达式的教程的话,你可以参考Zed Shaw的Learn Regex the Heard Way。

高亮操作符

Potion需要高亮的另外一部分是操作符。把下面的内容添加到你的语法文件里:


     syntax match potionOperator "\v\*\="     
     syntax match potionOperator "\v/\="
     syntax match potionOperator "\v\+\="
     syntax match potionOperator "\v-\="
     syntax match potionOperator "\v\*"
     syntax match potionOperator "\v/"
     syntax match potionOperator "\v\+"
     syntax match potionOperator "\v-"
     syntax match potionOperator "\v?"

关闭再打开factorial.pn文件。你会发现factorial函数中间的*=操作符现在被高亮显示了。

你发现的第一个现象应该是我把每个正则表达式作为单独的一行来显示,而不是像关键词一样进行分组。这是因为syntax match不支持在同一行包含多组的方式。

你应该也发现了,我在每个正则表达式的前面都加上了\v,即使它并不是必要的。这是因为我在写Vimscript的时候为了保持我的正则表达式的语法的一致性,即使这样会让我多输入几个字符。

你也许会奇怪我为什么不用“\v-\=?”这样一个正则表达式来匹配-和=。显然你可以那样做,它也会正常工作的。我只是把-和-=当作两个不同的操作符来使用,所以我把它们放在不同的行里定义。

把这些操作符分开来定义,可以简化正则表达式,但是会使得代码变得比较冗长。不过我喜欢这样,如果你有其他的想法的话,你自己可以决定该怎么去做。

并且我还没有把=定义成一个操作符。我们会在后面来完成它,因为我想把它留到后面的内容里。

因为我分别对-和-=用了不同的正则表达式,所以我必须要在-后面定义-=!

如果我使用了相反的顺序的话,并且在Potion文件里使用了-=,那么Vim就会匹配到-,并且高亮它,然后就会留下=没有被匹配了。这个说明了当你用syntax来组建语法组的话,每个分组只会处理文件里还没有被匹配的内容。

这个有点过度简化了,但是我现在还不想过多的陷入到细节里面。现在你只需要记住这一的一条经验规则就可以了:首先匹配大的语法块,再匹配小的。

现在我们已经学到这个内容了,那么就把=加入到操作符里:


     syntax match potionOperator "\v\="

花点时间考虑一下你该在哪个位置放这些语法文件。如果你需要提示的话,重新阅读一下前面的章节。

练习

  • 阅读:help syn-match
  • 在我们的例子里,没有把:当作一个操作符。阅读Potion的文档,考虑一下什么时候需要把:当作一个操作符。如果你要把它当作操作符的话,那就加在语法文件里。
  • 对于.和/做同样的工作。
  • 添加一个Potion语法块来高亮数字,并且把它和Number高亮连接起来。注意Potion支持的数字有2,0xffaf,123.23,1e-2和1.9956e+2。记住平衡你处理边界情况的时间和边界情况被用到的次数。