You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
356 lines
19 KiB
356 lines
19 KiB
2 years ago
|
# 第十章 Vim 插件管理与开发
|
||
|
|
||
|
## 10.1 典型插件的目录规范
|
||
|
|
||
|
学 VimL 脚本的终极目标是写插件按需扩展 vim 的功能。在开始着手写插件之前,有必
|
||
|
要先了解一下典型的、功能较齐全的插件,应该如何组织目录结构,按 vim 的习惯将不
|
||
|
同类别的功能放在相应的子目录下。
|
||
|
|
||
|
### 10.1.1 vim 运行时目录
|
||
|
|
||
|
插件的目录,可参考 vim 本身安装的运行时目录。所谓运行时目录,顾名思义,就是在
|
||
|
vim 运行时如果要加载 `*.vim` 脚本,应该到哪里找文件。
|
||
|
|
||
|
有两个相关的环境变量,可用如下命令查看:
|
||
|
|
||
|
```vim
|
||
|
:echo $VIM
|
||
|
:echo $VIMRUNTIME
|
||
|
```
|
||
|
|
||
|
如果从源码安装 vim ,且自定义安装于家目录的话,它们的值大概如下:
|
||
|
|
||
|
```
|
||
|
$VIM = ~/share/vim
|
||
|
$VIMRUNTIME = ~/share/vim/vim81
|
||
|
```
|
||
|
|
||
|
所以 `$VIM` 指的是 vim 安装目录,而且不同版本的 vim 都将安装在该目录下,
|
||
|
`$VIMRUNTIME` 就是具体当前运行的 vim 版本的安装目录。不过此安装目录不包括 vim
|
||
|
程序本身(那是被安装到 `~/bin` 中的),主要是 vim 运行时所需的大量 `*.vim` 脚
|
||
|
本,相当于“官方插件”。该目录有哪些文件目录,可用如下命令显示:
|
||
|
|
||
|
```vim
|
||
|
:!ls -F $VIMRUNTIME
|
||
|
```
|
||
|
|
||
|
就是 shell 的 `ls` 命令,选项 `-F` 只是在子目录后面添加 `/` ,使得容易区分子目
|
||
|
录与文件。也许直接从 shell 执行 `ls` 是被 alias 定义的别名,自动加上了一些常用
|
||
|
选项,但从 vim 内用 `!` 调用是不读别名的。
|
||
|
|
||
|
`$VIMRUNTIME` 既是官方目录,显然是不建议用户在其内修改或增删的。如果不是自定义
|
||
|
安装在个人家目录,使用系统默认安装的 vim 的话,普通用户也无权修改。
|
||
|
|
||
|
于是 vim 提供了一个选项叫 `&runtimepath` (常简称 `&rtp`),那是类似系统 shell
|
||
|
的环境变量 `$PATH`,就是一组目录,只不过不用冒号分隔,而是用逗号分隔。可用如下
|
||
|
命令查看 `&rtp` :
|
||
|
|
||
|
```vim
|
||
|
:echo &rtp
|
||
|
:echo split(&rtp, ',')
|
||
|
```
|
||
|
|
||
|
通常,`~/.vim/` 目录会在 `&rtp` 列表中,而且往往是第一个。另外,官方目录
|
||
|
`$VIMRUNTIME` 也在 `&rtp` 列表较后一个位置。当 vim 在运行时需要加载脚本时,就
|
||
|
会依次从 `&rtp` 列表中每个目录(及其子目录)中查找,有时查找第一个就会停止。
|
||
|
所以 `$VIMRUNTIME` 目录并不特殊,只是 `&rtp` 中一个优先级并不高的目录。对用户
|
||
|
来说,`~/.vim/` 目录才更特殊些,常被称为 vim 的用户目录。
|
||
|
|
||
|
一般建议用户将个人的 `vimrc` 及其他 vim 脚本放在 `~/.vim/` 目录中。可以用这个
|
||
|
命令:
|
||
|
|
||
|
```vim
|
||
|
:echo $MYVIMRC
|
||
|
```
|
||
|
|
||
|
查看当前你运行的 vim 启动时读取 `vimrc` 。如果显示是 `~/.vimrc` ,则建议将其移
|
||
|
至 `~/.vim/vimrc` 或软链接指向它。vim 会尝试读取 `vimrc` 的几个位置及顺序,也
|
||
|
可用如下命令查看:
|
||
|
|
||
|
```vim
|
||
|
:version
|
||
|
```
|
||
|
|
||
|
然后提一下,如果是 windows 操作系统,没有 `~/.vim/` 目录。但它肯定有 `$VIM` 安
|
||
|
装目录,然后用户目录就是 `$VIM/vimfiles` 。
|
||
|
|
||
|
当了解了用户目录 `~/.vim/` ,就可以参照官方目录 `$VIMRUNTIME` 来组织管理自己的
|
||
|
vim 个性化配置及扩展脚本(插件)。
|
||
|
|
||
|
### 10.1.2 全局插件目录 plugin/
|
||
|
|
||
|
最简单的插件就是将 `*.vim` 脚本存到(某个) `&rtp` 的 `plugin/` 子目录下。当
|
||
|
vim 启动时,就会读取(每个) `&rtp` 的 `plugin/` 子目录下的 `*.vim` 脚本并加载
|
||
|
。因为它们总是被加载,故有时称为全局性插件。
|
||
|
|
||
|
一般 vimer 初学阶段,倾向于完善与丰富自己的配置 `vimrc` 。当 `vimrc` 文件越来
|
||
|
越大感觉不便维护时,可将部分功能拆成独立脚本放在 `plugin/` 目录下,毕竟这个目
|
||
|
录下的脚本也是能初始加载的,与合在 `vimrc` 中没有太大区别。可以想象一下,常规
|
||
|
`vimrc` 配置大约有如下内容:
|
||
|
|
||
|
* 使用 `set` 设置的选项
|
||
|
* 使用 `map` 系统列定义的快捷键
|
||
|
* 使用 `command` 定义的命令
|
||
|
* 自动事件命令组 `augroup`
|
||
|
* 自定义函数
|
||
|
* 为 gVim 定义的菜单
|
||
|
* 其他
|
||
|
|
||
|
如果为以上某部分内容进行了重度自定义,譬如快捷键,对键盘上每个按键都仔细自己
|
||
|
规划了一遍,甚至需要一些简单函数以便支持快捷键功能;那么就可尝试将这部分抽出来
|
||
|
,另存为名如 `~/.vim/plugin/myremap.vim` 的脚本。极端点,可以将 `vimrc` 中每部
|
||
|
分功能都拆出来扔到 `plugin/` 目录。而 `vimrc` 只需留下这两行:
|
||
|
|
||
|
```vim
|
||
|
set nocompatible
|
||
|
filetype plugin indent on
|
||
|
```
|
||
|
|
||
|
这就是网上曾流传的所谓“最简配置”。第一行设置为不兼容 vi 模式,意即开启 vim 的
|
||
|
扩展功能;第二行是打开文件类型检测。另外我还建议在 vimrc 中定义一个环境变量
|
||
|
`$VIMHOME` 保存用户目录:
|
||
|
|
||
|
```vim
|
||
|
let $VIMHOME = $HOME . '/.vim'
|
||
|
if has('win32') || has ('win64')
|
||
|
let $VIMHOME = $VIM . '/vimfiles'
|
||
|
endif
|
||
|
```
|
||
|
|
||
|
这样,在之后的 `vimrc` 或其他脚本的代码中,引用 `$VIMHOME` 就更有通用性,尤其
|
||
|
是在需要手动加载(`:source`)脚本时。
|
||
|
|
||
|
不管是从大 `vimrc` 拆出脚本,还是从头开始写某个功能脚本放在 `plugin/` 目录,都
|
||
|
要注意全局插件的一些特性。
|
||
|
|
||
|
其一是某个 `plugin/` 目录下的所有 `*.vim` 脚本加载顺序不能保证。因此每个脚本要
|
||
|
相应独立完成某个或某类功能,避免引用其他兄弟脚本定义的全局变量。如有这需求,类
|
||
|
似 `$VIMHOME` 环境变量,还是在 `vimrc` 中定义吧,保证最开始被执行到。
|
||
|
|
||
|
其次是 `plugin/` 的所有脚本还包含其子目录,即更深层次下的 `&rtp/plugin/**/*.vim`
|
||
|
脚本也会被自动加载。利用这个特性,可以对该目录进一步组织管理,将相关门类功能
|
||
|
的脚本再放入更恰当的子目录名。但也要避免这个特性滥用,太深层次目录搜索比较耗时
|
||
|
,可能会影响 vim 的启动速度。故一般不建议在 `plugin/` 下再建子目录,最多再建一
|
||
|
层。
|
||
|
|
||
|
如果 `plugin/` 中脚本太多,影响 vim 启动速度,应该将其移出 `plugin/` 目录。可
|
||
|
能的直觉错误是在 `plugin/` 下建个 `backup/` 子目录,把某些不想用但想备用的脚本
|
||
|
扔进去,这不管用,藏不住的。可以把 `*.vim` 脚本后缀改为 `*.vim.bak` ,这就不会
|
||
|
被 vim 启动加载了。更好的建议是建一个与 `plugin/` 平级的 `plugin.bak/` 子目录
|
||
|
,因为文件后缀名对 vim 编辑是重要的。
|
||
|
|
||
|
顺便说一下,在 vim 启动时,也有命令行参数可以指示 vim 在启动时跳过加载
|
||
|
`plugin/` 的脚本。但一般日常使用时不必考虑这种差别。
|
||
|
|
||
|
### 10.1.3 类型插件目录 ftplugin/
|
||
|
|
||
|
与全局插件相对应的,是局部,具体讲,是与某种文件类型相关的插件,只在打开对应类
|
||
|
型的文件时才生效。
|
||
|
|
||
|
文件类型是 vim 的一个概念,每个编辑的文件,都有个独立的选项值 `&filetype` ,这
|
||
|
就是该文件的类型。直观地看,文件名后缀代表着其类型。但本质上这不是同一个概念。
|
||
|
vim 只是主要根据文件名后缀来判断一个文件类型,有时还根据文件的部分内容(如前几
|
||
|
行)来判断文件类型,用户还可以用 `set filetype=` 来手动设置一个类型。一种文件
|
||
|
类型也可以关联好几个后缀名,比如 `cpp`、`hpp` 都是 C++ 文件,文件类型都是 `cpp`,
|
||
|
同样情况还有 `htm` 与 `html` 后缀名的文件,都认为是 `html` 文件类型。
|
||
|
|
||
|
文件类型插件要生效,还得在 `vimrc` 中添加 `filetype plugin on` 这行配置,这一
|
||
|
般也是推荐必须配置。然后在打开文件并成功检测到属于某种文件类型时,vim 就会加载
|
||
|
`&rtp/ftplugin/{&ft}.vim` 脚本。
|
||
|
|
||
|
例如,每当打开 `*.cpp` 或 `*.hpp` 文件时,vim 都认为它属于 `cpp` 文件类型,它
|
||
|
就会加载 `~/.vim/ftplugin/cpp.vim` 脚本,以及其他 `&rtp` 目录下的
|
||
|
`ftplugin/cpp.vim` 。实际上,vim 搜寻文件类型插件脚本时规则很宽松,还会尝试搜
|
||
|
索 `cpp_*.vim` 脚本,甚至子目录 `cpp/*.vim` 下的脚本。这目的是允许在同一个
|
||
|
`ftplugin/` 目录中为一种文件类型提供多个插件脚本,它们都会被加载运行。
|
||
|
|
||
|
相比于 `plugin/` 目录中的插件脚本只会在 vim 启动时执行一次,`ftplugin/` 则可能
|
||
|
在 vim 运行时重复执行多次。每打开相应类型的文件(准确地说是 `&filetype` 选项值
|
||
|
被设置时触发)就会再次搜索并执行所有 `&rtp/ftplugin` 中所有匹配类型的脚本。
|
||
|
|
||
|
因此为了避免无意义重复工作,在文件类型插件脚本中,只推荐写那些确实每个文件(
|
||
|
buffer)都需要独立设置的工作,如:
|
||
|
|
||
|
* `setlocal` 设置局部选项值
|
||
|
* `remap` 系列命令加上 `<buffer>` 参数,只为当前文件定义快捷键
|
||
|
* `command` 自定义命令也加上 `-buffer` 参数
|
||
|
* `let` 命令只修改 `b:` 作用域的变量
|
||
|
|
||
|
此外,还可以在相应的脚本中,通过 VimL 语法来控制脚本的实际执行。比如,参考官方
|
||
|
目录的 `cpp` 类型插件,使用 `:e $VIMRUNTIME/ftplugin/cpp.vim` 打开,内容如:
|
||
|
|
||
|
```vim
|
||
|
" Only do this when not done yet for this buffer
|
||
|
if exists("b:did_ftplugin")
|
||
|
finish
|
||
|
endif
|
||
|
|
||
|
" in c.vim
|
||
|
" let b:did_ftplugin = 1
|
||
|
|
||
|
" Behaves just like C
|
||
|
runtime! ftplugin/c.vim ftplugin/c_*.vim ftplugin/c/*.vim
|
||
|
```
|
||
|
|
||
|
开始几行通过判断 `b:did_ftplugin` 变量的存在性来决定是否继续加载当前这个脚本,
|
||
|
一般在加载当前脚本时会将该值设为 `1` ,这是 vim 官方推荐的文件类型插件的标准头
|
||
|
写法。注意如果每个类型插件都是这样写,那是排他的意义,那就是加载了其中第一个类
|
||
|
型插件的脚本,就不会再加载其他(有这个保护头的)脚本。虽然 vim 的机制会继续搜
|
||
|
索其他匹配的类型插件脚本,但 VimL 语句层面上控制了不会重复加载,而这种控制是用
|
||
|
户可选的方案。
|
||
|
|
||
|
最后一行表示 `cpp` 类型“继承”加载所有 `c` 类型的插件脚本,这是符合 C++ 语言与
|
||
|
C 语言特定业务关系的。这样就可以将 `C/C++` 相关的都只写在 `c.vim` 类型插件中,
|
||
|
避免重复代码。事实上,那个 `b:did_ftplugin` 变量就只在 `c.vim` 中定义,不能在
|
||
|
`cpp.vim` 前面先定义,否则执行到 `c.vim` 是会被跳过。
|
||
|
|
||
|
有时在类型插件脚本中,比如定义局部快捷键时,不可避免要到调用特定函数以便封装具
|
||
|
体实现。这种函数显然也只应该随文件类型插件加载,没用到过该类型就没必要加载,但
|
||
|
是与局部快捷键需要为每个新打开文件定义的情况不同,函数定义最好只定义一次,不必
|
||
|
为每个新文件重复定义。
|
||
|
|
||
|
如果是自己写在 `~/.vim/ftplugin/{&ft}.vim` 中,脚本大致结构可以如下:
|
||
|
|
||
|
```vim
|
||
|
if exists("b:dotvim_ftplugin")
|
||
|
finish
|
||
|
endif
|
||
|
let b:dotvim_ftplugin = 1
|
||
|
|
||
|
" 设置局部选项、快捷键等
|
||
|
|
||
|
if exists("s:dotvim_ftplugin")
|
||
|
finish
|
||
|
endif
|
||
|
let s:dotvim_ftplugin = 1
|
||
|
|
||
|
" 剩余只需加载一次的支持函数、代码
|
||
|
```
|
||
|
|
||
|
注意这里开头使用 `b:dotvim_ftplugin` 变量控制,不同于官方习惯的统一的变量
|
||
|
`b:did_ftplugin`,主要是不想有排他性。也就是说自己只想在 `~/.vim` 用户目录下额
|
||
|
外加些设置,执行完后还想加载官方的(或安装在其他目录的第三方的)同类型插件。
|
||
|
|
||
|
同样地,也可以在用户目录中让一种文件类型继承加载另一种文件类型。但是 `:runtime`
|
||
|
命令太泛了,会搜索所有 `&rtp` 目录。我们自己明确知道另一个目标文件类型是哪个脚
|
||
|
本,就直接用 `:source` 会更有效率,例如在 `~/.vim/ftplugin/cpp.vim` 中:
|
||
|
|
||
|
```vim
|
||
|
source $VIMHOME/ftplugin/c.vim
|
||
|
```
|
||
|
|
||
|
当然了,按个人实际情况,很可能都不会写纯 C 代码,那就直接维护 `cpp.vim` 脚本好
|
||
|
了,不必额外有个 `c.vim` 脚本。另外,也有可能不同的文件类型都有部分共同设置代
|
||
|
码,那也可以提取出来放在独立的 `ftplugin/language.vim` 脚本中,然后在各个具体
|
||
|
的文件类型插件脚本中都调用这个脚本:
|
||
|
|
||
|
```vim
|
||
|
source $VIMHOME/ftplugin/language.vim
|
||
|
```
|
||
|
|
||
|
这里假设没有哪种文件类型名恰好叫 `language` ,不过若防意外,也可以故意取个比较
|
||
|
特殊的名字,如 `ftplugin/_common_.vim` 。
|
||
|
|
||
|
### 10.1.4 文件类型其他相关目录
|
||
|
|
||
|
与文件类型相关的目录,不止 `ftplugin/` 这一个。`ftplugin/` 一般是通用目的的
|
||
|
VimL 代码,还有其他几个目录,是 vim 为了实现其他具体功能时所需读取的脚本,虽然
|
||
|
它们也是 `*.vim` 后缀名的脚本,理论上也可以写任意 VimL 代码,但实践习惯上只为
|
||
|
完成特定功能。
|
||
|
|
||
|
因本书的主旨是讲 VimL 的,所以对这些目录或文件只简单罗列介绍于下:
|
||
|
|
||
|
* `syntax/` 定义文件类型的语法高亮规则,基于正则匹配的;
|
||
|
* `compiler/` 定义相应语言的编译命令及错误格式
|
||
|
* `indent/` 设定缩进规则
|
||
|
* `filetype.vim` 检测文件类型的规则,自动事件 `filetypedetect`
|
||
|
* `indent.vim` 设置自动缩进的事件
|
||
|
* `ftplugin.vim` 文件类型插件加载机制
|
||
|
|
||
|
如果阅读这些官方脚本的源码,就会发现 `ftplugin.vim` 等就是利用自动事件实现的。
|
||
|
显然也可以自己在 `vimrc` 中用 `autocmd` 实现根据文件后缀名加载特定的相关脚本。
|
||
|
但是由于这个需求如此常见,官方已经帮我们做好了,并且支持了大量你见过的与未见过
|
||
|
的编程语言。
|
||
|
|
||
|
另外,类似全局插件功能的,除了 `plugin/` 外,也还有其他几个约定目录。如
|
||
|
`colors/` 就是定义配色主题的。这里就不一一介绍了。
|
||
|
|
||
|
### 10.1.5 自动加载目录 autoload/
|
||
|
|
||
|
`autoload/` 是放自动加载脚本的目录,在第 5.5 节介绍自动加载函数时就已提及。不
|
||
|
过由于它在现代 vim 中非常重要,故这里再单独列出。自动加载机制是顺应 vim 发展而
|
||
|
提出的,也是 VimL 脚本语言的一大进步,因为 `autoload/` 就相当于 perl/python 等
|
||
|
脚本语言存放模块的搜索路径。自动事件(`autocmd`)是 vim 内置机制,用户无法过多
|
||
|
干涉,`autoload/` 自动加载函数是自动事件的一个重要扩充,允许用户在 VimL 语言层
|
||
|
面对函数与脚本的自动加载作灵活的控制。
|
||
|
|
||
|
自动加载函数是名字中含有 `#` 的函数,如 `part1#part2#final()` ,其函数名代表着
|
||
|
(某个 `&rtp` 目录下的) `autoload/` 目录下的相对路径,如
|
||
|
`autoload/part1/part2.vim` 。基于这种对应关系,定义自动加载函数的脚本不必在
|
||
|
vim 启动时事先加载,可以在 vim 运行时直接调用,首次调用时就会从 `&rtp` 中找到
|
||
|
相应的脚本自动加载。当然这是按 `&rtp` 顺序找到的第一个自动加载脚本就采用,所以
|
||
|
`~/.vim/autoload` 往往有最高的优先级。但最好避免这种潜在的命名冲突与隐藏。
|
||
|
|
||
|
关于自动加载函数的用法,请回顾复习第 5.5 节,这里不重复了。不过全局变量名也可
|
||
|
以采用 `#` 的标记,如 `g:part1#part2#varname` ,只在取值时会触发自动加载。
|
||
|
|
||
|
一般在开发较大型插件时,应该将主要实现函数都放在 `autoload/` 目录下,并且建议
|
||
|
将插件名再建一层子目录,这样该插件使用的函数名都有相同的前缀,或可称为命名空间
|
||
|
。而在 `plugin/` 与 `ftplugin/` 目录中只写简单的用户界面如快捷键、命令定义。如
|
||
|
此在一定程度上就相当是 vim 接口与 VimL 实现的分离,有利于大型插件的项目管理。
|
||
|
|
||
|
### 10.1.6 善后目录 after/
|
||
|
|
||
|
`after/` 是个很有趣的目录,每个 `&rtp` 目录下的 `after/` 子目录又是一个 `&rtp`
|
||
|
目录,被自动添加到原来常规的 `&rtp` 列表之末。该 `after/` 目录的结构可以与其父
|
||
|
目录或其他 `&rtp` 目录一样。如果你了解数学上“分形”这个概念,可作此类比理解,就
|
||
|
是“部分与整体拥有相似的结构”。
|
||
|
|
||
|
如果使用 `:echo &rtp` 命令,很可能在回显消息的末尾看到如下两个目录:
|
||
|
|
||
|
```
|
||
|
$VIMRUNTIME/after
|
||
|
$VIMHOME/after
|
||
|
```
|
||
|
|
||
|
因为 `after/` 是自动添加到 `&rtp` 列表末尾,而 vim 在搜索运行时脚本时按顺序搜
|
||
|
索 `&rtp` ,所以 `after/` 目录可以保证尽可能后地被搜索。这机制有什么用途呢?
|
||
|
|
||
|
运行时脚本有两类明显不同的搜索方式。一种是搜索第一个匹配的脚本就停止,如
|
||
|
`autoload/` 目录下的脚本,如此排在 `&rtp` 前列的具体更高的优先级。另一种是始终
|
||
|
搜索所有 `&rtp` 目录,如 `plugin/` 与 `ftplugin/` ,如此排到 `&rtp` 末尾的脚本
|
||
|
具有更高的优先级。
|
||
|
|
||
|
如果用户安装了许多插件,每个插件被安置在独立的 `&rtp` 目录中(详见下一节的插件
|
||
|
管理),那么不同 `&rtp` 目录下的同名脚本,就有可能冲突。因此在本插件目录下另建
|
||
|
`after/plugin/` 或 `after/ftplugin/` 目录可以大概率保证本插件提供的功能不被覆
|
||
|
盖。
|
||
|
|
||
|
但是,一般的插件,除非有特别理由,不建议添加 `after/` 子目录。强行武断地排他,
|
||
|
提升自己的优先级。最好尊重用户的意愿,保留用户目录 `$VIMHOME/after/` 让用户自
|
||
|
己决定如何解决冲突,覆盖其他插件的影响。
|
||
|
|
||
|
同时,也不要故意为难 vim ,在 `after/` 目录下继续递归地建立 `after/` 目录。
|
||
|
|
||
|
### 10.1.7 文档目录 doc/
|
||
|
|
||
|
最后要介绍的文档目录。vim 提供了详尽的在线使用手册,或叫帮助文档。在使用过程中
|
||
|
如有任何疑难杂症,都推荐使用 `:help` 尝试。如果英文水平有限的,可以下载一份中
|
||
|
文翻译文档。但最好还是习惯英文原文文档,毕竟命令与函数名是没办法翻译成中文的,
|
||
|
熟悉 vim 官方文档使用的术语,有助于更好使用 vim 。
|
||
|
|
||
|
官方文档放在 `$VIMRUNTIME/doc` 目录下,就是 `txt` 纯文本文档。不过有特殊的约定
|
||
|
格式,尤其是表示超链接目标与跳转到超链接的表示法,其他语法颜色对于 vim 已是司
|
||
|
空见惯。
|
||
|
|
||
|
用户可以并且建议为自己开发的插件编写文档,放在自己的 `$rtp/doc` 目录下,然后用
|
||
|
`:helptags` 生成索引(需要指定 `doc/` 目录作为参数),以便支持跳转,这样就纳入
|
||
|
了 vim 的帮助文档系统。用不带参数的 `:help` 打开帮助系统首页,在末尾部分有一节
|
||
|
名为 `LOCAL ADDITIONS` 的,就列出了本地帮助文档,也就是除 `$VIMRUNTIME` 以外的
|
||
|
其他 `&rtp` 目录下的 `doc/*.txt` 文档。
|
||
|
|
||
|
最后提一句,善用帮助文档是学习与使用 vim 的不二法门。看过的任何书籍或技术博客
|
||
|
文章,都大概率看过就忘记的,包括你正在看的这一本,它们的价值在于领进门,帮忙建
|
||
|
立个概念,在实际遇到问题时还知道个搜索关键字,或者是 `:help` 的主题参数。至于
|
||
|
详细使用细节,都以 vim 帮助文档为准。
|