定制 Vim

作者:Dan Puckett

Vim 是一款编辑器,其设计目标是像最古老的 UNIX 编辑器 vi 一样工作。Vim 不仅仅是克隆 vi;它还扩展了 vi 的功能,例如多级撤销、图形界面(如果需要)、窗口、块操作、在线帮助和语法着色。

除了新功能之外,Vim 5.5(我写作时的当前版本)有 196 个您可以设置的选项。实际上,您可能在纯 vi 中发现的任何令人讨厌的行为都可以在 Vim 中配置成您喜欢的样子。要下载或获取更多关于 Vim 的信息,请访问 Vim 首页 http://www.vim.org/。在 Vim 中,您可以随时通过按下 ESC 键,输入 :help 并按下 ENTER 键来查看在线帮助。

我承认,要浏览 196 个选项,仅仅为了碰运气找到一两个能满足我需求的选项,这个想法可能有点令人望而生畏,所以这里列出了一些我最喜欢的 Vim 定制,希望能帮助您入门。这些定制为我避免了很多挫败感,并帮助我成为了一个经常使用 Vim 的用户。

保存您的定制

在讨论具体的 Vim 定制之前,我想先解释一下如何保存您的定制,以便每次启动 Vim 时都能加载它们。当您第一次开始使用 Vim 时,它将 100% 兼容 vi。在您激活 Vim 的花哨功能之前,您不会注意到任何这些功能。

这种行为很好:它允许系统管理员用指向 Vim 的链接替换 /bin/vi,而不会引起用户反抗并尖叫:“vi 坏了。修好它!”事实上,有些人以这种方式使用 Vim 多年,而没有意识到他们使用的是比 vi 更高级的东西。但是,严格的 vi 仿真可能会让那些期望一开始就看到 Vim 所有花哨功能的人感到困惑。

幸运的是,很容易让 Vim 相信我们实际上是在 Vim 中而不是在 vi 中。Vim 定制存储在您主目录中名为 .vimrc 的文件中。如果 Vim 看到您有一个 .vimrc 文件——即使该文件是空的——Vim 也会关闭 vi 兼容模式,这将把 Vim 配置为 Vim,而不是 vi。

如果您没有 .vimrc 文件,但您确实有一个 .exrc 文件,您过去曾用它来定制您的 vi 会话,请执行以下命令

mv ~/.exrc ~/.vimrc

将您的 .exrc 文件重命名为 .vimrc。

如果您既没有 .exrc 文件也没有 .vimrc 文件,请执行以下命令

touch ~/.vimrc

创建一个空的 .vimrc 文件。

您现在可以认真开始配置 Vim 了。您可以像将命令添加到 .exrc 文件一样,将命令添加到您的 .vimrc 文件中。也就是说,如果您尝试了 Vim 的增量搜索功能(我稍后会描述),方法是按下 ESC 键并输入命令

:set incsearch

并且决定要将增量搜索作为未来 Vim 会话的默认行为,您可以通过将以下行

set incsearch
单独放在 .vimrc 文件中的一行。请注意前面没有冒号。
快速查找:incsearch

假设您有以下文本文件要编辑

In Xanadu did Kubla Khan
A stately pleasure-dome decree:
Where Alph, the sacred river, ran
Through caverns measureless to man
Down to a sunless sea.

您的光标在第一行的 I 上。您需要找到单词 “measureless” 的第一次出现。您该怎么做?

一种方法是按 / 键将 Vim 置于搜索模式,输入 “measureless”,然后按 ENTER 键。Vim 将找到当前光标位置之后的第一个 “measureless”,并将您的光标停留在 m 上。原则上很简单,但实际上我不是一个很好的打字员。当我尝试向前搜索单词 “measureless” 时,我很有可能拼错它。如果我拼错为 “measurless”,直到我按下 ENTER 键,Vim 返回 “Pattern not found: measurless” 时,我才会意识到我的错误。

