写给非程序员的 Vim 新手教程

想为非程序员写一篇 Vim 新手入门教程有很久了。
很多人说 Vim 入门学习曲线陡峭,又只适合程序员、系统管理员使用,纷纷敬而远之。
网络上各种入门教程要么千篇一律,要么极为简单,要么假设读者已经有编程基础。
对新人确实不够友好,一定程度上也阻止了更多的人学习、喜爱上 Vim。

而以我自学的经历来说,Vim 的上手远没想象的那么恐怖。
非程序员写写中文文章、脚本、配置文件等也能从 Vim 中获益良多。
也许我自学的方法和心得对新人有用,希望这篇新手教程能够帮到愿意尝试 Vim 的朋友。

本篇教程希望在如下方面做得更好:

  1. 尽量细致讲解一些基础概念。知其然并知其所以然才能更好的记住知识。
  2. 提供实用的助记方法。在理解基础上,找到规律再记忆,能达到事半功倍的效果。
  3. 面向非程序员,教程基于 Windows 下的 gVim(GUI 图形界面版本),覆盖尽可能多的新手,降低入门难度。而其他大部分优秀教程都是在 Linux/Mac 系统下的。
  4. 提醒注意或避开一些经典的坑,特别是 Windows 下的,不至于掉到坑里连怎么求助都不知道,新人可以少遭点罪。

为什么选择 Vim

我曾经在 Windows 平台下寻找了很久,希望找到一个功能强大、稳定、高效、占用资源少、自定义能力强,最好是免费、开源、跨平台(只是日常使用也会接触到各种操作系统)的编辑器。
其他要求容易评价,功能强大、高效和自定义需求方面,很难说哪个编辑器是适合所有人的。
就我自己而言,反正在主力编辑器换用 Vim 之前,经常会为了增加或完善某个功能尝试不同的编辑器。
而在那之后,基本上只需要找相应的操作快捷键、命令、配置或插件,因为99%的情况下,Vim 已经做到了,只等着你去发掘操作、配置方法和插件,或者自己编写。

因此,只要度过最初的入门阶段,知道到哪里去发现增强功能的手段,今后的文本编辑和处理就可以一直在 Vim 的平台上完成,越来越熟练,从而节省了寻找和适应新编辑器的时间。

而且,Vim 的设计哲学与其他文本编辑器截然不同,在这种设计哲学下,文本操作效率高,入门后复杂的快捷键和命令其实也并不难记忆,习惯了之后有举重若轻、事半功倍的快感。
即使许多编辑器有模仿 Vim 操作指令的模式,但只能模仿一部分,永远也无法完全复制原生 Vim 的体验。

如今大部分高级编辑器,不论是与 Vim 相爱相杀多年的 Emacs 还是后起之秀 VS Code,都有 Vim 模式;
流行的浏览器,如 Chrome、Firefox、Edge,也都有应用 Vim 模式的扩展;
这正说明了 Vim 哲学的生命力和魅力:就算离开 Vim,甚至 Vim 作为一个编辑器软件不再存在,我们也依然可以将其他编辑器或软件当作 Vim 设计哲学的载体,受益于它。

Vim 的入门之道

传说中 Vim 的学习曲线是陡峭的悬崖,但我更倾向于认为这是因为入门方法不正确。
我希望新人们先接受 Vim 的设计哲学,了解到 Vim 的操作为什么如此与众不同,明白如此设计的优势何在,看上去纷繁无比的命令、指令和配置才不会显得那么可怕,反而可以在不断的学习中融会贯通。

从心态上说,我希望初学者从基本的编辑功能开始,逐步替换基本的编辑器,不要试图一下子掌握太多技能。
然后也不用纠结一上来就完全抛弃鼠标和方向键,练习的过程中觉得怎么方便怎么来就行,不要给自己太多压力。

其他教程

为避免本教程水平有限误人子弟,欢迎不得其法的入门者尝试以下的其他教程,不要因为入门艰难而放弃探索这个有意思的编辑器。
也可相互参考,同步学习,不必拘泥于本教程的章节顺序设置。

中文翻译

其他编辑器推荐

Vim 肯定不可能适合所有人,只要你找到最适合自己的工具,完成好自己的工作,不用纠结这个工具在别人看来如何。
如果最终还是没法适应 Vim,我推荐在 Windows 下其他几款文本编辑器:

  • Visual Studio Code
    微软出品的开源、跨平台编辑器,性能优化不错,发展迅速,已经成为最主流的编辑器之一。

  • Notepad ++
    基于 Scintilla 的开源、免费文本编辑器,小巧迅捷,遵循 GPL 协议。

  • EmEditor
    日本公司开发的共享软件,速度快,大文件支持好,有多种贴心功能。
    有可免费使用的老版本。

  • Sublime Text 23
    很受前端程序员欢迎的文本编辑器,界面美观,速度快,功能强大,插件也较多。

  • UltraEdit
    很经典的编辑器,至今还有大量程序员在使用,付费软件。

  • EditPlus
    另一款非常经典的编辑器,韩国人出品,同样也有大量用户,付费软件。

  • EmacsSpacemacsDoom Emacs
    Emacs 堪称功能比 Vim 更加强大的文本编辑器,后两者则是在 Emacs 基础上融合插件和优化配置的尝试。

Vi 的设计哲学和操作逻辑

学习 Vim 最关键的不是死记硬背,而是先知其所以然。

Pascal Precht 在《为何使用 Vim》中说,用好 Vim 要理解:
- 模式概念
- 文本对象

Vim 特有的操作逻辑都基于这两个概念,理解了这两个概念以及为何 Vim 如此设计,你会发现,Vim 的学习曲线更像翻墙而过,而不是一直爬陡坡。

以下的概念介绍很重要,但不必记住具体的操作,后面的基础操作讲解中都会提到,到那个时候再动手练习也不迟。

模式

Vim 的模式有许多种,作为入门者最常接触的有四种(近似的模式做了合并):

  1. 普通模式 normal mode
    用于输入编辑文本的指令和移动光标。
    例如在普通模式下输入 x,会立即删除光标所在的字符(你可以将 x 理解为画一把叉表示删除,方便记忆)。
    输入 h/j/k/l 分别是向左/下/上/右横向一个字符或纵向移动一行。
    普通模式是 Vim 的默认模式,也是切换到其他模式的入口。许多资深用户认为一旦停止输入,应该立即回到这个模式下。

  2. 插入模式 insert mode
    用于输入文本字符。与一般的文本编辑器并无二致。

  3. 命令/执行模式 command/ex mode
    用于输入命令,执行函数,变更配置。
    例如在普通模式下,输入 : 进入命令模式,然后输入 sort 回车,给所有行排序。

  4. 可视/选择模式 visual/select mode
    用于选择文本对象,以便对其执行下一步操作。
    例如在普通模式下,输入 V 会选中光标所在的那一整行,接下来输入的操作命令都是针对这一整行文字的。

新手学习 Vim 遇到的第一堵墙一般是,一开始进入 Vim 并不能直接输入文字,因为默认是处于普通模式中,切换到插入模式才能像一般的编辑器一样输入。

既然这样麻烦,那为什么 Vim 要设计多模式呢?
我的理解是,文本编辑器在输入文字之外,还有调整文字的任务,因此必然需要输入一套命令信息,并能区分于输入的文字信息。
Vim 为了更好的完成调整文字的任务,在输入文字之外增加了多种模式。

输入的命令信息可以分为三类:

  1. 非键盘操作
    比如鼠标或手指的选择、点击、拖拽等等,或借助菜单触发指令。
    一般的文本编辑器都支持这种方式,直观易上手是最大的优点。
    弊端是,随着操作越来越多,此类命令就越难以记忆,或者界面上的菜单、按钮等等越来越复杂。
    在 Vi/Vim 诞生的年代,还没有普及这么高级的输入方式,虽然现在也支持,但许多人入门后会隐藏菜单、禁用鼠标。

  2. 增加指令键,引入按键组合
    CtrlShiftAlt/Meta/OptionsWindows/CommandFnF1-F12等功能键,InsertDelete 等编辑键,这些按键和字母、数字、符号键的组合,以及这些组合之间的组合,都能与输入的文字信息区分开来,让计算机可以识别。
    一般的文本编辑器也采用这种方法,与第一种方案结合,可以满足大部分人的需求。
    Vim 中的许多指令也会用到这些按键组合。
    弊端是,有的辅助按键本身并无含义,又住在键盘的偏远角落里,有的复杂命令可能需要多个按键同时按下,还可能反复多次组合,长期使用下来,手指很遭罪,记忆难度也迅速上升。
    而且,这类按键组合容易与其他程序不可调整的全局快捷键冲突。

  3. 增加模式
    增加模式的结果是,在插入模式下用于输入文字的按键,在普通模式下按下就变成修改文本或移动跳转的命令,在选择模式下就变成改变选择范围的命令。
    相当于在输入按键基本不变的前提下,输入的命令信息因为模式的增加而翻倍
    这样,数字、字母、符号键也就能够充分利用起来,这些按键的意义也比辅助按键易于记忆。
    正是这种不同一般的思路使 Vi/Vim 选择多模式方案,与一般的文本编辑器分道扬镳。

文本对象

Vim 可以识别文本中的英文单词、句子、段落、块,并有对应的文本对象选择命令。
与编辑、移动、选择的命令结合起来,可以快速的操作整个文本对象。

以如下这段文字为例:

文本对象示例1

普通模式下,光标在浅蓝色范围内任意一处时,按下 viw 就会选中整个浅蓝色部分的单词。
而这个命令组合翻译过来就是:
v: visual,进入可视模式,开始选择文本
i: inside/inner,内部,表示如果单词后面有空格等其他字符,选择的范围不包括空格
w: word,单词

