在Vim中突出显示JavaScript的行内块注释

3

背景

我在很多Windows系统管理需求中使用JScript(微软的ECMAScript实现),这意味着我经常使用许多ActiveX(自动化COM)对象。这些对象的方法通常需要数字或布尔参数,例如:

var fso = new ActiveXObject("Scripting.FileSystemObject");
var a = fso.CreateTextFile("c:\\testfile.txt", true);
a.WriteLine("This is a test.");
a.Close();

(MSDN上的CreateTextFile方法)

在第二行中,您可以看到我所谈论的第二个参数。一个布尔值“true”并不能真正描述方法行为的变化。这对我来说不是问题,但我那些害怕自动化的同事们很容易被吓到。他们不知道一个参数的作用会让他们受到惊吓。不幸的是,长长的常量列表(当然,当前的JScript版本不支持真正的常量)也会让他们感到惊慌。因此,我开始使用内联块注释记录一些基本的函数调用。以上示例中的第二行将被写成:

var a = fso.CreateTextFile("c:\\testfile.txt", /*overwrite*/ true, /*unicode*/ false);

这给我带来了一个小的语法高亮的困境。我喜欢我的注释被鲜明地突出显示,包括块注释和行注释。然而,这些微小的内联块注释对我个人来说意义不大。我想以一种更柔和的方式突出显示这些特定的注释(例如白色的浅灰色)。这就带来了我的困境。

困境

当开始和结束标记在同一行时,我想覆盖块注释的默认语法高亮。理想情况下,这只需要在我的vimrc文件中完成,而不是在javascript.vim语法的个人副本中完成。我的初始尝试很糟糕:

hi inlineComment    guifg=#bbbbbb
match inlineComment "\/\*.*\*\/"

直接看到这个正则表达式模式的第一个问题就是它是一个贪婪搜索。它将匹配从行首的“/*”到行尾的最后一个“*/”,这意味着两个内联块注释之间的所有内容也将获得此突出显示样式。我可以解决这个问题,但我真的不知道如何处理我的第二个问题。
在ECMAScript中,无法在字符串文字中定义注释。因此,这种语法突出显示也会覆盖字符串突出显示。我在系统管理脚本中从未遇到过这个问题,但是当我检查为浏览器设计的许多JavaScript库(例如less.js)的源代码时,它经常会让我感到困扰。
令人惊叹的StackOverflow社区会推荐什么正则表达式模式、语法定义或其他解决方案来恢复我的vimrc zen呢?
2个回答

3

我不确定,但根据你的描述,似乎你不需要一个新的语法定义。Vim的语法文件通常允许您使用自己选择的高亮方式覆盖特定的语法项。在这种情况下,您想要的项目称为javaScriptComment,因此像这样的命令将设置其高亮:

hi javaScriptComment guifg=#bbbbbb

但是你需要在你的 .vimrc 文件中执行此操作(或者在那里引用),以便它在语法文件之前被评估。语法文件使用 highlight default 命令,所以语法文件的高亮选择仅影响没有设置高亮显示的语法项。有关更多详细信息,请参阅 :help :hi-default。顺便说一句,它仅适用于 Vim 5.8 及更高版本。
上述命令将更改所有内联的 /* */ 注释,并保留 // 行注释的默认设置,因为行注释是不同的语法项 (javaScriptLineComment)。您可以通过查看 javascript.vim 文件找到所有这些组的名称。 (最简单的方法是 :e $VIMRUNTIME/syntax/javascript.vim。)
如果你只想改变一些内联注释,那就有点复杂了,但仍然可以通过查看 javascript.vim 看出该如何操作。如果您这样做,您会发现块注释是这样定义的:-
syn region javaScriptComment start="/\*" end="\*/" contains=@Spell,javaScriptCommentTodo

注意,您可以使用不同的正则表达式来匹配起始和结束标记:您无需担心使用非贪婪量词或其他任何东西来匹配之间的内容。如果要创建类似但仅适用于单行的语法项,请尝试添加oneline选项(有关更多详细信息,请参见:h :syn-oneline):

syn region myOnelineComment start="/\*" end="\*/" oneline

我已经删除了两个contains组,因为(1)如果你只是用它来作为参数名称,你可能不想在这些注释中开启拼写检查,(2)包含的部分如果不是oneline将覆盖容器区域中的oneline,所以你仍然会匹配到这个区域中的所有TODO注释。

你可以在你的.vimrc文件中定义这种新的注释区域,并设置你喜欢的高亮方式:看起来你已经知道如何做了,所以我就不再详细介绍了。我还没有尝试过这个特定的例子,所以你可能需要一点调整才能使它正常工作。试试看,然后告诉我结果如何。


太令人兴奋了!我不知道有这个一行选项!这可能足以让我到达目的地。我应该很快能够报告我的结果。谢谢! - nullscape
1
这让我找到了我需要的!不幸的是,它在我的vimrc中没有起作用。然而,您提供的额外信息帮助我找到了这个答案,它引导我进入了vim的after目录。虽然所引用的内部帮助部分并没有很清楚地表明,但是一个相关的搜索结果确实很清楚地说明了一个个人javascript.vim文件可以放在哪里,该文件将在内置的javascript.vim之后被处理。 - nullscape
我最终成功地实现了所需的功能,方法是创建一个 $HOME/vimfiles/after/ftplugin/javascript.vim 文件,其中仅包含您组装的语法高亮规则。它完美地工作! - nullscape
啊,如果你没有特别提到你想要它在你的 .vimrc 中,我会告诉你把它放在那里。哦,好吧,又是一个学习经验,要检查一下提问者真正想要实现什么 :-) - Dan Hulme
我不怀疑。当我写道,“理想情况下,这应该仅在我的vimrc文件中完成,而不是在一个取代javascript.vim语法的个人副本中”,我认为我需要备份原始文件并在-/vimfiles/syntax/javascript.vim上创建自己的文件。由于运行时路径的无知以及对我设想的解决方案过于详细的描述使我概述了不必要的限制。对此我感到抱歉,并非常感谢您的帮助。 - nullscape

2
为什么不在调用上面添加一行注释?
我认为
// fso.CreateTextFile(filename:String, overwrite:Boolean, unicode:Boolean)
var a = fso.CreateTextFile("c:\\testfile.txt", true, false);

比起其他的,这篇文章更加易读且信息量更大。

var a = fso.CreateTextFile("c:\\testfile.txt", /*overwrite*/ true, /*unicode*/ false);

我确实看到了那个想法的价值。事实上,你提出的格式更加完整。 - nullscape

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接