我可以搜索 “measureless” 的子字符串来增加正确键入搜索模式的机会。例如,如果我搜索 “measu”,我需要键入的字符更少,这意味着我拼错搜索模式的方式更少。但是,这意味着我必须猜测多少个字符才能指定我要查找的单词的唯一子字符串。如果我的搜索模式键入的字符不够,我最终会到达错误的位置。例如,如果我为 “me” 搜索,我最终会到达第二行的 “pleasure-dome”,而不是我想要到达的位置,即第四行。然后我必须通过按 n 键再次搜索。

Vim 的增量搜索功能可以帮助解决这两个问题。要试用它,请按 ESC 键进入命令模式,然后键入

:set incsearch

然后按 ENTER 键。

增量搜索意味着当您输入搜索模式时,Vim 会在您键入每个字母时显示下一个匹配项。因此,当您通过按 m 键开始搜索 “measureless” 时,Vim 会立即向前搜索文件中当前光标位置之后的第一个 m。在本例中,它是第二行 “pleasure-dome” 中的 m。然后 Vim 将在文本中突出显示它到目前为止为您匹配的模式。由于 “pleasure-dome” 不是您想去的地方,因此您需要在搜索模式中键入更多字母。当您按 e 键时,“pleasure-dome” 仍然与子字符串 me 匹配,因此 Vim 将突出显示 “pleasure-dome” 中的 “me” 并等待更多输入。当您按 a 键时,“pleasure-dome” 不再与子字符串 mea 匹配,因此 Vim 将突出显示 mea 的下一个匹配项,即第四行中的 “measureless”。太棒了!由于那是您要查找的单词,请按 ENTER 键,Vim 会将您的光标停留在 “measureless” 中的 m 上。

使用增量搜索,您始终知道搜索结果是什么,因为结果始终在屏幕上突出显示。如果您拼错了搜索模式,Vim 将不再显示您的搜索模式的突出显示匹配项。当您突出显示的匹配字符串从屏幕上消失时,您会立即知道应该使用 BACKSPACE 键后退并修复您的搜索模式。如果您改变了想要搜索的内容,可以按 ESCAPE 键,Vim 会将光标返回到其先前的位置。

更好的搜索:ignorecase 和 smartcase

程序员通常不会一致地大写代码。我也不例外。从一个程序到另一个程序——有时甚至,让我感到羞愧的是,在同一个程序中——我的大小写方案也会改变。

“让我想想,那个子程序的名称是 “CrashAndBurn”、“CRASHANDBURN”、“crashandburn” 还是 “Crashandburn”?” 如果您的编辑器在搜索模式中区分大写字母和小写字母方面过于挑剔,您将很难匹配字符串。另一方面,有时大小写很重要,您确实想找到 “CrashAndBurn” 而不是 “crashandburn”。该怎么办?

默认情况下,vi 和 Vim 都不会在文本中任何大小写与您输入的搜索模式完全不同的地方进行匹配;但是,我们可以更改此默认行为。Vim 有几个选项,当一起使用时,可以消除大小写混淆带来的痛苦。您可以通过按 ESCAPE 键,然后键入以下两个命令,并在每个命令后按 ENTER 键来尝试这些选项

:set ignorecase
:set smartcase

ignorecase 选项在 vi 和 Vim 中都受支持。它完全忽略搜索模式中的大小写区别。设置 ignorecase 后,搜索模式 “crashandburn” 将匹配文本中的 “CrAsHaNdBuRn”、“crashANDburn” 以及 “crashandburn” 。

在某些情况下,这比默认行为有所改进,但是如果我真的想基于大小写区别进行搜索怎么办?每次我想以不同的方式搜索时,我都必须设置和取消设置 ignorecase 吗?

在 vi 中,不幸的是,答案是肯定的。不过,Vim 更微妙一些,因为它也提供了 smartcase 选项。如果同时设置了 ignorecase 和 smartcase,则仅当搜索模式全部为小写时,Vim 才会忽略搜索的大小写。但是,如果搜索模式中有任何大写字符,Vim 将假定您真的想进行区分大小写的搜索,并将相应地进行匹配。

例如,在同时启用 ignorecase 和 smartcase 的情况下,Vim 将把 “crashandburn” 与 “CrashAndBurn” 和 “crashandburn” 都匹配。但是,如果您输入 “CrashAndBurn” 作为搜索模式,则 Vim 只会在文本中匹配字符串 “CrashAndBurn”。它不会匹配 “crashaNDBUrn”。