学习和记忆 Vim 的指令时,建议尽量找到其对应的英文单词,只要能方便记忆就行,不必纠结于单词是否正确。
这样很多指令组合就像用英语说话,可以大大降低记忆难度。

如果光标在绿色范围内时,按下 yis 就会复制整个绿色部分的句子。
这组命令的含义是:
y: yank,复制
i: inside/inner,内部
s: sentence,句子
非常接近于自然语言:yank inside sentence.

如果光标在黄色范围内时,按下 dap 就会清除整个黄色部分段落的内容,光标停留在下一段的起始处。
这组命令的含义是:
d: delete,删除
a: around,围绕在外部
p: paragraph,段落
delete around paragraph.

注意,Vim 原生环境不能按照中文文本对象规则识别中文字符和标点,比如在处理如下示例文字时:

文本对象示例2

粉红色部分会识别为一个单词,理想情况下应该按中文含义分词再选择,显然目前还没有编辑器能够做到这点。
淡紫色部分会识别为整个句子,这就错得更加离谱了,原因是 Vim 对逗号、分号、句号一视同仁。
淡蓝色部分还是会识别为段落,因为段落是根据换行判断的,中英文没有区别。

借助插件能扩展 Vim 对文本对象的支持。

做好一件事

Vim 只专注做一件事情——纯文本编辑器,不考虑编辑富文本,不插入图片,更没有成为“操作系统”的野心。

减少重复操作和复杂度

重复的劳动就应该交给编辑器来完成,编辑者要做的是提取文本操作的规律,转换成 Vim 可以识别的操作语言。
也许一开始会觉得这种转换过程还不如重复操作快,但一旦掌握了 Vim 的“语言”,效率可以成倍提升。
这时,使用者的思维和操作方式已经变了,从重复机械动作发展到抽象出操作的模式,再用抽象出的模式应对千变万化的文本。
即使今后历史悠久的 Vim 退出主流文本编辑器的舞台,这种抽象和精简模式的思想也会继续流传,并在文本编辑之外的领域发扬光大。

Vim 的短板

在蛊惑新人下载安装之前,先说明一下 Vim 做不到和做得不好的地方。倘若你无法接受这些缺陷,后面的内容就可以不用看了。

  • Vim 不是大而全的“操作系统”或包打天下的“万能工具”
  • Vim 无法内嵌显示图像或其他多媒体格式的内容
    Vim 固然功能强大,但依然专注于纯文本编辑,坚持“Make each program do one thing well”的 UNIX 哲学。
  • Vim 不支持非等宽字体
  • Vim 不支持在指定列软换行,要么在窗口处折行,要么使用硬换行,但有变通办法模拟软换行
  • Vim 处理超长行和大文件的语法高亮存在性能问题,未来可能有望解决
  • Vim 没有统一的插件市场/社区,总体弊大于利
  • Vim 无法替代一些编程语言的 IDE
    不用争辩 Vim 是否可以武装成为最强大的 IDE,Vim 不会是程序员的终极工具,也不是程序员的专用工具。所以我才会写下本文,希望非程序员也可以享受到 Vim 的强大与便捷。

安装

下载

Vim 官方网站下载页下载,Windows 平台用户选择安装包文件即可。

下载

安装的过程就不做演示了,但请务必记住 Vim 的安装目录,以及操作系统分配给当前用户的用户目录。
根据版本和选项不同,这些目录下有名为 _vimrc 的文件,是 Vim 的关键配置文件,后面会详细说明。

如果今后报错说缺少 iconv.dll 文件,可以从 gettext for Win32 下载的文件中提取,放在 gvim.exe 所在的目录中,如 vim90 目录。

有其他人自己编译了支持 Perl、Ruby、Lua 等的 Vim 版本,这样可以用上更加强大的插件。
你可以下载 Vim 源码自己编译,也可以下载其他人编译的版本,比如这里这里

启动

在安装目录中有 vim.exegvim.exevimrun.exe 等可执行文件,因为是面向非程序员,所以我们优先使用有图形界面(GUI)的 gvim.exe 作为启动命令。

救命!

不要恐慌!
如果你在使用 Vim 时晕头转向,手足无措,一般有两个救命锦囊(并不保证总是有效 :P):
1. 按键盘左上角的 Esc 键,返回刚进入 Vim 时的普通模式,然后再重新出发。
Esc 表示 Escape,记忆为“逃脱”就行。
2. 在普通模式下输入 :help 关键字,根据关键字查找 Vim 帮助文档中相应的主题(可以简写为 :h 关键字)。

帮助

学习到相关的知识后再尝试操作。
其后我会在知识点中加上对应的帮助主题关键字,以斜体表示。如有更多疑问,可在 Vim 中自己查找帮助文档。
更高级的用法是 :helpgrep 关键字,像 grep 命令一样查找帮助文档中包含关键字的所有行,但只会在新窗口中展示第一个匹配的结果,更多的用法可以自己输入 :help helpgrep 探索。

作为基本编辑器的 Vim

掌握 Vim 的强大功能之前,建议先将其作为基本的编辑器使用一段时间,在日常使用过程中一步步发掘不同于一般编辑器的功能点,渐进式地学习。
所以,我会先讲解如何将 Vim 当作最简单的编辑器使用,然后再逐步引入更高级、更复杂的功能。

初次进入的界面

在默认配置下,首次进入 gVim 会看到如下界面:

启动界面

菜单栏和按钮工具栏与一般的文本编辑器大同小异,菜单中部分命令有相应的命令提示。

菜单

如果不熟悉常用功能的命令,可以暂时保留菜单栏和工具栏,等到熟悉了再隐藏。

目前我自己配置的界面是这个样子:

自定义界面

原来菜单栏和工具栏的位置被缓冲区标签页代替。
底部则是状态栏,显示当前的模式、文件名、文件修改时间、文件格式(dos、unix 或 mac 格式)、字符编码、文件类型和光标位置信息。

自定义界面

如果按 : 进入命令模式,则在状态栏下方输入命令:

输入命令

不妨输入以下命令
:echo $VIM
:echo $VIMRUNTIME
:echo $HOME
分别可以在最下方的状态栏看到 Vim 的应用程序所在目录、运行时目录、操作系统中的用户目录。
后续有可能会用到。

启动参数

Windows 下使用 Vim 打开文本文件会自动新建窗口,启动一个新的 gVim 实例。
你也可以更改启动命令的参数,使用 gvim.exe --remote-silent,在同一个窗口的新缓冲区中打开,或使用 gvim.exe --remote-tab-silent 在新的标签页中打开。

我自己是使用 Total Commander + candy,在任何文件上按下 F4,会跳出 candy 的菜单:

candy

然后可以自由选择是在新的 gVim 进程实例还是新的缓冲区打开文件。

关于缓冲区、标签页的说明,后面会提到。如果不熟悉,可以暂时不更改启动参数,保持原样。

进入插入模式开始编辑

因为默认模式是普通模式,所以要输入文字需要进入插入模式。
进入插入模式最常用的指令是 i,是 insert 的缩写,含义是在当前字符之前插入,也就是移动光标至当前字符之前再进入插入模式。
例如,现在要在光标所在位置之前开始编辑文字:

插入之前

左下角的模式显示为 NORMAL,表示处于普通模式。

按下 i 键后,光标变为表示可以输入的竖线:

进入插入模式

如果无法正常进入插入模式,界面上出现未上屏的 i 字符,多半是因为开启的中文输入法抢先拦截了。
可以切换到英文输入状态,然后在普通模式下输入指令。
如果觉得总是英文输入状态很麻烦,可以试试谷歌输入法、手心输入法等。

如果要在当前字符之后插入呢?
按下 a 就行,含义是追加,对应的英文为 append

也许你会觉得,在字符前还是后进入插入模式还要弄两个命令,太小题大做。
那插入新行的指令 oO 就显得实用多了。
在普通模式中输入 o,表示在当前行下插入新行,并停留在插入模式。
相比之下,一般编辑器需要按 End 移动光标到行尾,再按 Enter 换行。
大写字母 O 指令则正好相反,在当前行上面插入新行,并停留在插入模式。
相比之下,一般编辑器要按 Home 移动光标到行首,按 Enter 换行,再按 Up 移动到新行。

更加厉害的是,上述指令可以与数字配合。
遵循 [count]command 的格式,如 12O,进入插入模式输入文字后再按 Esc 退回普通模式,刚才输入的文字就会变成12行。
如果你想快速插入分隔线,这个也很有用。

输入法

如果你使用 Vim 写中文文章,那么有一个比较困扰的问题是每次切换模式时,都要注意切换输入法的中英文状态。
例如,在普通模式下保持中文输入状态时,按 a 不会进入插入模式,因为系统认为你在输入拼音,等按键确认上屏后才会切换模式。

在 Windows 环境下,暂时没有完美的解决方法,不过,谷歌输入法、手心输入法、卡饭输入法、Windows 10系统自带的微软输入法遇到的问题相对较少。

光标移动

在插入模式下,光标的移动与一般的文本编辑器基本没有区别,除了涉及折行的上下移动,具体见后文解释说明。
但这样的移动方式效率太低,如果要熟练掌握 Vim,必定要学习其别具特色的光标移动指令。

最简单的移动指令相信初学者也有所耳闻,就是标准键盘右手四指附近的 hjkl 四键,分别对应普通模式下,左、下、上、右四方向移动光标的操作。
因为小拇指操作比较别扭,所以分配给食指的是 hj 两个键,如果你的键盘盲打手势很标准,熟悉这四个指令应该不是难事。

