你应该在很多源代码文件中看到过类似下图红框中这种注释信息,在源文件中的注释信息中设置跟 Vim 相关的选项,这是使用了 Vim 的模式行 (modeline) 特性。

vim-modeline

一、Vim 模式行介绍

Vim 模式行是指文件中一行以特定语言的注释符 (如 #///*) 开头,间隔一个空格,以 vi:vim:Vim: 等关键字触发的设置命令。该命令只对命令所在文件生效,且该行命令在文件中的位置有具体要求:需要放在文件的前 行或末尾最后 行之间。如果把 Vim 模式行命令置于超过文件首尾 行的范围,那么这条模式行设置是无效的!具体是 行,由 Vim 的 modelines 选项决定。

modelines 选项的默认值为 5,这说明默认情况下,有效的 Vim 模式行只能放置在一个文件的前面 5 行或最末尾 5 行的范围内。可以通过在Vim配置文件或命令行模式下设置 set modelines=10 来使得有效模式行的范围为文件开头10行和末尾10行内。

在命令行模式下输入命令 :help modelines,可以看到官方帮助文档对 modelines 选项的说明如下:如果 modeline 已启用并且 modelines 设置了行数,那么便在相应位置范围内查找 set 命令;如果 modeline 禁用或 modelines 设置的行数为 0 则不查找。

此外,为了使用正常使用 Vim 的模式行功能,必须开启 modeline 选项 (即设置 set modeline)。默认情况下,当 Vim 以非兼容模式运行时该特性都是启用的,除了在一些发行版中,出于安全考虑,Vim 的 ~/.vimrc 配置文件中显式禁用了该选项。

二、Vim 模式行格式

有两种模式形式:[text]{white}{vi:|vim:|ex:}[white]{options}[text]{white}{vi:|vim:|Vim:|ex:}[white]se[t] {options}:[text]

其中 [text] 表示任何文本,可以为空,一般是对应语言的注释符号;{white} 表示不少于一个的空白字符 (空格或Tab);{vi:|vim:|Vim:|ex:} 是 Vim 模式行的标识字符;[white] 表示可选的任意个空白字符;se[t] 表示字符串 setse (注意空格),使用 Vim: 时必须用 set{options} 表示选项设置的列表,用空格: 分隔,每个 : 之间的部分成为一个 :set 命令的参数 (可为空),:help options 可以查看所有有效选项的说明。

例如,本文提到的 noainoautoindent 选项的缩写,用于设置不自动缩进;tstabstop 选项的缩写,用于设置文件里的 Tab 键代表的空格数;swshiftwidth 选项的缩写,用于设置执行Vim缩进操作 ( <<>> )时缩进的列数,更多内容,推荐阅读Vim自动缩进

简单来说,Vim 在文件特定范围内检索模式行时,首先会判断该文件的类型(参考Vim文件类型检测原理及应用),再根据获取到的文件类型获取对应的注释符号,最后,在注释行中查找 vim:ex: 等关键词作为 Vim 的模式行。

Vim 的模式行格式有以下规则:

  • 注释符号 与模式行关键词 vim: 间必须包含空格

  • 如果用 set 来设置模式行的内容,Vim 会在找到第一个 : 时结束选项的设置,后面类似 */ 之类的为了闭合注释而出现的文本均不会被当做模式行选项

  • 如果不用 set 设置模式行,那么从 vim: 开头的该行以后的所有内容均被视作模式行选项

因此,对应 C++ 语言的源文件来说,/* vim: set noai ts=4 sw=4:expandtab */ 是一个有效的模式行设置,但 : 后面的 expandtab 选项不会生效,因为其位于 第一个 : 之后;

/* vim: noai:ts=4:sw=4 */ 是无效的,因为模式行中包含 */ 这部分非法的内容,需要修改为 // vim: noai:ts=4:sw=4 才是个有效的模式行设置,当然,也可以换成下面这种分成两行的形式,因为 Vim 检测模式行时只会处理到行尾。

1
2
/* vim: noai:ts=4:sw=4
*/

在 Vim 命令行模式下,输入 :verbose set modeline? modelines? 命令可以查看当前与模式行相关的设置及它们最新的设置。类似结果如下所示:

1
2
3
4
modeline
Last set from ~/.vimrc
modelines=6
Last set from ~/.vimrc

三、Vim 模式行应用示例

假设当前的 Vim 配置文件中有如下配置:

1
2
3
set modeline
set modelines=6
set tabstop=4

制表符被设置为 4 个空格,如果想把当前目录下的文件 test.cpp 中的所有制表符增加到 8 个空格而不影响其它所有文件,可以在 test.cpp 文件的前 6 行内 增加 // vim: noai:ts=8: 并保存。

此后,在 test.cpp 文件中输入一个制表符时,空格的数量变成了 8 个。

vim-modeline

嗯,扫一扫就可以找到小女子我啦~