在实践中,这种选项组合是一个很好的折衷方案,让您可以很好地平衡区分大小写和不区分大小写的搜索,而无需设置或取消设置选项来执行它们。

保留一些上下文:scrolloff

当我在编辑程序或文档时,我喜欢在我的工作周围保留一些上下文,方法是将我正在处理的文本行始终与窗口边缘保持几行距离。

在 vi 中,我会通过在我希望编辑的行上方或下方滚动几行来维护这一点上下文,然后移回我的目标位置并进行编辑。这不是很棒,但总比盲打要好,每当我在屏幕的第一行或最后一行工作时,我都会有这种感觉。

幸运的是,Vim 可以通过使用 scrolloff 选项自动为您维护一些上下文。您可以通过按 ESC 键并输入

:set scrolloff=2

2 表示我希望始终在光标周围至少显示两行上下文。您可以将其设置为您喜欢的任何数字。Vim 将滚动您的文件,以便您的光标永远不会比您指定的行数更靠近屏幕的顶部和底部边缘。

Vim 并不总是能够遵守您的 scrolloff 规范。如果您靠近文件的底部或顶部,则光标和文件的开头或结尾之间可能没有足够的行来为您提供您要求的上下文。不过,它会尽力而为。

我强烈推荐 scrolloff 功能。它对我的帮助很大。

文件名补全:wildmode

我讨厌输入文件名。如果起始字符 “thelong” 可以从当前子目录中的所有其他文件中唯一标识文件名,那我为什么要输入像 “thelongestfilenameintheworld.html” 这样的完整文件名呢?我也有一个习惯,就是想编辑不熟悉的目录结构深处的文件。

幸运的是,Vim 具有文件名补全功能。文件名补全允许您在 Vim 中输入部分文件名,然后按 TAB 键让 Vim 搜索可以完成它的文件或目录名。如果 Vim 找到完全匹配的一个文件或目录,它会填写名称的其余部分。如果 Vim 找不到任何匹配项,它会发出哔哔声。

如果 Vim 找到多个匹配的文件或目录名怎么办?您可以通过设置 wildmode 选项来指定在这种情况下 Vim 接下来做什么。wildmode 的默认设置为 “full”。当 wildmode 像这样设置时,您第一次按 TAB 键,Vim 将填写与您到目前为止键入的内容匹配的文件或目录名之一。如果您再次按 TAB 键,Vim 将向您显示另一个完成匹配的文件。当您继续按 TAB 键时,Vim 将遍历所有可能的补全。当它用完时,您下次按 TAB 键,Vim 将显示您输入的原始不完整字符串。现在您又回到了起点。如果您再次按 TAB 键,Vim 将再次显示第一个匹配项。

虽然这很好,但我更喜欢我的文件名补全以稍微不同的方式工作。以下是我喜欢设置 wildmode 的方式

:set wildmode=longest,list

以这种方式设置 wildmode 使 Vim 的行为如下。当我输入文件名的一部分并按 TAB 键时,Vim 会将我的文件名补全为备选项中最长的公共字符串。然后它等待我执行以下操作之一:按 ENTER 键接受该文件名,从该位置继续键入文件名,按 ESC 键取消命令,或再次按 TAB 键。第二次我按 TAB 键时,Vim 将列出所有可能完成我的部分文件或目录名的文件。

不喜欢我上面列出的任何一种文件补全方法?不用担心:wildmode 有许多不同的选项。有关详细信息,请输入

:help wildmode

Vim 将向您显示每个可能的选项。

结论

享受定制 Vim 的过程吧。如果您一次迈出一步,您会发现随着时间的推移,使用 Vim 变得越来越愉快。我认为您越是让 Vim 以您的方式而不是默认方式工作,您就会越喜欢它。

更多信息

电子邮件:puckett@acm.org

Dan Puckett 为一家相当大的电信公司提供配置管理软件支持。他是一位作家和演员。欢迎您通过 puckett@acm.org 发表评论。

加载 Disqus 评论