除此之外,还有指令取代 HomeEndPageUpPageDown 键。
0^ 都是移动到当前行的行首,区别在于 ^ 移动到的是第一个非空白字符。
$ 则是移动到当前行最后一个非空白字符。
Ctrl-F 对应 PageDownF 代表 Forwards,前进。
Ctrl-B 对应 PageUpB 代表 Backwards,后退。

还记得之前提到的文本对象概念吗?
以文本对象为单位跳转的功能自然少不了。
w 指令用于跳转到下一个单词的头部,助记的单词是 word。
e 指令跳转到下一个单词的尾部,助记的单词是 end。
b 指令跳转到上一个单词的头部,助记的单词是 backwards。
每个指令都有相应的大写指令,不过是以字符串而不是单词为单位跳转。

比如,跳转的位置如下所示:
跳转位置

因为存在英文标点符号,因此 wW 跳转的位置会有差异。

注意:由于中文的文本对象识别不完善,因此相应的跳转功能也未尽如人意,未用空格等特殊字符分隔的一串中文字符,在跳转时会被当作单词。
中文跳转

这些指令同样可以和数字结合起来使用。
比如,10j 表示光标向下移动10行;
2<Ctrl-F> 表示光标向下移动2个屏幕;
4w 表示向后跳4个单词。

有的编辑器可以迅速跳转到文档最开始和最后的位置,Vim 对应的指令是 ggG,助记的单词都是 go。
如果是跳转到当前屏幕的顶部、中部和底部,可以分别输入 HML,对应的单词分别是 HomeMiddleLast
如要直接跳到指定行,直接进入命令模式输入行数即可,如 :100 就会跳到第100行。

有时候我们并不想光标逃开,而希望屏幕相对光标和我们的视线滚动,这样就不必重新定位光标所在位置。
上下相对滚动屏幕的常用指令有 ztzzzb,分别对应屏幕相对滚动后,光标所在行显示在窗口的顶部、中部和底部。

更有威力的指令是跳转。
Ctrl-O 是跳转到光标上次移动到的位置,而 Ctrl-I 正相反。
当你移动光标去另一处临时编辑后,要回到之前的位置时,会发现这个指令非常实用。

注意,Vim 有个古怪之处,光标会始终停留在屏幕范围内。
如果你用鼠标拖动滚动栏上下翻页,光标不会待在原地不动,而会跟随屏幕移动。

另外,Vim 中与行相关的移动也与众不同。
一般的文本编辑器,按 End 跳转到行尾时,如果该行在窗口内换行,那么光标还是会停在换行处:

行尾

而 Vim 中按 End$ 则是无视窗口换行,直接跳到真正的行尾:

真正的行尾

同样地,行间移动也比较有个性:

普通的文本编辑器中,上下移动是这样的:

上下移动

而 Vim 中是这样的:

上下移动

如果你日常使用窗口内换行的设置,可能会因此而困扰。
不过好在在设置中这可以修改为符合普通编辑的方案。

由于本教程面向非程序员,因此涉及代码常见的成对符号、标签间的跳转就略过了。
更多的指令可自己查看 scrollingcursor-motions 的帮助文档。

保存

输入一些文字之后,如果点击工具栏上的 保存 按钮,Vim 会提示说:
E32: 没有文件名
入门者可能被吓住,一般的编辑器不是在保存未命名文件时会弹出系统浏览器,让你选择保存的路径和文件名吗?
这是怎么回事呢?

这是因为需要事先指定保存的路径和文件名,Vim 才知道要保存到哪里。
如果一开始没有指定文件名,需要使用 savesaveaswrite 命令指定路径和文件名。
如输入 :save test.txt 回车,默认会在 Vim 的当前目录(current-directory)保存 test.txt 文件。
你也可以在输入文件名之前,save 指令的空格之后,输入路径,并按 Tab/Shift-Tab 让 Vim 自动补全路径。
saveaswrite 命令可以分别简写为 savw

如果希望看到熟悉的弹出窗口,通过 Windows 自带的资源浏览器选择保存的路径和文件名,那么可以使用 :browse save 命令:

保存

之后可以使用 Ctrl-S 快捷键或点击 保存 按钮,也可以再使用 :w 命令来保存文件。

打开文件

如果习惯使用资源浏览器打开文件,可以输入 :browse edit 命令,然后读入指定的文件开始编辑。
如果不想调出资源浏览器窗口,新文件的位置又在附近,直接输入 :edit 然后使用 Tab/Shift-Tab 补全文件名更能更快。

如果希望像一般的多标签编辑器那样,新打开的文件显示在新的标签页中。
可以使用 :tabedit filename:browse tabedit 命令:

标签页打开

如果喜欢多缓冲区模式,换成用 :enew filename 命令即可,相当于 edit new。

当然,最快的还是配合 Total Commander 和 candy 使用。

同时处理多个文件时,Vim 的缓冲区(buffers)、标签页(tab-page)和窗口(window)的概念与一般的编辑器有些差异,入门者会犯糊涂很正常。
后续会有详细章节介绍这些概念。
我建议尽量在一个窗口中使用多个缓冲区,为了方便可以开多个窗口,而尽量不要使用多标签页。
等到你熟悉了这些概念后,可以自由选择适合自己的多文件管理方式。

选择

既然 Vim 号称可以无鼠标使用,那么要用什么方法代替鼠标点选文字呢?
答案就是可视模式(visual-mode)和选择模式(select-mode)。

在普通模式下,按键 v 用于进入可视模式,进入后即会选择光标当前所在的字符。
此时如果再移动光标,则光标经过的位置都会选择。
再输入指令,就会处理选择的内容。
例如,v$ 表示选择从当前光标所在位置到行尾的所有字符。

选择指令的威力配合文本对象和操作指令才能完全发挥(visual-operators),比如:
选中整个段落: vap,visual around paragraph
选中 HTML/XML 标签内的内容:vit,visual inner tag
按照指定的宽度(textwidth)重新排版:选中之后输入 gq

Vim 的指令大小写通常有关联,大写的 V 同样可以用于选择,不过其效果是选择光标所在的整行。
例如 ggVG 全选操作可以分解为:
gg:光标跳转到文档第一行第一列;
V:进入可视模式,选择整个第一行;
G:光标跳转到最后一行,列位置不变(因为之前光标在第一列,G 跳转后应该也在第一列)。
由于 V 是选择整行,因此不管 G 跳转后,光标在哪一列,最后一行都会全部选中。

用惯了 Windows 系统默认快捷键的用户可能会认为,Ctrl-A 全选更快捷。
Windows 下的 gVim 默认也是可以按 Ctrl-A 全选的,但 Ctrl-A 在普通模式下另有妙用。
如果你习惯了 ggVG 的全选操作,可以自己查看和修改 Vim 安装目录中的 mswin.vim 文件,解放 Ctrl-A 快捷键。

整列选择的指令是 Ctrl-V,但因为和 Windows 系统的粘贴快捷键冲突,gVim 默认的快捷键映射为了 Ctrl-Q
所以当你在其他教程中看到说 Ctrl-V 的列块操作时,请记得在 gVim 中换成 Ctrl-Q
当然也可以编辑 mswin.vim 文件取消这个映射。

整列选择后,Vim 相当于进入了其他编辑器的列块模式。
使用 jk 或其他光标移动指令选择整列文字后,按 IA 分别在选中列块之前或之后进入插入模式。
输入文字后按 Esc 回到普通模式,刚才输入的文字就会插入之前选择的各行。

例如,光标在以下文档最前方,需要在每行第二列插入空格字符:

列块模式

按下 Ctrl-Q,可以看到左下角的模式已经转换为“可视 块”,表示不但已经切换到可视模式,而且是列块模式:

列块模式

按下 G 或者 2j 移动到最后一行,可以看到选择的范围也相应变成所有行第一列的字符:

列块模式

再按下 A ,光标即落在第一、二列之间,输入一个空格后效果如下:

列块模式

这时只看到第一行插入了空格,其他行却维持原样,这行事风格和其他编辑器的列块模式不一样啊。
不要恐慌,按下 Esc 退出可视模式之后,事情起了变化:

列块模式

Vim 中的选择一样可以使用鼠标,和一般的文本编辑器类似,左键按住然后拖动就行。
列块模式的选择则是按住 Alt 键,再用鼠标左键选择。
如果你忘记了键盘指令,临时用鼠标对付就是了。

有时候我们选择了文字之后,因为各种原因取消了选择,又想再重新选择,可是文字太多,或者早就跳转到文档其他位置了,很难再回到之前的状态,该怎么办呢?
Vim 提供了一个神奇的指令:gv,助记方法是 get/gain visual
在普通模式下,只要没有再次选择,输入该指令就能重新选择上一次选择过的文字。

至于选择模式,对入门用户来说更像一般的文本编辑器中的操作方式,选择文字之后继续输入,就会替换被选择的文字。
进入选择模式的方法是,在可视模式下选择文字之后,按 Ctrl-G

复制和粘贴

Vim 另一个违背新手习惯的地方是,默认设置下,它的“默认剪贴板”与系统剪贴板不通用
也就是说,虽然它有粘贴命令,但在其他程序中复制的内容,无法简单地通过粘贴命令贴到 Vim 中。
在 Vim 中通过复制命令复制的文本内容,也不会传递给系统剪贴板,而是存放在其内部的寄存器中。

好在这个问题通过一行简单的配置代码就可以解决。
如果你等不及,可以去后面的配置章节看看。
如果只在内部试试复制粘贴,请继续往下阅读。

Windows 系统中,复制、粘贴的快捷键是 Ctrl-CCtrl-V
而 Vim 中对应的指令则是 yp,用于助记的词分别是 yank 和 paste/put。

复制通常有三种操作方式,其一是先进入选择模式选择好要复制的文本后,输入 y 指令。
只要熟悉了选择模式,再结合 y 按键就可以了。

另一种操作方式是与文本对象结合,比如之前范例提到过的:
yis:yank inner sentence,复制整句
还有:
yab:yank around brackets,复制小括号(())及其内部的内容
只要你熟悉了文本对象,也可以迅速和复制命令结合使用。

第三种是在普通模式先输入 y 指令,然后移动光标,如:
y0:复制从光标处到行首的文本
y3j:复制从光标处到下移3行后之间的文本
甚至可以 y:100<CR>:复制从光标处到第100行的文本,其中 :100<CR> 表示进入命令模式,跳转到第100行。
只要你熟悉了光标移动的操作,同样可以迅速和复制操作结合起来使用。

比较特殊而常用的用法是 yy,即复制光标所在的整行,包含行尾的回车换行。
指令前面也可以加数字,表示操作的次数,如 3yy 就是复制光标处及以下的3行内容。

复制之后,移动光标到要粘贴的位置,如果按下 p 表示粘贴到光标位置之后,按下大写的 P 表示粘贴在光标之前。
如果复制的内容是整行,那么 p 会将整行粘贴到当前行之下,P 正好相反。
粘贴指令之前也可以加数字来多次重复粘贴。

删除/剪切

普通模式下的删除有两个指令:
x:助记词组是 cross out,用于以字符为单位删除,如 3x 表示连续删除3个字符。
d:助记单词是 delete,用于与光标移动结合删除,如 d3l 同样也可以连续删除3个字符。
dd 对应于 yy,是删除光标所在的整行。
两个指令都可以与选择模式结合使用。

至于剪切,好吧,Vim 中删除就是剪切,因为内容删除后可以用粘贴指令粘贴出来,其效果就等于剪切。
实际上 Vim 中的删除是将文本送到了某个特殊的寄存器中,这个寄存器也用于复制和粘贴,所以才会有删除=剪切的功效。
这也是让新手迷惑的地方,因为复制之后,如果又做了删除操作,刚才复制的内容就消失了……
熟悉了之后,这倒不是什么大问题,何况也可以指定用于删除、复制、粘贴操作的寄存器,这就属于进阶的学习内容了。

关闭退出

Vim 专属的经典笑话是“新手如何退出 Vim?”,实际上可没有那么可怕。

Vim 当然还是支持 Windows 系统中标准的快捷键 Alt-F4,或者直接用鼠标左键点右上角的关闭按钮。

但更加常用的方法,是在命令模式下操作,输入 :q 退出当前的窗口。助记单词为 quit。
如果当前窗口是最后一个,则整个 Vim 程序都会关闭、退出。

如果文件之前没有存档,可以保存和退出一步完成::wq,相当于 write and quit。
也可以用 :x 命令,与 :wq 的区别是,如果文件没有修改变动,前者不会实际写磁盘。
如果不想存档就退出,就需要加惊叹号用于确认:q!

如果觉得输入 : 很麻烦,也可以在普通模式下,用 ZZ 指令代替 :x 命令,用 ZQ 指令代替 :q! 命令。

如果你和我一样习惯使用多缓冲区,则可以用 :bd 命令退出当前缓冲区,它是 buffer delete 的简写。

查找

Vim 的前身 Vi 最初是纯字符命令行界面的编辑器,因此不可能像我们日常接触的编辑器一样,弹出查找窗口用于输入要查找的字符串。
相应的查找方法也就是像输入命令一样,只不过输入命令是使用 : 指令,而向文档下方查找的指令是斜杠 /

例如要查找“无涯”,在普通模式下直接输入 /无涯 然后回车,光标会跳转到第一个搜索结果上:

查找

? 指令则是向文档上方查找。

只要将 ?/ 看作召唤出查询界面的命令就好了,特别是 ? 代表要查找时的疑问,这样是不是比用通用的 Ctrl-F 组合快捷键更加省事呢?

如果要重复上一次搜索,再向前/后查找同一个关键词,按 n 键,表示 next。
重复相反方向查找的指令是大写的 N

一般使用 / 就够了,这样 nN 就分别固定表示继续向下查找和反向向上查找,更加容易记忆。

还有,曾经搜索过的内容都保留在操作历史中(保留的数量可以在配置中自定义),按 / 之后用上下方向键可以浏览,输入起始字符可以缩小范围。
例如,输入 /fo 再按 ,可以逐个查看以 fo 开头的搜索历史。

默认状态下,Vim 的查找对大小写敏感,如搜索 vim 是定位不到 Vim 的。
在后面的配置介绍中,会告诉你如何修改设置,更合理地区分查找大小写文本。
还有搜索结果高亮、使用多种颜色标记不同内容等高级功能。

如果处理英文文档较多,*# 指令非常实用,它们会以光标所在位置的单词为关键词向上/向下查找。

想了解更加花样繁多的搜索参数和指令,请查阅 :h / 的帮助文档。

Vim 的查找默认采用正则表达式,可以查找行首(^)、行尾($)、换行(\n)、制表符(\t)、空白(\s)等特殊标记,也可以查到某个条件不出现、出现一次或多次等情况。
如有兴趣进一步了解正则表达式规则,可以看看 pattern 相关的帮助文档,或者正则表达式的教程。
正则表达式应用广泛,功能强大,了解一点有好处。

一些复杂的关键词可能包含正则表达式本身用到的特殊字符,如 /.*()| 等,要做转义处理,在前面加 \ 才能正常查找。
如查找12.34时,输入 /12.34 是查不到的,要输入 /12\.34 才行。

如果用到正则表达式的机会不多,可以在搜索的关键词后加 \v\m 参数,这样大部分需要转义的特殊字符就不需要手动转义了,具体的规则参考 /magic 部分的帮助文档。
也有 Vim 插件让用户完全不用考虑转义的烦恼,后续会有介绍。

替换

最简单的替换功能就是将字符串 A 替换成 B,命令写法是 :s/A/B,意思是将本行内第一个 A 字符串替换成 B 字符串。

一般的用法是全文全部替换:
:%s/A/B/g
其中 % 表示搜寻全文范围,g 标记可以看作 globally 全局的意思,表示一行内所有匹配的 A 都替换成 B。

助记的方法是记住替换命令接近完全的形态:
:[range]s[ubstitute]/{pattern}/{string}/[flags]
别看命令很长,它是有规律的,翻译成白话文很好理解:
[range]:在某个范围内
s[ubstitute]:使用替换命令(substitute 是完整的命令名称,一般当然只用简短的 s
/{pattern}:将匹配某个模式的字符串
/{string}:替换成某个字符串
/[flags]:并且启用某些特殊功能

如果要替换指定范围内的内容,最快的方法就是先选中那个范围,然后 : 进入命令模式。
这时就不需要再指定范围,直接输入 s 及之后的参数即可。

用于替换的模式和目标字符串方面,有几点要注意:
一是要使用正则表达式表示特殊控制符,如使用 \t 表示制表符;
二是因为每行结束跳到新行时,Windows 下的回车(\r)+换行(\n)、Unix 系统下的换行以及 Mac 系统下的回车的表示方法各不相同,所以可能出现 ^M 之类的奇怪字符。
这时如果要匹配这个字符替换为正常的回车换行,可以在替换时用 Ctrl-Q Ctrl-MCtrl-Q <Enter> 打出来(还记得吗?gVim 中 Ctrl-Q 默认替代了 Ctrl-V 快捷键,所以在其他平台应该用 Ctrl-V)。
三是匹配回车换行时使用 \n,但是替换成回车换行请用 \rCtrl-Q <Enter>

常用的标记除了表示行内全匹配的 g 之外, 还有:
c:每次替换都向使用者询问、确认
n:不实际替换,只报告匹配的次数,常用语统计某个字符串出现的次数

指令 助记方法 作用
? 疑问 反向查找
/ 与 ? 共用按键 正向查找
s substitute 替换

正则表达式简介

正则表达式(regular-expression)虽然有些难以上手,但非程序员用户只要理解其思路,掌握了诀窍后,也不是那么恐怖,而且在其他编辑器或工作环境中能用上(一些细节可能有差别),可以受益无穷。
况且,不涉及编程工作和复杂的文本处理的话,需要用到的正则表达式语法来来回回也就那么多,记住几个最常用的就好。

还是从实际的应用场景入手吧。

因为 / 字符是查找的命令,也是替换功能中的分隔符,那如果要搜索或替换 / 时该如何写呢?
这个时候就需要用到转义符 \ 了,其含义是告诉计算机,后面跟着的这个字符含义变了,不能再当作命令或分隔符看待。
如查找 1/2,就不能用 /1/2 这样的命令,而应该写作 /1\/2
要替换 人天 变为 人/天,应该写作 :%s/人天/人\/天/g

同样需要转义的常见字符还有 .\[]*?,都是正则表达式中有特殊作用的一些保留字。

如果搞不清楚什么时候该用上转义符,没有关系,Escape Search 这个插件可以让你在查找时不用关心正则表达式。
想要查找什么,直接在 / 命令后面输入要查的内容,然后按下自定义的快捷键(默认是 F7),触发这个插件,它就会自动在需要转义的特殊字符前方插入转义符 \
例如,本来搜索命令是 /http://www.vim.org/,按下 F7 之后就会自动变成 /http:\/\/www\.vim\.org\/

有的特殊字符,如回车和换行,Tab 制表缩进,也需要查找和替换,需要用正则表达式来表示,较为常用的正则表达式有:

含义 正则表达式
换行符 \n
回车符 \r
空白符 \s
行首 ^
行尾 $
制表符 \t

其中空白符包括了空格、换行、回车和制表符。

比如要将行首的制表符全部替换为2个空格,可以这么写:

:%s/^\t/ /g

有个容易踩到的坑要注意,替换的目标是换行时,使用换行符 \n 表示,但替换后的效果是另起一行时,得用回车符 \r 来表示。
如将连续三个换行替换为连续两个,命令写为:
:%s/\n\n\n/\r\r/g
而不是
:%s/\n\n\n/\n\n/g

正则表达式还有各种高级用法,作为非程序员的入门新手不必一下子学太多,等要用到再临时抱佛脚还来得及。
如果要深入钻研,推荐余晟老师的著作《正则指引》。

覆写

覆写模式使用频率不高,简单地记住三类指令就行:
普通模式下,r 是覆写当前的一个字符,输入后立即退回到普通模式,用于临时修改;
普通模式下,R 是进入覆写模式,输入后按 Esc 才退回普通模式,用于大段覆写修改;
插入模式下,Insert 的功能和一般的文本编辑器相同,相当于普通模式下的 R 指令。
r 代表的是 replace

最近打开的文件

当编辑过多个文件后,下次打开时希望找到之前编辑过的文件,该如何调出历史文件呢?
最基础的办法是使用如下命令:
:browse oldfiles 或简写为 bro ol
调出历史文件清单,每个历史文件有对应的编号。
输入 q 之后,再输入对应编号回车,就能打开指定历史文件。

结合插件有更加方便好用的办法,后续会补充介绍。

撤销

初级、低频率使用文本编辑器的用户可能不觉得撤销功能有多重要,但对每天大量使用的用户来说,撤销功能是否方便、完备,和使用体验息息相关。
而 Vim 的撤销功能既方便又强大。

方便之处在于,只要一个表示 undo 的 u 指令,就能在普通模式下撤销上一次的操作。
gVim 默认保留了 Windows 下通用的 Ctrl-Z 的撤销快捷键,插入和普通模式均有效。

要是撤销之后又想恢复被撤销的内容,也就是重做,可以在普通模式下按 Ctrl-R 来恢复,助记的单词是 recover。
gVim 默认也支持 Ctrl-Y 通用快捷键,不过建议不要占用插入模式下的 Ctrl-Y 指令,因为它本来的功能是复制上一行同一列的字符。

Vim 写文件时,会同时将撤销历史写入撤销文件。
这样下次打开文件时,可以恢复上一次编辑的撤销历史,不至于保存并关闭后,就再也无法撤销了。
在配置文件章节会提及如何设置撤销历史文件和路径。

不过要当心的是,Vim 的撤销不是以单个字符为单位,如普通模式下的一次指令修改、插入模式下一连串动作,都视为一个可撤销的操作单位(action)。
也就是说,如果你进入插入模式输入、编辑了一大段文字,然后退出到普通模式,输入 u 指令,刚才输入的这所有文字都会清除掉,回到上一次进入插入模式之前的状态。

如果你以中文输入为主,可以在配置文件中加入以下内容,每次修改文本都会打断撤销序列,保证可以灵活地撤销。
autocmd TextChangedI * call feedkeys("\<C-G>u")

如果以英文输入为主,则可以在配置文件中定义插入模式的按键映射,每次按下空格键后打断撤销序列,实现以单词为单位撤销。
:inoremap <Space> <Space><C-g>u

有时候我们也会遇到反复多次修改、撤销、重做后,中间阶段输入的内容再也无法通过撤销重现的情况,因为一般的撤销历史都是线性的。
而 Vim 目前已经支持撤销分支(undo-branches),所有的变化都是改变树的叶节点,输入 :undolist 命令可以看到所有变化。
如果使用 uCtrl-R 找不回来的文白,普通模式下使用 g-g+ 指令也许可以找回来。

除此之外,还可以指定回到多少次更改之前的状态,或者多久时间之前的状态,如果有需求可以深入研究 earlier 部分的帮助文档。

如果觉得自带的撤销分支不直观,还有 Gundo 之类的插件可用。

指令 助记方法 作用
u undo 撤销
Ctrl-R redo 重做

美化

颜值要求高的用户可能看不上 Windows 环境下的 gVim 界面,丑陋的默认 fixedsys 字体,糟糕的渲染,古老年代风格的图标和配色……
怎么看都像是要被抛弃到垃圾堆的历史文物。

但其实还是可以抢救一下的。

屏幕字体渲染

Windows 10 之前的字体渲染效果非常糟糕,建议安装 MacType。
对比效果如下:

开启 MacType 之前:

开启字体渲染前

开启 MacType 之后:

开启字体渲染后

一目了然,如何选择不用多说了吧。

Windows 10 之后基本上不需要操心或者操心了也没有很大用处。

配置文件简介

以下的美化工作涉及修改 Vim 配置,所以先介绍 Vim 的配置文件。

Vim 是可以高度自定义的文本编辑器,它的各种自定义配置绝大多数都写在配置文件中,在启动时读取生效。

与只能通过图形界面自定义有限配置项的编辑器不同,自己写配置文件能够掌控的选项多多了,而且方便迁移和备份个性化的配置。
代价则是需要额外学习如何自定义配置文件,以及忍不住花费许多时间调教出最适合自己的配置方案。
所以,如无必要,不要随意动修改配置(和插件)的心思,你会投入比入门多得多的时间,沉迷其中无法自拔,这是一个老用户的人生经验。

如果你使用的 Vim 不是自己编译,而是从官方网站或他人处下载安装的,其配置文件的位置可能会有不同。
请先输入 :version 命令查看配置文件的位置,如:

查看配置文件位置

其中,$VIM 一般是 Vim 的安装目录,$HOME 一般是系统分配的当前登录用户的目录。
如果想确认准确路径的话,可以使用 :echo $VIM:echo $HOME 命令获取到完整路径。

Vim 会按照顺序在以上目录中寻找对应的配置文件。
官方推荐在 Windows 环境中使用 $HOME/vimfiles/vimrc 作为配置文件。

配置文件的内容以 Vimscripts 脚本语言书写,虽然在程序员眼里它不够强大和高效,但基础语法符合自然习惯,胜在容易理解。

比如设置显示行号,就增加一行 set number
设置搜索时忽略大小写:set ignorecase
设置总是显示底部状态栏:set laststatus=2

还可以用 map 命令自定义各种快捷键,如:
nnoremap <C-F1> <Esc>:browse saveas<CR>:普通模式下按 Ctrl-F1 打开“另存为”对话窗口;
nnoremap <F4> a<C-R>=strftime("%Y-%m-%d %H:%M:%S")<CR><Esc>:按下 F4 插入指定格式的当前时间戳;
nnoremap <C-c> :let @* = expand('%:p')<CR>:按下 Ctrl-C 复制当前正在编辑的文件的完整路径;
nnoremap <leader>ev :e $HOME/vimfiles/vimrc<CR>:按下 <leader>ev 打开配置文件。

一些特殊的按键这样表示:
C=CtrlA=AltS=ShiftCR=Enter<leader>=\(可自己重新定义)

更多关于 Vimscripts 的知识请自己查阅帮助文档,:h vimscripts

写入并保存配置文件不会立即生效,默认需要用 :source $HOME/vimfiles/vimrc 命令强制重新读取,或者重新启动 Vim。

重要的事情再说一遍,刚上手建议先不要随便修改配置文件,等到发现问题或觉得使用上不方便时,再有目的地复制其他用户的配置文件片段,并尽量找有详细注释的配置文件,以免修改后出现预料之外的状况。

自动换行、行号

因为 Vim 主要面向编写代码的程序员,默认是不换行的,也就是说,一行的文字超出窗口宽度,不会自动折回,在下一行显示,需要左右移动光标才能看到窗口之外的部分。

:set wrap:set nowrap 命令可以切换是否自动换行。
非程序员建议在配置文件中加上 set wrap,默认自动换行。

:set number:set nonumber 命令可以切换可以是否现实行号。
建议在配置文件中为此类常用命令配置快捷键映射,不用总是手工敲命令。

编码

由于历史原因,Windows 环境下的编码问题相对而言比较多。
在这里为了简单,就不详细介绍各种编码问题和设置的具体内容了,按照以下的方式配置 Vim 与语言编码相关的设置,应该可以应对大部分的编码问题:

set encoding=utf-8,内部使用的字符默认编码为 UTF-8
set fileencodings=utf-8,chinese,ucs-bom,gb18030,gbk,gb2312,cp936,打开文件时,参考此字符编码列表
set helplang=cn,设置帮助文件语言为中文
set langmenu=zh_CN.utf-8,设置菜单语言选项为中文,编码为 UTF-8
language messages zh_CN.utf-8,设置弹出信息语言选项为中文,编码为 UTF-8
set ambiwidth=double,所有在 Unicode 字符集中在东西方语言中共用的字符,如省略号、破折号、书名号和全角引号,设置为与中文字符一致的双倍西文字符宽度

字体

官方版本的 gVim 目前只支持等宽字体,如果你经常处理中文,那么可选择面就比较窄了。
目前使用比较多的有雅黑等宽字体、字体印象(Impression of Font)的多个系列(如 XHei)、文泉驿系列、Inziu Iosevka、等距更纱黑体、霞鹜文楷系列。

使用 :set guifont=* 命令可以调出字体选择菜单,但选择的结果仅对当次打开的窗口生效。关闭窗口再打开新进程,字体又会恢复到默认设置。
需要在配置文件中配置固定的字体,如以默认的黑体为例,vimrc 文件中的配置如下:

set guifont=SimHei:h11
set guifontwide=SimHei:h11

配置默认字体需要首先知道用于配置的字体名称,如果 vimrc 文件是 GBK 编码,可以使用中文名,如果像我一样习惯使用 UTF-8 编码,要使用对应的英文名称。
如系统自带的黑体是 SimHei,雅黑等宽是 Yahei_Mono,空格用下划线表示了。
字体名称与字号之间用冒号 : 分隔。

其中 guifont 用于指定图形界面版本使用的字体列表,guifontwide 用于指定双宽字符的字体列表。

如果今后隐藏了菜单栏,使用 :set guifont=* 命令可以调出字体选择界面预览字体效果。
有的时候,可能不知道如何指定字体名称,如字体名称显示为“等距更纱黑体 T SC”,在配置中实际应该写为等距更纱黑体_T_SC

小技巧:可以先用 :set guifont=* 命令选择字体,再用 :set guifont 查看当前所用的字体配置名称。

配色

Vim 继承自终端界面时代默认的配色方案大多扎眼,如果你更喜欢现代编辑器更加养眼、优雅的配色,可以到网上找配色方案装上,如官方网站,或 Vim Colors

配色方案其实就是一个后缀名为 vim 的配置文件,其中都是配置、变更配色信息的命令。
下载下来的配色文件可以放入 vimfiles/colors 目录,然后使用 :colorscheme [配色方案名称] 的方式临时启用,或者输入 :colorscheme 命令后按空格和 Tab 选择已有的配色方案。

如果要更改默认配色方案,需要在 vimrc 配置文件中写入 colorscheme [配色方案名称] 的配置内容,再重启 Vim。

语法高亮

非程序员虽然不用编写程序,但日常还是可能处理文本文档、配置、脚本和日志文件,有时也会临时改改 HTML,依然需要借助语法高亮(syntax highlight)提升阅读体验。

语法高亮也是和配色方案类似的配置文件,不过需要放在 vimfiles/syntax 目录下。

Vim 根据文件后缀名自动识别文件类型(filetype)并再根据文件类型自动匹配相应的语法高亮方案,例如文件类型为 Markdown 时,自动应用 Markdown 的语法高亮:

语法高亮

并且已经内置大部分常见的语法高亮规则。
官方网站高亮语法区也会发布其他用户贡献的语法高亮脚本。

如果觉得当前的文件类型识别不正确,可以用 :set filetype 命令手工指定文件类型:
:set filetype=markdown
这个时候输入 :set syntax? 命令(注意最后的问号),会显示当前的语法高亮规则就是匹配的 markdown 类型:

语法高亮

如果不想更改文件类型而只更改语法高亮规则,比如对 html 后缀的文件应用 Markdown 语法高亮规则,可以直接设置语法类型:
:set syntax=markdown

有时候应用语法规则会影响 Vim 效率,有的 Vim 并不会默认打开语法高亮功能,这就需要用户自己来操作。
关闭和打开语法高亮的命令分别是: :syntax off:syntax on

较现代的文本编辑功能

好了,现在最基本的编辑命令已经介绍完毕,至此,入门者已经可以用 Vim 像最简单的记事本一样写文档。(画外音:你在逗我吗?讲到现在才赶上记事本?!)
但我们当然不可能停留在最基础的功能。
以下的内容已经脱离入门的层次,如果你略过不看,并不会影响你使用 Vim 的基本功能,完成基础的文本编辑。
但如果想更深入地了解 Vim,不妨读一读。

多标签/多缓冲区

一般的文本编辑器界面通常有应用程序窗口(Program Window)和标签页(Tab)的概念。
应用程序窗口,在 Windows 操作系统中对应的是一个编辑器应用程序进程的可视界面,顶部有标题栏,底部一般有状态栏,侧边可能有滚动条,右上角有最小化、最大化、关闭窗口等 Windows 窗口的标准按钮。
标签页,是在一个应用程序窗口内同时打开多个文件时,通过文件名等标识标记、区分和方便用户来回切换的界面元素,其灵感来自于现实中文件夹的标签页概念。已经打开的某个文件,可以看作是标签页这个容器中的内容,而窗口中又容纳了多个标签页。
选中一个标签页,则编辑器展现的内容会切换到标签页容纳的文件。

在 Vim 中,增加了缓冲区(Buffer)的概念,窗口和标签页(Tab-page)的含义也有微妙的不同。

缓冲区

用 Vim 打开的文件都会加载到内存中,使用缓冲区来描述正在编辑的文件,一个缓冲区对应一个内存中的文件副本,不仅包含了文件内容,还有文件的编辑状态等配置信息,比如激活、隐藏、上次编辑所在行数等。

使用 :ls:buffers 命令可以看到当前存在的所有缓冲区,同时打开了 file1、file2 和 file3 三个文件:

缓冲区列表

第一列的数字是缓冲区的编号,可以使用 :buffer n 命令跳转到第 n 个缓冲区。

如果使用 Tabline 方式管理缓冲区的插件,可以很直观地看到当前的缓冲区情况:

缓冲区

新建缓冲区的命令 :enew 之前已经介绍过。
删除当前缓冲区的命令是 :bdelete,可以简写为 :bd,是 buffer delete 的缩写。

窗口

缓冲区内容在窗口中展示,这里的窗口并非作为 Windows 应用程序的 Vim 的主窗口,而是 Vim 主窗口内部的分割窗口概念,当同时展示多个 Vim 分割窗口时,类似于 Microsoft Word 中多窗口平铺的样式。
当修改某一个窗口中的文件时,实际是修改的这个文件对应的内存缓冲区,其他窗口中展示同一缓冲区的内容也会同步更新。
只要没有退出 Vim 进程,或删除缓冲区,否则你关闭窗口,只是关闭缓冲区内容展示的通道,看不到刚才编辑的文件了,但它依然保存在内存的缓冲区中,可以随时再次打开。

使用 :split:vsplit 命令可以开辟水平和垂直分屏的窗口。
其中的 v 表示 vertical。

同时在三个窗口中展示三个不同的缓冲区效果如下:

多窗口多缓冲区

之前所说的 :q 命令实际是关闭当前窗口。
默认情况下,如果缓冲区只在当前窗口展现,退出当前窗口时,也会关闭并从内存中卸载该缓冲区。
也就是说,如果退出 file1 在左上角的展示窗口,file1 的缓冲区也会从缓冲区列表中消失。

如果在配置文件中设置了 hidden 参数,则退出窗口时,缓冲区还保留在内存中。
也就是说,如果退出 file1 的展示窗口,file1 的缓冲区仍在缓冲区列表中。

:only 命令可以只保留当前窗口,关闭其他所有窗口。

Ctrl-W 开头表示这个组合快捷键与 Window 窗口有关。
比如 Ctrl-W q 可以关闭当前的窗口。
光标在多窗口之间跳转可以在普通模式下使用 Ctrl-W h/j/k/l 指令。
移动窗口的相对位置,左下上右的指令改为大写:Ctrl-W H/J/K/L
交换对调上下、左右窗口的位置,使用 Ctrl-W r 指令。
换成 Ctrl-W +/-/ 则可以调整当前窗口的高度和宽度。

如果更习惯使用鼠标操作,你也可以直接用鼠标点击窗口移动光标,或者将鼠标移动到窗口边缘拖动来改变窗口大小。

标签页

标签页可以看作介于 Vim 应用程序主窗口和分割窗口之间的容器,可容纳展示一个或一组分割窗口,可以通过 :tabedit filename 命令在另一个标签页中打开指定的文件,在这个标签页中又可以打开多个窗口。

一般情况下 Vim 的标签页长相普通:

标签页

但 Vim 的标签页与普通的多标签文本编辑器还不太一样。
其他编辑器的标签页以文件为单位,一个文件对应一个标签页。
而 Vim 的标签页是分割窗口的容器,一个标签页中可以有多个窗口,窗口中可以是不同的缓冲区,也可以是同一个缓冲区。
因此,一个缓冲区既可能出现在多个窗口中,也可能出现在同一个或者不同的标签页下的多个窗口中。
如果你不太习惯标签页这个特性,还是采用缓冲区的管理方式比较好。

新建标签页的命令是 :tabedit 或者 :tabnew,关闭当前标签页使用 :tabclose,关闭所有其他标签页使用 :tabonly
普通模式下,前后切换标签页使用 gtgT 指令。

更多的标签页命令见 tab-page-commands 帮助文档。

窗口分屏

分屏用于在一个界面中同时展现两个文档,对照或比较内容时很常用。
分屏的基础命令 :split filename:vsplit filename 之前已经有提及。其中 v 是垂直(vertical)的缩写。
如果不指定文件名,默认是对照当前文本本身。

两个命令可以分别简写为 :sp:vs,也可以分别使用快捷键实现:
水平分屏:Ctrl-W s 或者 Ctrl-W Ctrl-S
垂直分屏:Ctrl-W v 或者 Ctrl-W Ctrl-V

使用 Ctrl-W q:close 命令退出当前窗口来结束分屏。

折叠

折叠功能(fold)可以将一大块暂时不必关注的文本折叠为一行,从而让你专注于目标文本。
即使你不是程序员,不编写编程代码,也可能需要借助折叠特性更好地阅读、管理大段有结构的文本。

Vim 支持多种折叠方法,但基于语法和表达式等方式的折叠,非程序员一般用不上。
通常可以用上的是根据缩进和标识来折叠的方法,如果涉及文本比对,也可以根据比较结果折叠没有更改的行(fold-diff)。

根据缩进折叠(fold-indent),意思就是折叠级别由这一行缩进的量决定,缩进的层次越多,折叠的级数也就越多。
但缩进折叠对手动排版的要求挺高,如果想更自由的控制折叠,可以使用折叠标识(fold-marker)。

折叠的效果如下,三段文字:

折叠之前

生成三个1级折叠:

折叠之后

折叠标识通常是类似于 {{{1{{{2 这样的文本,{{{ 表示这是折叠标识,数字表示折叠的级数。
折叠标识放在一行中的任意位置都可以,但最好放在行末,或者独占一行,避免影响正文阅读。
如果后面没有出现折叠结束标志 }}},那么这个折叠标志结束位置,就是下一个级别数字小于等于它的折叠开始标志。

例如,第二段改为第2级折叠,加上折叠结束标志:

折叠标志

折叠后,因为有折叠标志,第2级折叠和第1级并列展现。

折叠标志

如果去掉折叠结束标志, Vim 认为1级折叠之后的2级折叠从属于第1级:

折叠标志

因此折叠第1级时,就同时折叠了包含的第2级内容:

折叠标志

展开第1级时,2级折叠可以保留不同的折叠状态:

折叠标志

增加折叠标识后,使用 :set foldmethod=marker 命令切换到根据标识折叠的方式,就可以使用指令折叠和打开文本了。

折叠相关的指令(fold-commands)全部以 z 开头,中文用户记忆为“折”的拼音首字自然最方便相关,你也可以将其看作模仿折叠起来的纸片的形象。

最基础的折叠指令是 za,可以不断切换打开还是关闭光标当前位置的折叠。
在普通模式下,将光标移动到某行上,输入 za 指令,应该能看到折叠的结果,再输入一次 za 就又可以打开。

创建折叠的指令是 zf,它会为选中部分创建带折叠起始和结束标志的注释。
但并不能自动创建折叠级别,所以最好是手工加上级别,或者借助插件完成。

相应的删除折叠命令是 zd,光标所在位置所属的折叠,或者选中部分涵盖的折叠,都会清除掉。

基于折叠还有一些高级功能,例如在折叠间移动,关闭或打开某一级别以上的折叠,针对打开或关闭的折叠执行命令等等。具体可参考 folding 部分的帮助文档。

如果你习惯使用 Markdown 等轻量标记语言,也可以使用诸如 Vim Markdown Folding 这样的插件,根据层级标记自动实现折叠功能。

关键字补全

最简单的补全功能,是基于当前文件中已经输入的词语,对当前字符串进行补全(compl-generic)。
在插入模式下输入 Ctrl-PCtrl-N 会向前或向后搜寻起始字符串匹配的关键字。

例如,之前已经输入过“相呴以湿”、“相濡以沫”,再次输入“相”字时,按下 Ctrl-P 就会出现关键字补全的可选项。
因为按向前搜索的顺序,“相濡以沫”更接近,因此默认选中的是这个词:

关键字自动补全

如果默认选中的结果不正确,再多按几次 Ctrl-P 可以循环选择。

倘若经常使用关键字补全功能,Ctrl-PCtrl-N 快捷键并不方便,可以用 SuperTab、VimCompletesMe 等插件改为按 TabShift-Tab 选择补全选项。

结合 YouCompleteMeNeocomplete 等插件, 以及 LSP(Language Server Protocol)功能,能体验更高级的补全功能和自定义配置,如:模糊匹配、跨文档补全、语法补全、路径补全、触发条件设置、补全关键字来源设置等等。
对非程序员来说,系统自带的补全已经基本够用了。

差异比对

有时候一份文档多处编写,保留了多个版本,如果没有使用专门的版本管理工具,如何比较它们的差异并快速调整呢?
Vim 自带了差异比对的功能,使用 gvim.exe -d file1 file2 / vim.exe -d -g file1 file2 / gvimdiff.exe file1 file2 等多种方式启动 gVim,就进入差异比对模式:

差异比对

小屏幕窗口垂直分隔不方便看,启动时加 -o 参数可以使用水平分隔:

差异比对水平分隔

有差异的部分以不同颜色标记。

如果要比对已经打开的文件,可以使用 :vertical diffsplit 或者 :vertical diffthis 命令,并在分隔窗口中切换不同的文件。其中 vertical 表示垂直分隔窗口。

比对模式下,Vim 默认开启同步滚动(scrollbind),这样在一个窗口中移动光标,另一个窗口中也会同步移动,省去了来回跳转的操作。

使用 [c]c 指令可以向前和向后跳到最近的差异点。

如果确认同步修改有差异的地方,使用 :diffget 命令修改当前文件,使用 :diffput 以当前文件为准修改比对的文件。
要是更改后自动刷新不对劲,用 :diffupdate 强制重新刷新试试。

版本控制

Vim 本身不提供版本控制功能,需要借助 git 等版本控制工具,各种相关的插件可以实现在 Vim 中完成基本的版本控制操作,以及直接查看版本状态。

插件 fugitivevim-gitgutter 专精于 git,vim-signify 则可以配合所有常见的版本控制工具使用。

配置文件详解

之前我们有介绍过 Vim 配置文件的基本用法,为了更加顺手地使用 Vim,还需要更进一步的优化配置文件。
以下配置的条目可以直接复制到 vimrc 文件中保存。

更加个性的配置则可以在网上寻找其他人共享的配置文件、配置项目,也可以参考我的配置文件
切记不要一把全部复制到自己的配置中,一定要先弄明白再取用。

另外,强烈建议入门者不要在配置上花费太多时间,你会发现这是个时间的无底洞,严重影响你的生产力——除非你知道自己在干什么,而且现有的配置实在难用。

使用鼠标

如果一时无法适应纯键盘操作,可以允许所有模式下使用鼠标:

if has('mouse')
  set mouse=a
endif

补全

命令行补全功能挺重要,建议打开:
set wildmenu

编码

处理中文总是不免要和编码问题打交道,以下的配置经过长期验证,另外再加上 fencview 插件,日常使用甚少出现乱码情况(除非使用的中文字体有缺失)。

首先作为活跃在21世纪的文本编辑器,文件编码请尽量默认统一使用 UTF-8:
set encoding=utf-8

读取和展示已有文件时,Vim 会按字符编码列表顺序尝试解码,默认从 UTF-8 编码开始,最后落到 cp936:
set fileencodings=utf-8,chinese,ucs-bom,gb18030,gbk,gb2312,cp936

菜单、弹出信息的语音同步改为中文(菜单配置在修改后加载),否则也可能会有乱码:

set langmenu=zh_CN.UTF-8
source $VIMRUNTIME/delmenu.vim
source $VIMRUNTIME/menu.vim
language messages zh_CN.utf-8

在 encoding 设为某种 Unicode 编码时,Unicode 字符集中某些同时在东西方语言中使用的字符,如省略号、破折号、书名号和全角引号,可以设置为与中文字符宽度一致,即 ASCII 字符的两倍宽度:
set ambiwidth=double

如果转换文件编码遇到问题,请输入 :version 命令,查看当前的 Vim 是否带 +iconv/dyn 特性编译,并寻找、下载 iconv.dll 文件放到 vim.exe 所在的目录。

搜索

判断在 gVim 下自动开启语法高亮和搜索结果高亮:

if &t_Co > 2 || has("gui_running")
   syntax on
   set hlsearch
endif

输入搜索的字符串时,可以逐字即输即查,不用等到全部输入后回车才跳到最近的匹配处:
set incsearch

如果搜索的字符串全部是小写字母,就忽略大小写:

set ignorecase
set smartcase

比如输入 /vim 搜索会匹配到 vim/Vim/VIM 等等,而搜索 Vim 就只会匹配 Vim。

剪贴板

Vim 默认使用内置的剪贴板(寄存器)存放复制粘贴的内容,一开始上手会很不习惯操作系统中复制的内容为什么无法粘贴到编辑器中。
如果要与 Windows 系统共用剪贴板,需要在配置文件中加上以下内容:
set clipboard=unnamed

缓冲区

退出缓冲区时,建议选择隐藏而不是将其从内存中卸载。否则来回编辑多个缓冲区,又不想马上保存,会比较烦人。
而且一定要选择弹出对话框进行提示,避免在没有提示时一不小心执行了影响文件的重要操作。

set hidden
set confirm

其他配置

set nocompatible
不使用兼容模式。兼容模式会启用一些与 Vi 兼容的设置,有的设置项会关闭一些高级特性,所以建议不采用兼容模式。

source $VIMRUNTIME/mswin.vim
behave mswin
加载 mswin.vim 配置,使用更接近 Windows 的操作。
比如默认 Ctrl-A 是全选,Ctrl-V 是粘贴。

if has("autocmd")
autocmd GUIEnter * simalt ~x
endif
打开 Vim 后自动最大化窗口,相当于自动点 Windows 窗口右上角的最大化按钮。

set showcmd
在屏幕最后一行显示一些命令的操作信息。
比如,选择多于一行时,在屏幕最下方显示选择的行数。

set shortmess=aoOtTI
缩写某些提示信息。比如 I 设置项表示启动 Vim 时不给出基本的介绍消息。

set showmatch
插入括号时,短暂地跳转到匹配的对应括号。

set number
在窗口左侧显示行号。

autocmd BufWinEnter * setlocal cursorline
autocmd BufWinLeave * setlocal nocursorline
在当前缓冲区高亮光标所在行,如果窗口不是当前缓冲区,则不会高亮光标所在行。

set backspace=2
设置为2表示退格会删除缩进、换行符和进入插入模式时的起始位置,与通常的习惯保持一致。

autocmd BufReadPost *
     \ if line("'\"") > 0 && line("'\"") <= line("$") |
     \ exe "normal! g`\"" |
     \ endif

打开文件时回到上次光标所在的位置。

if has("autocmd")
  "autocmd bufwritepost .vimrc source $MYVIMRC
  autocmd GUIEnter * simalt ~x
endif

进入 gVim 后自动最大化窗口。

set guioptions=ehrv
去掉 Vim 窗口的菜单栏(m)和工具栏(T),保留标签页(e),限制水平滚动条的大小为光标所在行的长度(h),右边的滚动条总是存在(r),空间足够时,对话框使用垂直的按钮布局(v)。

set scrolloff=3
set sidescrolloff=8
当光标移动到屏幕边缘时,窗口会自动滚动,保证距离屏幕上下边缘有3行文字,距离左右边缘有8列。

set laststatus=2
总是在窗口下方显示状态行,可用于显示各种各样的定制信息。

set wildmenu
打开命令行的补全功能。当你只记得命令的前面部分时,如输入 :set syn 后按 <Tab> 制表符,会提示在 :set synmaxcol:set syntax 之间选择,继续按制表符来回切换。

set hidden
退出时隐藏而不是卸载缓冲区。
也就是说,切换到其他缓冲区时,并不会将当前缓冲区中的内容从内存中移除,而是相当于在后台保留,还可以在缓冲区列表中看到,并且切换过去继续编辑。
但要注意,如果当前缓冲区修改后再隐藏,可能会因此忘记保存。虽然退出 Vim 时会提示保存。

寄存器与宏

Vim 使用寄存器(registers)来保存一些特殊的内容,比如复制、剪切、删除的文本,曾经输入过的命令和查找过的内容,等等。使用 "+寄存器名+指令动作 来操作寄存器。

比如 + 寄存器是与系统剪贴板相通的,"+y"+p 指令就是分别将内容复制到系统剪贴板和粘贴过来。":p 可以粘贴上一次执行的命令,"/p 可以粘贴上一次搜索内容。
0 寄存器保留了最近一次复制的内容,不会被删除的内容覆盖掉。
输入 :registers 命令可以查看各个寄存器中的内容。

a-z 26个寄存器分配给用户自己使用,比如 "ay"ap 就是用寄存器 a 代替了默认的剪贴板寄存器,自然也可以用来记录宏命令。

宏(macro)在文本编辑器中是一连串操作的记录,用于将重复的人工操作变为可以重复执行的自动操作。

使用 q+寄存器名字 指令来开始录制宏,比如 qa 表示接下来的操作指令都会记录到寄存器 a 中。
再按一次 q 来结束录制,真正写入寄存器中。

使用 @+寄存器名字 来执行保存的宏,比如 @a

只要你知道某个操作对应的指令是什么和如何写入指定的寄存器,就能自己编写包含该指令的宏,简单的宏命令非常容易搞定。

比如输入 ggVGd,其指令含义是全选并删除——gg 跳到首行,V 选中整行,G 跳到尾行,d 删除。
选中这些内容后,执行 "ay 指令,表示复制到 a 寄存器中。
再使用 @a 执行 a 寄存器的内容,于是就删除了整个文件的内容。

也可以使用 :let @a=ggVGd 直接写入寄存器 a

宏还有多种高级用法,比如多次执行、对选中的行全部执行等等,在用的到的时候再去查找教程

插件系统

安装插件

尽管 Vim 本身已经非常强大,有的人甚至不装任何插件也能如鱼得水,但有个好插件确实能事半功倍。

手动插件管理 Pathogen

Vim 的插件最开始都是没有管理功能的,下载下来的插件压缩包中,通常会有 plugin、doc、syntax、autoload 等目录,需要用户自己复制到 Vim 安装目录下对应的同名目录中。

这样就存在几个问题:

  1. 多个插件的文件混杂在一起,可能会有冲突和混淆,移除插件时,都不知道哪些文件是属于哪些插件了;
  2. 启用和停止插件非常麻烦;
  3. 升级都要自己动手,帮助文档的安装和更新也全是手动完成。

于是用于管理插件的插件也就应运而生:

Pathogen 插件是 Vim 插件大神 Tim Pope 编写的简单易用的插件管理系统,只实现最基本、最简单的分目录管理插件功能,需要手工下载插件并放在指定的目录,而不考虑自动下载、版本管理、插件清单维护等高级功能,好处是简单、灵活、容易理解。
Pathogen 插件本身(pathogen.vim)放置在 vimfiles\autoload 目录中,然后在配置文件 vimrc 中加上一句:call pathogen#infect(),其他要安装的插件目录则复制到 vimfiles\bundle 目录下,再重启 Vim 就可以了。

如果其他插件自带了帮助文档,则使用 :Helptags 命令可以让 Vim 读取、更新这些帮助文档。

高级插件管理 Vim-plug

Vim-Plug 插件 能够通过修改配置文件来自动下载、安装、更新和移除在 Github 上有仓库的插件(官网的插件在 Github 都有镜像仓库,所以基本不用愁没有仓库来源),适合更懒的用户。
详细用法请阅读插件自己的帮助文档。

类似的插件还有 Vundle、Neo Bundle、Vim Addon Manager、Packer、Lazy(只能用于 Neovim) 等等,用户可以根据使用习惯和插件兼容情况挑选一款最适合自己的。

技巧和常见问题

转换为 HTML

输入 :TOhtml 命令(注意大小写!)可以将当前编辑的纯文本文档转换为 HTML 文档,并尽量保持在 Vim 看到的样式。
也就是说,Vim 中的主题配色、语法高亮、折叠效果等都可以在输出的 HTML 文档中保留下来。
其中保留折叠效果需要在配置文件中加上这么一句:
let g:html_dynamic_folds = 1

重新选择

Vim 有个神奇的功能:重新选择上一次选择的文字。
比如说,选中过一段文字,因为种种原因做了其他非选择类的操作,清除了选择范围,之后如果在普通模式下输入 gv 指令,就会重新选择最后一次选择的文字。

重新选择

文件编码转换

尽管现在许多文档都默认使用 UTF-8 编码,但中文文档仍有许多是 GB2312 的编码,有时候我们也会需要在多种编码(fileencoding)之间转换。
Vim 没有提供现成的编码转换菜单,可以用命令搞定:

转换为 GB2312 编码:
set fileencoding=cp936

转换为 UTF-8 编码:
set fileencoding=utf-8

该命令改变的是文件写入磁盘时的编码。

缩进控制

如果你开启了文件类型判断(filetype),而当前文件类型有自动缩进规则,例如 XML、HTML 等,那么可以用 = 命令叫 Vim 自动应用缩进规则。
手动控制缩进也有快捷方法,在配置文件中写入以下两行内容:

vnoremap < <gv
vnoremap > >gv

常用指令、命令总结

以下是最常用的指令和命令的清单,方便记忆:

命令 助记方法 应用场景模式 含义 操作类型
i insert 普通 在当前字符前进入插入模式 编辑
a append 普通 在当前字符后进入插入模式 编辑
o open new line 普通 在下方插入新行并进入插入模式 编辑
c clear 普通、可视 删除光标移动经过的字符并进入插入模式 编辑
v visual 普通 进入可视模式,选择光标经过的字符 选择
y yank 普通、可视 复制 编辑
p paste/put 普通 粘贴 编辑
q 普通 录制宏 宏命令
d delete 普通、可视 删除、剪切 编辑
x cross out 普通、可视 删除、剪切 编辑
~ 普通、可视 切换当前字符大小写 编辑
w word 普通、可视 跳到下一词词首位置 跳转
e end 普通、可视 跳到下一词词尾位置 跳转
b backwards 普通、可视 跳到上一词词首位置 跳转
hjkl 普通、可视 光标左下上右移动 跳转
^/0 普通、可视 跳到行首 跳转
$ 普通、可视 跳到行尾 跳转
e edit 命令 打开文件 文件
w write 命令 保存文件 文件
s substitute 命令 替换 编辑
q quit 命令 退出 编辑
? 疑问 普通 反向查找 查找
/ 与 ? 共用按键 普通 正向查找 查找
n next 普通 继续向下查找 查找
u undo 普通 撤销 编辑
Ctrl-R redo 普通 重做 编辑

其他技巧

重复上一个命令 .
% 在对应括号跳转
排序和剔重 sort u
整行操作
Ctrl-A / Ctrl-X
对齐 Tabularize
自动缩进和重排版
删除光标前文字 Ctrl-U
大小写切换 ~
前后跳转 Ctrl-I/O
缓冲区切换 Ctrl-^
自定义折叠
模式行 modeline
重新选择上次选择的文本 gv
按下 oO 可以在列块选择的范围四角跳转
Gundo 多分支撤销
拼接两行 J
重复上一行 Ctrl-Y Ctrl-X Ctrl-L
K keyword 查看关键字释义
:![cmd] 直接执行终端命令,选择后执行结果替换选择的部分
普通模式下 q: 查看命令历史清单
如果想要对可视化选中文本执行宏的话,可以执行 :normal @a(或者其他你所定义的宏的名字),这条命令会临时将你切换到普通模式,针对选中的每一行执行宏命令。

Vim 社区和其他资源

Vim 官方网站
Vim Awesome
Telegram 群组
Neovim 官方网站
Vi and Vim Stack Exchange
用户邮件讨论组
VimNeovim 的 Reddit 论坛
Telegram Vim 中文用户群
Vim Tips Wiki
Best of Vim Tips