《Practical Vim》(《Vim实用技巧》) 是关于Vim技巧最好的教程,豆瓣评分9.1。之前断断续续地看过,不过没整理笔记。这书得经常翻看并实践,以后把看书和Vim练习的笔记记录整理在此,便于反复复习和练习使用。

ed 为 ex 之父,ex 为 vi 之父,而 vi 为 Vim 之父。

Vim折叠
https://www.cnblogs.com/welkinwalker/archive/2011/05/30/2063587.html

zR 展开当前文件所有的折叠
zM 折叠当前文件所有可以折叠的

zc 折叠当前行
zo 打开当前折叠

zO 对所在范围内所有嵌套的折叠点展开
zC 对所在范围内所有嵌套的折叠点进行折叠

za 打开/关闭当前折叠 zc/zo

以下是《Vim使用技巧》笔记和摘录。

####################################### 第一部分 模式 #######################################

. 重复上次操作
* 查找光标所在的单词 按n查找下一个 N回到上个
/string 查找字符串string 按n查找下一个 N回到上个
:%s/content/copy/g 全文档替换

<C-g>  查看文件状态

f{ch}  查找字符
F{char}  反向移动到上一个 {char} 所在之处
t{char}  正向移动到下一个 {char} 所在之处的前一个字符上
T{char}  反向移动到上一个 {char} 所在之处的后一个字符上
; 重复f{ch}
, 回到上次的f{ch}

s 删除光标所在字符,进入插入模式
cw 删除从光标开始到单词结束的所有字符,进入插入模式
db 删除从光标起始位置到单词开头的内容,但会原封未动地留下最初光标所在字符
b 回到单词首个字符
e 定位到单词最后一个字符
dw 删除光标所在字符到单词结尾部分
aw 文本对象(text object)
daw 删除了该单词,它还会删除一个空格 命令解读为“delete a word”,这样比较容易记忆
dap 删除一段
dl == x 删除一个字符
~  切换大小写字符
g~  大小写切换 gu小写  gU大写 gUaw将当前单词变成大写 gUap整段变成大写
貌似~ vu vU 比g~ gu gU快..
= 自动缩进 gg=G 自动缩进这个文档

Vim 的语法只有一条额外规则,即当一个操作符命令被连续调用两次时,它会作用于当前行。
所以 dd 删除当前行,而 >> 缩进当前行。gU 命令是一种特殊情况,我们既可以用 gUgU ,
也可以用简化版的 gUU 来使它作用于当前行。

VG 行可视 从当前行到文档结尾
V10j 行可视 从当前行下面再选中10行

行可视后 :'<,'>normal .  针对行可视块 执行命令 .

I 不管光标在哪里 在行首插入
A 不管光标在哪里 在行尾插入

<C-a> <C-x>查找行内数字进行加减 前缀数字可以定义加减多少
<C-[> == Esc键
<C-o> 切换到插入-普通模式
插入-普通模式是普通模式的一个特例,它能让我们执行一次普遍模式命令。在此
模式中,我们可以执行一个普通模式命令,执行完后,马上就又返回到插入模式。

在当前行正好处于窗口顶部或底部时,有时我会滚动一下屏幕,以便看到更多的上下文。
用 zz 命令可以重绘屏幕,并把当前行显示在窗口正中,这样就能够阅读当前行之上及之下的半屏内容。
常常会键入 <C-o>zz,在插入-普通模式中触发这条命令。此操作完成后就会直接回到插入模式,
因此我可以不受中断地继续打字。

「.范式」 用一次按键移动,另一次按键执行,最理想的模式
口诀::执行、重复、回退。

插入模式下的命令:
<C-h> 删除一个字符 跟delete键一样
<C-w> 删除一个单词
<C-u> 删除至行首

这些命令不是插入模式所独有的,甚至也不是 Vim 所独有的,在 Vim 的命令行模式中,
以及在 bash shell 中,也可以使用它们。

不离开插入模式,粘贴寄存器中的文本:
yt,  从光标复制到, 默认复制到寄存器0
<C-r>0 粘贴寄存器0的内容

如果寄存器中包含了大量的文本,你也许会发现屏幕的更新有些轻微的延时。
这是因为 Vim 在插入寄存器内的文本时,其插入方式就如同这些文本是由键盘上一个个输进来的。
因此,如果 ‘textwidth’ 或者‘autoindent’ 选项被激活了的话,那么最终就可能会出现不必要的
换行或额外的缩进。
<C-r><C-p>命令则会更智能一些,它会按原义插入寄存器内的文本,并修正任何不必要的缩进
不过这个命令有点不太好 输入!因此,如果我想从一个寄存器里粘贴很多行文本的话,
我更喜欢切换到普通模式,然后使用某个粘贴命令

表达式寄存器<C-r>= 后面接运算表达式,回车后即可得到结果,方便一些简单的计算。

用字符编码插入非常用字符:
ga 显示光标所在字符的字符编码
<C-v>065 插入字母A 十进制0开头
<C-v>u00bf 十六进制 u开头
<C-v>{nondigit} 按原义插入非数字字符

用二合字母插入非常用字符:
<C-k>12 插入½
<C-k>?I 插入¿

用替换模式替换已有文本:
R 由普通模式进入替换模式,替换完一个光标会自动往右移,逐个替换
r 直接在普通模式替换单个字符
Vim 还有另外一种替换模式,称为虚拟替换模式(Virtual Replace mode)。
该模式可由 gR 命令触发,它会把制表符当成一组空格进行处理。假设我们把光标移到一个占屏幕 8 列宽
制表符上,然后切换到虚拟替换模式,在输入前 7 个字符时,每个字符都会被插入到制表符之前;
最后,当输入了第 8 个字符时,该字符将会替换制表符。
在虚拟替换模式中,我们是按屏幕上实际显示的宽度来替换字符的,而不是按文件中所保存的字符进行替换。
这会减少意外情况的发生,因此我建议在可能的情况下尽量使用虚拟替换模式。

可视模式:
Vim 具有 3 种不同的可视模式,分别用于操作字符文本、行文本或块文本。
v 字符文本
V 行文本
<C-v> 块文本
gv 重选上次的高亮选区  不过如果上次的选区被删除了,它也许会工作得不太正常。

viw 高亮选择光标所在单词 按c删除后进入插入模式

如果当前处于面向字符的可视模式,我们可以按 V 来切换到面向行的可视模式,
或是用 <C-v> 来切换到面向列块的可视模式。然而,如果在面向字符的可视模式
中再次按 v,就会回到普通模式。所以,你可以把 v 键当成在普通模式及面向字符的
可视模式间转换的开关,V 及 <C-v> 键也一样可以在普通模式及其对应的可视模式间切换。
当然了,你总是可以按 <Esc> 或 <C-[>回到普通模式(就像退出插入模式那样)。

可视模式下o键可以切换活动的首尾两端,然后重新调整选区的边界即可
重复执行面向行的可视命令示例:
Vj选中两行 > . 缩进两次 也可以2> 不过推荐使用. 可以有视觉反馈,也方便撤回

可视模式可能比 Vim 的普通模式操作起来更自然一些,但是它有一个缺点:在这 个模式下 . 命令
有时会有一些异常的表现。我们可以用普通模式下的操作符命令来规避此缺点。
只要可能,最好用操作符命令,而不是可视命令

vit 选择标签里的内容。vit 可被解读为高亮选中标签内部的内容
(visually select inside the tag),其中,it 命令是一种被称为文本对象(text object)
的特殊动作命令
选中后U将选中变为大写,.重复操作,只能影响相同的选中长度

vit U 的效果用普通模式下实现就不会出现影响长度不同的问题:

gUit j. j. 更佳!

这两种方式都只需要 4 次按键操作:vitU 及 gUit,但其背后的含义却大相径庭。
在可视模式所采用的方式里,这 4 次按键可以被当做两个独立的命令。
vit 用来选中选区,而 U 用来对选区进行转换。与之相反的是,gUit 命令可以被当成一个单独的
命令,它由一个操作符(gU)和一个动作命令(it)组成。

如果我们想使点命令能够重复某些有用的工作,那么最好要远离可视模式。作为 一般的原则,
在做一系列可重复的修改时,最好首选操作符命令,而不是其对应的可视模式命令。

这并不是说可视模式出局了,它仍然占有一席之地。因为并非每个编辑任务都需 要重复执行,
对一次性的修改任务来说,可视模式完全够用。并且,尽管 Vim 的动作命令允许我们进行精确的移动,
不过有时要修改的文本范围的结构很难用动作命令表达出来,而处理这种情形却恰恰是可视模式所擅长的。
分使用场景进行选择。

用面向列块的可视模式编辑表格数据:
<C-v>3j x.. gv r| 列块4行减小缩进 重新选中添加分隔符|
yyp Vr- 添加横线-
<C-v>jje c xxx <Esc> 列块选中同一个单词替换
在 Vim 列块可视模式中,修改命令的表现或许有点怪,它看上去有点不一致。
删除操作会同时影响所有被选中的行,但插入操作只影响顶行(至少在处于插入模 式的期间)。
不过在实践中,最终的结果没什么区别。因为你处于插入模式的时间很短,所以没必要太过惊讶。

<C-v>jj$ A; xxx <Esc> 列块模式行后添加相同的内容

命令行模式:
出于历史原因,在命令行模式中执行的命令又被称做 Ex 命令。
我们可以用 Ex 命令读写文件(:edit 和 :write),创建新标签页(:tabnew)及 分割窗口(:split),
或是操作参数列表(:prev/:next)及缓冲区列表(:bprev/:bnext)。
事实上,Vim 为几乎所有功能都提供了相应的 Ex 命令(参见:h ex-cmd-index获得完整列表)。

普通模式命令一般操作当前字符或当前行,而 Ex 命令却可以在任意位置执行
使 Ex 命令脱颖而出的最让人赞叹的功能,是它们拥有能够在多行上同时执行的能力。

Ex命令有:print(:p) :delete(:d) :join :substitute :normal等
在一行或多个连续行上执行命令,指定行范围:
:10 将光标定位到第10行  相当于普通模式下10G
:10p 打印第10行 :1,9p 打印第1到9行  p换成d即为删除
操作前会先移动光标
:{start},{end} 这种模式{start} 和 {end} 都是地址。到目前为止,我们已经看到过用行号作为地址,
然而很快就会看到也能用查找模式或是位置标记作为地址。
:.,$p 打印当前行到最后一行
符号 % 也有特殊含义,它代表当前文件中的所有行: :%p 打印所有行
这和运行 :1, $p 是等效的。这种简写形式在和 :substitute 命令一起使用时非常普遍:
:%s/Practical/Pragmatic/ 把每行内的第一个“Practical”替换为“Pragmatic” 加g则是所有都替换 
i表示大小写不敏感

我们也可以用高亮选区选定一个范围,而不是用数字指定。VG :'<,'>p
Vim 也接受以模式作为一条 Ex 命令的地址, 如 :/<html>/,/<\/html>/p  打印html标签和标签之间的内容
用偏移对地址进行修正:
:2 :.,.+3p 打印2-5行
0 虚拟行,位于文件第一行上方
第 0 行在文件中并不真实存在,但它作为一个地址,在某些特定场景下会很有用处。 特别是,
在把指定范围内的行复制或移动到文件开头时,可以用它做 :copy {address} 及 :move {address} 
命令的最后一个参数。

:copy 命令(及其简写形式 :t  :co)让我们可以把一行或多行从文档的一部分复制到另一部分, 
而 :move(:m)命令则可以让我们把一行或多行移到文档的其他地方。
:[range]t {address}  
:6t. 复制第6行内容放到当前行下面
:t6 复制当前行到第6行下面
:t$ 复制当前行到文本结尾
:t. == yyp
:'<,'>t0 把高亮选中的行复制到文件开头

以上的t换成m就是移动了。
重复上次的 Ex 命令非常简单,只需普通模式下按@:即可
普通模式命令适合在光标附近进行操作,而 Ex 命令则可以远距离操作。

在指定范围上执行普通模式命令:
如果想在一系列连续行上执行一条普通模式命令,我们可以用 :normal 命令。此命令在与 . 命令或宏结合使用时,
我们只需花费很少的努力就能完成大量重复性任务。
A;<Esc> 每行尾添加分好 jVG :'<,'>normal . 选中下面所有行 全部执行 . 命令 
以上例子等价于 :%normal A;
符号 % 代表整个文件范围,因此 :%normal A; 告诉 Vim 在文件每行的结尾都
添加一个分号。在做此修改时会切换到插入模式,但是在修改完后 Vim 会自动返回到普通模式。
在执行指定的普通模式命令之前,Vim 会先把光标移到该行的起始处。因此在执行时,用不着担心光标的位置。
例如,下面这条命令可以把整个 JavaScript 文件注释掉::%normal i//
虽然用 :normal 命令可以执行任意的普通模式命令, 但是我发现当它和 Vim的重复命令结合在一起时,最为强大,
既可以用 :normal . 应对简单的重复性工作, 也可以用 :normal @q 应对较复杂的任务。

自动补全 Ex 命令:
<C-d> 显示可用的补全列表
Tab 自动补全 按多次会循环遍历可选

在多个补全项间选择:
习惯用 bash shell 的方式工作,那么下面的设置会满足你的需要:
set wildmode=longest,list
习惯于 zsh 提供的自动补全菜单,或许会想试试这个:
set wildmenu 
set wildmode=full
当 ‘wildmenu’ 选项被启用时, Vim 会提供一个补全导航列表。 我们可以按 <Tab> 、<C-n> 或 <Right> 
正向遍历其列表项,也可以用 <S-Tab>、<C-p> 或 <Left> 对其进行反向遍历。

把当前单词插入到命令行:
* 查找光标当前单词 cw修改
批量修改使用:s 
:%s//bar/g  表示把最近的搜索结果都替换成bar  比如之前用*查找了foo 就会把所有的foo都替换成bar
等价于 :%s/foo/bar/g 参考:http://vim.wikia.com/wiki/Search_and_replace
Ex命令模式下按 <C-r><C-w>插入光标所在的单词,按<C-r><C-a>输入光标所在的字符串
打开你的 vimrc 文件,把光标移到其中的一项设置上,然后输入 :help <C-r><C-w> 就可以查阅该设置的文档了。

命令行窗口:
普通模式下,输入 q:,打开命令行窗口
可以用 k 及 j 键在历史中向前或向后移动,也可以用 Vim 的查找功能查找某一行。在按下 <CR> 键时,
将会把当前行的内容当成 Ex 命令加以执行。命令行窗口的好处在于它允许我们使用 Vim 完整的、区分模式的编辑
能力来修改历史命令。
当命令行窗口处于打开状态时,它会始终拥有焦点。这意味着,除非关闭命令行窗口,否则我们无法切换到其他窗口。 
要想关闭命令行窗口,我们可以执行 :q 命令 (就像关闭普通 Vim 窗口那样),或是按 <CR> 。
我们正在命令行上构建一条 Ex 命令,做到一半时,才意识到需要更强大的编辑能力,
按<Ctrl-f>从命令行模式切换到命令行窗口。

运行 Shell 命令:
在 Vim 的命令行模式中,给命令加一个叹号前缀就可以调用外部程序。
注意区分 :!ls 和 :ls 的不同之处。前者调用的是 shell 中的 ls 命令,而 :ls 调用的是 Vim 的内置命令,
用来显示缓冲区列表的内容。
在 Vim 的命令行中,符号 % 代表当前文件名。例如,如果我们正在编辑 某个 Ruby 文件,
那么可以用下面的方式执行此文件:
:!ruby %

:!{cmd} 这种语法适用于执行一次性命令,但是如果想在 shell 中执行几条命令要怎么做?
可以执行 Vim 的 :shell 命令来启动一个交互的 shell 会话, exit 命令可以退出此 shell 并返回 Vim。

假设我们正在 bash shell 中运行 Vim,然后需要执行一些 shell 命令。我们可以先按Ctrl-z 挂起 Vim 所属
的进程,并把控制权交还给 bash。此时 Vim 进程在后台处于挂起状态,让我们可以像往常一样与 bash 会话进行交互。
运行jobs命令以查看当前的作业列表。在 bash 中,我们可以用fg命令唤醒一个被挂起的作业,把它移到前台。
这会让 Vim恢复成挂起前的状态。Ctrl-z和fg命令比 Vim 所提供的:shell和exit命令更加方便快捷。

把缓冲区内容作为标准输入或输出:
:read !{cmd} 命令让我们把命令的标准输出重定向到缓冲区。正如你所期望的 一样,:write !{cmd} 做相反的事。
它把缓冲区内容作为指定 {cmd} 的标准输入。
:read !ls 把ls命令执行的结果插入到当前光标的下方
:write !sh 在 shell 中执行当前缓冲区中的每行内容 注意 :write! sh是不一样的,表示强制覆盖文件sh

使用外部命令过滤缓冲区内容:
:[range]!{filter}  使用外部程序 {filter} 过滤指定的 [range]

first name,last name,email 
john,smith,john@example.com 
drew,neil,drew@vimcasts.org 
jane,doe,jane@example.com

我们想基于第二个字段“姓氏”来重排这些记录。我们可以用 -t’,’ 参数告诉 sort 命令,这些记录以逗号分隔,
然后再用 -k2 参数指定按第二个字段进行排序。因为文件的第一行是标题信息, 我们想把它们保留在文件顶部, 
因此需要用范围 :2,$ 把它排除在排序范围之外。下列命令将完成我们想要的功能:
:2,$!sort -t',' -k2
Vim 对某些外部命令会另眼相待。例如,make 及 grep 在 Vim 中都有包装命令, 这些命令不仅执行起来更方便,
而且 Vim 还会将它们的输出解析、导入到 quickfix 列 表中。


####################################### 第二部分 文件 #######################################
用缓冲区列表管理打开的文件:
文件是存储在磁盘上的,而缓冲区则存在于内存中。
绝大多数 Vim 命令都用来操作缓冲区,不过也有一些命令针对文件进行操作,
这当中包括 :write、:update 及 :saveas 命令。
:ls 命令会列出所有被载入到内存中的缓冲区的列表
:bnext 命令可以切换到列表中的下一个缓冲区
% 符号指明哪个缓冲区在当前窗口中可见,而 # 符号则代表轮换文件。按<C-^>可以在当前文件和轮换文件间快速切换
轮换文件意思应该是被编辑过的文件(在vim中打开过的文件)
我们可以用 4 条命令来遍历缓冲区列表。 
:bprev 和 :bnext 在列表中反向或正向移动,每次移动一项;
:bfirst 和 :blast 则分别跳到列表的开头和结尾。
:ls 列表的开头有一个数字,它是在缓冲区创建时由 Vim 自动分配的编号。
我们可以用 :buffer N 命令直接凭编号跳转到一个缓冲区
或是用更直观的 :buffer {bufname} 格式实现同样的功能
:bufdo 命令允许我们在 :ls 列出的所有缓冲区上执行 Ex 命令,不过在实际应用中,我发现 :argdo 更加实用
删除缓冲区:
:bdelete N1 N2 N3 
:N,M bdelete

用参数列表将缓冲区分组:
参数列表易于管理,适用于对一批文件进行分组,使其更容易访问。
用 :argdo 命令可以在参数列表中的每个文件上执行一条 Ex 命令。
参数列表是 vi 的一个功能,而缓冲区列表是 Vim 引入的增强功能
参数列表是缓冲区列表的一个强力补充

填充参数列表:
cd mvc (mvc是一个目录)
vim
打开后直接命令行模式 :args app.js index.html 则会把app.js和index.html载入缓冲区
如果只是想在列表里增加几个文件,用这种方式就行了。它的好处是可以指定文件的次序,但它也有一个缺点,
那就是手动增加文件的工作量比较大。如果想往参数列表中加入大量文件,那么使用通配符会快得多。

用 Glob 模式指定文件:
通配符是一个占位标记,它代表了可用于文件或目录名称的字符。* 符号用于匹 配 0 个或多个字符,
但它的范围仅局限于指定的目录,而不会递归其子目录;;** 通配符也匹配 0 个或多个字符,但它可以递归进入
指定目录的子目录:
:args *.*   :args **/*.js   :args **/*.*
也可以指定多种后缀::args **/*.js **/*.css

用反引号结构指定文件:
:args `cat .chapters`
Vim 会在 shell 中执行反撇号(`)括起来的命令,然后再把 cat 命令的输出作 为 :args 命令的参数。
虽然本例是用 cat 命令获取 .chapters 文件的内容,但实际上我们可以用这种方式执行任意可用的 shell 命令。
然而,此功能并不是所有系统都可用。

参数列表比缓冲区列表更容易管理,这使其成为对缓冲区进行分组的理想方式。 
通过使用 :args {arglist} 命令,一下就可清空并重新设置参数列表,
接着就可以 用 :next 及 :prev 命令遍历参数列表中的文件,或是用 :argdo 命令在列表中的每个缓冲区
上执行同一条命令。:缓冲区列表就像是我的计算机桌面(desktop),它永远是乱七八糟的;
而参数列表则像一个整洁的独立工作区(workspace),只有在需要扩展空间时才会用到它。

管理隐藏缓冲区:
Vim 对被修改过的缓冲区会给予特殊对待,以防未加保存就意外退出。
No write since last change (add ! to override)
ls 缓冲区前有一个 + 号,表示这个缓冲区被修改过了。如果现在保存文件的话,缓冲区的内容就会被写入磁盘里,
而 + 号也会消失了。缓冲区被标记为 h,表示它是一个隐藏缓冲区(hidden)。
:q Vim 会把第一个有改动的隐藏缓冲区载入当前窗口,这样我们就可以决定如何处理它。
如果要保留修改,可以执行 :write 命令把缓冲区保存到文件;
如果想摒弃此修改,可以执行 :edit!,重新从磁盘读取此文件,这会用文件的内容覆盖缓冲区中的内容。
当缓冲区内容与磁盘文件一致后,我们就可以再次尝试执行 :q 命令了。
如果会话里有不止一个被修改过的隐藏缓冲区,那么每次执行 :quit 命令时, Vim 都会激活下一个未保存
的缓冲区。同样的,我们可以用 :write 及 :edit! 来保存或摒弃此修改。
当没有其他窗口和隐藏缓冲区时,:q 命令就会关闭 Vim。
如果想退出 Vim 而不想对未保存的修改进行检查,可以执行 :qall! 命令;
如果想保存所有有改动的缓冲区而无需逐个检查,可以用 :wall 命令。

将工作区切分成窗口:
<C-w> s 水平分  == :sp {file}
<C-w> v 垂直分  == :vsp {file}
<C-w> hjkl 在窗口之间移动
<C-w>w 切换活动窗口 循环
关闭窗口
:close 关闭活动窗口 
:only 关闭除活动窗口外的所有其他窗口

改变窗口大小及重新排列窗口:
<C-w>= 使所有窗口等宽、等高
<C-w>_ 最大化活动窗口的高度
<C-w>| 最大化活动窗口的宽度
[N]<C-w>_ 把活动窗口的高度设为[N]行
[N]<C-w>| 把活动窗口的宽度设为[N]列

用标签页将窗口分组:
用 Vim 的标签页可以把工作分隔到不同的工作区。 Vim 中的标签页更像是 Linux 中的虚拟桌面,
而不是像其他文本编辑器中的标签页。
:lcd {path} 命令让我们可以设置当前窗口的本地工作目录。如果我们创建了一个新标签页,
并用 :lcd 命令切换到另一个目录,那么就可以把每个标签页限制在不同的工程范围内。
注意::lcd 只影响当前窗口,而非当前标签页。如果一个标签页包含了两个或更多的窗口,
我们可以用 :windo lcd {path} 命令为所有这些窗口设置本地工作目录。

:tabedit {filename} 命令可以打开一个新的标签页, 如果省略了{filename} 
参数的话,那么 Vim 会创建一个新标签页,里面包含一个空缓冲区。
如果活动标签页中只包含一个窗口,那么 :close 命令将关闭此窗口以及包含此窗口的标签页。
我们也可以用 :tabclose 命令来关闭当前标签页,无论其中有多少个窗口。 
最后,如果想关闭除当前标签页外的所有其他标签页,可以用 :tabonly 命令。

标签页的编号从 1 开始, 我们可以用 {N}gt 命令在标签页间切换,可以把此命 令记成“跳到标签页{N}”。
当此命令带一个数字前缀时,Vim 会跳到指定编号的标签 页;如果省略了数字前缀,则会跳到下一个标签页。
gT 命令的功能与此相同,只是跳转方向相反。

使用:find 打开文件:
先配置path:
:set path+=app/**
** 通配符会匹配 app/ 目录下的所有子目录。
配置了path之后就可以使用:find来查找文件了,有些插件已经配置了自动添加path的配置

除了查看和编辑文件内容以外, Vim 还允许查看目录的内容。 Vim 发行版中自带的 netrw 插件
允许我们对文件系统进行管理。
要想返回上级目录,可以使用 - 键, 或是把光标移到 .. 条目上再按 <CR>。
:e.  打开文件管理器,并显示当前工作目录
:E  打开文件管理器,并显示活动缓冲区所在的目录

把文件保存到不存在的目录中:
:edit {file} 命令一般用于打开一个已存在的文件。然而,如果我们指定了一个不存在的文件路径, 
那么 Vim 就会创建一个新的空白缓冲区。
调用外部的 mkdir 程序 对此做出补救:
:!mkdir -p %:h   % 符号代表活动缓冲区的完整文件路径  它会展开成当前文件的完整路径
:w

以超级用户权限保存文件:
以超级用户运行 Vim 的情况并不常见, 然而有时我们不得不把修改保存到一 个需要 sudo 权限的文件中。 
无需重启 Vim 就能实现这一功能, 我们可以把这个任务委派给一个以 sudo 运行的 shell 进程来完成。
:w !sudo tee % > /dev/null
此时,Vim 需要与我们进行两次交互。首先要输入用户 drew 的密码,
然后 Vim 会警告我们该文件已被修改了,并显示出一个选项菜单。 
在这里,我建议按 l 键重新将该文件载入缓冲区。
:write !{cmd} 命令会把缓冲区的内容作为标准输入 传给指定的{cmd},{cmd} 可以是任何外部程序
该命令的后半部分可以展开为 下面的命令:tee /etc/hosts > /dev/null。
这条命令会把缓冲区的内容当作标准输入,并用它来覆盖 /etc/hosts 文件的内容。
之后,Vim 会检测到该文件已经被一个外部程序修改。一般情况下这意味着缓冲区中的内容和文件不同步了,
这就是为什么 Vim 会提示我们做出选择,是要保留缓 冲区中的版本,还是载入磁盘上的版本?
然而在本例中,文件与缓冲区的内容刚好是 完全一致的。


################################# 第三部分 更快地移动及跳转 ###############################

区分实际行与屏幕行:
理解实际行与屏幕行间的差别很重要,因为 Vim 提供了不同的动作命令来操作这两者。j 和 k 命令会根据实际行
向下及向上移动,而 gj 和 gk 则是按屏幕行向下及向上移动。

基于单词移动:
w 正向移动到下一单词的开头
b 反向移动到当前单词/上一单词的开头
e 正向移动到当前单词/下一单词的结尾
ge 反向移动到上一单词的结尾

每个面向单词的动作命令,都有一个面向字串的命令与其对 应,这当中包括 W、B、E 和 gE。
一个单词由字母、数字、下划线,或其他非空白字符的序列组成,单词间以空白字符分隔
而字串的定义则更简单,它由非空白字符序列组成,字串间以空白字符分隔
如果你想更快地移动的话,可以用面向字串的动作命令;而如果你想以更细的粒 度移动的话,
则可以用面向单词的动作命令。


用精确的文本对象选择选区:
文本对象允许我们操作括号、被引用的文本、XML 标签以及其他文本中的常见结构。
Vim 的文本对象由两个字符组成,第一个字符永远是 i 或是 a。我们一般说, 以 i 开头的文本对象会选择分隔符内部的
文本,而以 a 开头的文本对象则会选择包 括分隔符在内的整个文本。 为了便于记忆, 可以把 i 想成“inside”,
而把 a 想成 “around” 或“all”。
it和at表示标签和标签内容
i( 和 i) 等同,a[ 和 a] 也相同

Vim 的文本对象分为两类:一类是操作分隔符的文本对象,如i)、i"和it; 一类用于操作文本块,如单词、句子和段落。
我把第一类标注为“分隔符文本对象”,因为它们以配对的符号作为开始和结束。
单词、句子以及段落则以文本结构的范围进行界定,因此我把这一类称为“范围文本对象”。
iw 当前单词
aw 当前单词及一个空格
iW 当前字串
aW 当前字串及一个空格
is 当前句子
as 当前句子及一个空格
ip 当前段落
ap 当前段落及一个空行

一般来说,d{motion} 命令和 aw、as 和 ap 配合起来使用比较好,而c{motion}命令和 iw 及类似的文本对象
一起用效果会更好。(空格的问题 删除与修改)

设置位置标记,以便快速跳回:
mm 和 `m 命令是一对便于使用的命令,它们分别设置位置标记 m,以及跳转到该标记。
Vim 会自动帮我们设置一些位置标记,这些标记用起来非常方便。
`` 当前文件中上次跳转动作之前的位置
`. 上次修改的地方
`^ 上次插入的地方
`[ 上次修改或复制的起始位置
`] 上次修改或复制的结束位置
`< 上次高亮选区的起始位置
`> 上次高亮选区的结束位置

在匹配括号间跳转:
命令允许我们在一组开、闭括号间跳转。它可作用于 ()、{}以及[]
修改{}示例,要先执行一次 % 命令,在执行%命令时,Vim 会自动为发生跳转的地方设置一个位置标记,
而后我们就可以按``跳回那里。

在配对的关键字间跳转:
Vim 在发布时带了一个名为 matchit 的插件,它增强了 % 命令的功能。激活此插件后,% 命令
就可以在配对的关键字间跳转。
虽然 matchit 随 Vim 一起发布,但它缺省并未使能。下面的 vimrc 将使 Vim 在启动时自动加载
matchit 插件:
set nocompatible 
filetype plugin on 
runtime macros/matchit.vim
此插件提供的增强功能非常有用,因此我建议你激活该插件
我最喜欢的一个插件是 Tim Pope 写的 surround.vim
用它可以很容易地给选中的文本加分隔符。
 
遍历跳转列表:
:jumps
Vim 会记录跳转前后的位置,并提供了一些命令让我们能够沿原路返回。
动作命令在一个文件内移动,而跳转则可以在文件间移动。
<C-o> 命令像后退按钮一样,而与之互补的 <C-i> 命令则像是前进按钮。
这两条命令允许我们对 Vim 的跳转列表进行遍历。
任何改变当前窗口中活动文件的命令,都可以被称为跳转命令。
Vim 会把执行跳转命令之前和之后的光标位置,记录到跳转列表中。
:edit 命令打开了一个新文件
就可以用 <C-o> 和 <C-i> 命令在这个新文件以及原本的文件之间来回跳转。
 
gf  跳转到光标下的文件名
<C-]>  跳转到光标下关键字的定义之处
 
遍历改变列表:
:changes
用g; g, 命令反向或正向遍历改变列表。你可以拿 ; 和 , 命令当参考,来帮你记忆
要想跳到上次文档中被更改过的地方,我们可以按 g;。它会跳到上次完成编辑时光标所在的行及列上。
其结果与按 u<C-r> 类似,只是它不会对文档造成暂态的改变。
 
u 撤销更改  <C-r> 重做最新的更改
 
gi  快速回到退出的地方继续编辑。此命令会用 `^ 标记恢复光标位置,并切换到插入模式,这真是省时省力的好办法!

跳转到光标下的文件:
Vim 会把文档中的文件名当成一个超链接。在进行了正确的配置后,我们就可以 gf 命令跳转到光标下的文件了。
指定文件的扩展名:
‘suffixesadd’ 选项允许我们指定一个或多个文件扩展名(要先设置path),当 Vim 用 gf 命令搜寻文件名时,
会尝试使用这些扩展名
:set path+=app/**
:set suffixesadd+=.rb
每次用 gf 命令时,Vim 都会在跳转列表中增添一条记录,因此我们总是可以用 <C-o> 命令返回原处。
suffixesadd和path选项可以针对每个缓冲区进行设置,因此对不同的文件类型可以设置不同的值。
除 Ruby 以外,Vim 在发布时也附带了很多其他编程语言 的文件类型插件。
因此在实际应用中,你不会自己经常设置这两个选项。

<C-]>命令的作用也类似,它也需要进行一些配置,然而 一旦正确配置好,
它就允许我们从函数调用的地方直接跳到该函数定义的地方。

跳转列表和改变列表如同“面包屑小径”一样,它们允许我们沿原路返回。
而 <C-]> 命令则像是“虫洞”,它把我们从代码的一个地方传送到另一个地方。

用全局位置标记在文件间快速跳转:
m{letter} 命令允许我们在当前光标位置创建一个位置标记。
小写字母会创建局部于缓冲区的标记,而大写字母则创建全局标记。
设置好标记后,就可以用 `{letter} 命令使光标快速回到标记所在之处。
全局位置标记是一种书签,让我们可以在文件间跳转。全局标记在我们分析完代码,并想快速跳回一个文件时特别有用。

:vimgrep /fooBar/ **  
查找代码中所有出现 fooBar() 函数的地方。缺省情况下,:vimgrep 会直接跳到它所找到的第一处匹配上,
这或许会切换到另外一个文件。假设代码里有几十处匹配 fooBar 模式的条目。对每个 :vimgrep 所找到的匹配项,
在 quickfix 列表中都会为之创建一条记录。回到执行前的位置,可以利用全局标记。
一般来说,要养成在使用与 quickfix 列表有关的命令前, 如 :grep 、 :vimgrep 及:make,设置全局标记的习惯。


###################################### 第四部分 寄存器 #######################################
用无名寄存器实现删除、复制与粘贴操作:
通常情况下,在讨论剪切、复制与粘贴这 3 组操作时,指的都是操作系统剪贴板。 
不过,在 Vim 的术语里,我们操作的是寄存器,而并非剪贴板。
x dd 等这些命令之后内容会放到无名寄存器,p可以直接粘贴无名寄存器的内容。
"{register} 前缀的方式指定要用的寄存器。若不指明,Vim 将缺省使用无名寄存器。
如果我们想把当前单词复制到寄存器 a 中,可 执行 "ayiw,或者,可以用 "bdd,把当前整行文本剪切至寄存器 b 中。
在此之后, 我们既可以输入 "ap 粘贴来自寄存器 a 的单词,也可使用 "bp 命令粘贴来自寄存器 b 的一整行文本,
两者互不干扰。
除了普通模式的命令外,Vim 也提供用于删除、复制与粘贴操作的 Ex 命令。
例如,我们可以执行 :delete c,把当前行剪切到寄存器 c,然后再执行 :put c 命令将其粘贴至当前光标所在行之下。

复制专用寄存器("0):
复制专用寄存器,顾名思义,仅当使用 y{motion} 命令时才会被赋值。换句话讲,
使用 x、s、c{motion} 以及 d{motion} 命令均不会覆盖该寄存器。如果我们复制了一些文本,
可以确信该文本会一直保存于寄存器 0 中,直到我们复制其他文本时才会被覆盖。
复制专用寄存器是稳定的,而无名寄存器是易变的。

:reg "0 查看寄存器内容

有名寄存器("a – "z)
黑洞寄存器 "_  删除文本却不想覆盖无名寄存器中的内容时,此命令很管用。

系统剪贴板("+)与选择专用寄存器("*):
如果我们在外部程序中用剪切或复制命令获取了文本,就可以通过 "+p 命令(或在插入模式下用 <C-r>+)
将其粘贴到 Vim 内部。相反地,如果在 Vim 的复制或删除命令之前加入 "+ ,相应的文本将被捕获至系统剪贴板。
这意味着我们能够轻松地把文本粘贴到其他应用程序中了。

X11 视窗系统支持另一种被叫作主剪贴板(primary)的剪贴板,它保存着上次被高亮选中的文本,
可以用鼠标中键(如果有的话)把它们粘贴出来。Vim 的星号寄存器对应主剪贴板,可用 * 号.

"+  X11 剪贴板,用剪切、复制与粘贴命令操作
"*  X11 主剪贴板,用鼠标中键操作

Windows 与 Mac OS X 操作系统并没有主剪贴板的概念,因此 "+ 寄存器与 "* 寄 存器可以混用,
它们都代表系统剪贴板。X11 剪贴板的功能可在编译 Vim 时被激活或禁用。如果想验证该功能是否在
自己的 Vim 中被激活,可运行 :version 命令,然后找到 xterm_clipboard 关键字。
如果它前面有个减号,就表示你这个版本的 Vim 不支持该功能,而加号则表示此功能已被激活。
查看是否支持: vim --version | grep clip

在 mac 下编译也不能支持xterm_clipboard,未解决.但"+ "*是可用的.

表达式寄存器("=):
输入一段 Vim 脚本表达式并按 <CR> 执行,如果返回的是字符串(或者可被强制转换成字符串的数据),
Vim 将会使用它。

Vim 还提供了几组可被隐式赋值的寄存器。它们被称作只读寄存器:
"%  当前文件名
"#  轮换文件名
".  上次插入的文本
":  上次执行的 Ex 命令
"/  上次查找的模式

”/ 寄存器并非只读,可以用 :let 命令对其进行显式的赋值。但为了方便起见,我们仍把它列入该表。

用寄存器中的内容替换高亮选区的文本:
yiw jww ve p  先复制单词 调到下行,用可视模式选中要替换单词,粘贴替换

与系统剪贴板进行交互:
除了 Vim 内置的粘贴命令,我们有时也要用到系统粘贴命令。但当 Vim 在终端内部运行时,
使用该命令经常会产生意外的结果。为了避免这些问题,可在执行系统粘 贴命令之前激活 ‘paste’ 选项。
激活“autoindent(自动缩进)”选项,这样一来,当我们再次把系统剪贴板的文本粘贴出来时,
必然会引起奇怪的后果:
:set autoindent
设置键 :set pastetoggle=<f5>

如果你运行的 Vim 是已集成系统剪贴板的版本,就可以完全避免与 'paste' 选项打交道了。
普通模式下的 "+p 命令用来粘贴加号寄存器中的内容,即系统剪贴板的镜像。
无论 'paste' 与 'autocommand' 选项激活与否,该命令都能保证位于剪贴板中的文本缩进不会乱套。


宏的读取与执行:
把命令序列录制成宏q{register},按q结束
示例: qa A;^[Ivar q
查看寄存器a内容
:reg a

@{register} 命令执行指定寄存器的内容
@@ 来重复最近调用过的宏

黄金法则:在录制一个宏时,要确保每条命令都可被重复执行。

宏的执行是串行好还是并行好呢?
nqa 这种是串联,遇到错误会停止, normal @a是并联,针对可视化选中的每一行执行宏命令.
以并行的方式在多处执行宏更为健壮。
但如果宏在执行时遇到一处错误,而我们正想利用这些警告更正错误时,以串行、多次的方式执行宏
可以更容易定位出问题所在。

可在参数列表的所有缓冲区内执行宏了:
:argdo normal @a
:argdo write 可保存参数列表中的全部文件,但如果简单地运行以下命令的话,会更快:
:wall

基本的 Vim 脚本:
let i=0  let i+=1
:echo i

let+宏示例:
:let i=1
qa
I<C-r>=i<CR>)<Esc>
:let i += 1
q

将宏粘贴到文档中:
G 
:put a
为什么不直接用 "ap 命令呢?因为,在本例的上下文中,p 命令会把寄存器 a 的内容粘贴至当前行的
光标之后。而:put 命令总会将它们粘贴至当前行的下方,无论寄存器保存的是面向行的还是
面向字符的文本块。

将宏从文档复制回寄存器:
运行 "add(或者 :d a),但这么做可能会在以后导致问题。dd 命令将执行面向行的删除操作,
因此,寄存器会包含一个拖尾字符 ^J.
该字符表示一个换行符,且在大多数情况下,该字符都无关紧要。但有时这个拖尾字符可能会改变宏的意义。
为了保险起见,用面向字符的复制操作把这些字符从文 档复制回寄存器会更安全.
0 "ay$ dd 这样就把宏的内容保存回寄存器 a
用substitute也可以修改:
:let @a=substitute(@a, '\~', 'vU', 'g')

################################# 第五部分 模式 ###############################
按模式匹配及按原义匹配
查找、substitute 以及 global 命令的驱动核心是 Vim 的搜索引擎

如果启用‘ignorecase’设置,Vim 的查找模式将不区分大小写。这项设置具有副作用,
即会影响Vim 关键字自动补全的行为。
每次查找时设置大小写敏感性:
通过使用元字符 \c 与 \C,可以覆盖Vim缺省的大小写敏感性设置。
小写字母 \c 会让查找模式忽略大小写,而大写字母 \C 则会强制区分大小写。
/\cfoo    不区分foo大小写查找


按正则表达式查找时,使用 \v 模式开关:
与 Perl 相比,Vim 正则表达式的语法风格更接近 POSIX。对于已经熟悉 Perl 正则表达式的程序员
来说,这是一个令人失望的消息。但是,通过使用 very magic 模式开关,
就可以让 Vim 采用我们更为熟悉的正则表达式语法了。
我们可以利用 \v 模式开关来统一所有特殊符号的规则。该元字符将会激活 very magic 搜索模式,
即假定除_、大小写字母以及数字 0 到 9 之外的所有字符都具有特殊含义
\v 模式开关使得 Vim 的正则表达式引擎表现得更像是 Perl、Python 或者 Ruby 所为。
尽管如此,它们之间仍然存在差异,但Vim \v 模式开关的规则更容易记忆。
尽管 # 目前不具有特殊含义,但不意味着将来的版本也会这样。
万一将来 # 被赋予了特殊含义,我们必须要将其转义后,才可以匹配“#”字符本身。

按原义查找文本时,使用 \V 原义开关:
在正则表达式中使用的特殊字符,在按模式查找时用起来很顺手,但如果我们想按原义查找文本时,
它们就变成了阻碍。使用 very nomagic 原义开关,可以消除附加在 .、* 以及 ? 等大多数字符上
的特殊含义。
/a.k.a.  ->  /a\.k\.a\.  ->  /\Va.k.a.
:substitute 命令的查找域留空,Vim 将使用上一次的查找模式,会导致某些意想不到的错误发生。

作为通用法则,如果你想按正则表达式查找,就用模式开关\v,如果你想按原义查找文本,就用原义开关\V。

界定单词的边界:
/the  ->  /\v<the><CR> 前或后有空格

有时我们只想使用圆括号的分组功能,但并不关心所捕获的子匹配。例如,可以使用以下模式来匹配
我名字的两种形式:
/\v(And|D)rew Neil

无论我们采用的是正向还是反向查找方式,反斜杠字符永远都需要转义。

当我们使用 / 键执行一次查找时,Vim 将进行正向扫描。而如果是用 ? 键调出 查找提示符的话,
Vim 则会进行反向查找。

:set hlsearch  高亮查找匹配
:set nohlsearch  禁用高亮
:nohlsearch(:noh)  暂时禁用高亮 禁用当前而已 下次查找还是会高亮的

:set incsearch    在执行查找前预览第一处匹配

<C-r><C-w>  根据预览结果对查找域自动补全,但一旦在查找内容中加入元字符 \v 前缀,
<C-r><C-w> 会把光标下的完整单词,而不是单词的余下部分,作为补全的内容

:%s///gn  统计当前模式的匹配个数 
调用的是:substitute 命令,但标志位 n 会抑制正常的替换动作。
该命令不会对每处匹配进行替换,而是简单地统计匹配的次数,并将结果显示到命令行上。

将上次的查找命令插入到Ex模式中 <C-r>/


在整个文件范围内重复面向行的替换操作:
:s/target/replacement/g
突然,我们意识到了失误,应该加上前缀 % 才对。
接下来,我们只需输入 g& 即可在整个文件的范围内重复这条命令。

我们总是可以指定一个新的范围,并使用 :&& 命令重新执行替换操作。至于上次用的范围是什么并不重要。
具体来说,:&& 命令本身只作用于当前行,:'<,'>&& 会作用于高亮选区,而 :%&& 会作用于整个文件。
正如我们已经看到的那样,g& 命令作为 :%&& 的快捷方式,使用起来会更方便一些。

:args **/*.txt
/Pragmatic\ze Vim
:argdo %s//Practical/ge
Vim 会对所有这些文件执行 substitute 命令.e表示忽略错误

在所有的缓冲列表中查找:
/the
:vimgrep /<C-r>// **/*.txt
默认值显示当前缓冲区的查找结果.
每个由 vimgrep 返回的匹配都将在 quickfix 列表中被记录下来,
打开查看quickfix列表 :copen



global 命令:
:global 命令结合了 Ex 命令与 Vim 的模式匹配这两方面能力。
凭借该命令,我们可以在某个指定模式的所有匹配行上运行 Ex 命令。
就处理重复工作的效率而言,global 命令是除点范式以及宏之外,最为强大的 Vim 工具之一。

在缺省情况下,:global 命令的作用范围是整个文件(%),
这一点与其他大多数 Ex 命令(包括 :delete、:substitute 以及 :normal)有所不同,
这些命令的缺省范围仅为当前行(.)。
{pattern} 域与查找历史相互关联。这意味着如果将该域留空的话,Vim 会自动使用当前的查找模式。
:global 命令通常采用以下形式:
:[range] global[!] /{pattern}/ [cmd]
如果我们不指定任何 [cmd],Vim 将缺省使用 :print。

Grep 一词的来历:
请仔细琢磨一下 :global 命令的简写形式::g/re/p
re 表示 regular expression,而 p 是 :print 的缩写,它作为缺省的 [cmd] 使用。

用 ':g/re/d' 删除所有的匹配行
用 ':v/re/d' 只保留匹配行

将 TODO 项收集至寄存器:
通过把 :global 和 :yank 这两条命令结合在一起,我们可以把所有匹配 {pattern} 
的文本行收集到某个寄存器中。
:g/TODO  可以显示所有TODO

qaq 清空寄存机a的内容
reg a 查看验证
我们可以把包含 TODO 注释的行复制到此寄存器中了:
:g/TODO/yank A   将所有匹配模式 /TODO/ 的文本行依次附加到寄存器 a
此后,我们只需在任意分割窗口中打开一个新缓冲区,再运行 "ap 命令,
就可以将寄存器 a 的内容粘贴进去了。

另一种解决方案:
:g/TODO/t$
该命令是将所有 TODO 项复制 到当前文件的末尾,而不是把它们附加到寄存器。一旦运行完该命令,
我们就可以在 文件的末尾看到这些 TODO 项了。

甚至可以将 :global 命令与 :bufdo 或 :argdo 一起搭配使用,从一组文件中收集所有的 TODO 项。

Vim的排序简单使用示例:
vi{  :'<,'>sort
{}中的内容,使用vim内容排序函数进行排序.


################################# 第六部分 工具 ###############################
“只做一件事,并做到极致”是 Unix 哲学的精髓所在。

通过 ctags 建立索引,并用其浏览源代码:
ctags 是一个外部程序,它通过扫描代码库,生成关键字的索引。
ctags *.rb 创建了一个名为 tags 的纯文本文件,其内容是 ctags 经过对 3 个源文件的分析
而生成的关键字索引。
每一行文本均由关键字、文件名以及关键字在源代码中的位置这 3 项内容构成。
关键字是按照字母顺序排列的,Vim可以采用折半查找法快速地定位到某个关键字。

配置 Vim 使用 ctags:
想在 Vim 中使用基于 ctag 的跳转命令,首先,要确保标签文件是最新的, 
其次,要让 Vim 知道到哪里去找标签文件。

手动执行 ctags:
:!ctags -R
该命令将从 Vim 当前的工作目录开始,遍历其所有的子目录,并为其中的每一个文件建立索引。
最终,再把这个标签文件保存到当前工作目录中。
调整一下命令,加入 --exclude=.git 或 --languages=-sql 等类似的参数,
如果每次手动输入命令的话,势必会很麻烦。
可以建立映射:
:nnoremap <f5> :!ctags -R<CR>

在每次保存文件时自动执行 ctags:
Vim 的自动命令(autocommand)功能允许我们在某个事件发生时调用一条命令,
这些事件包括缓冲区的创建、打开或者保存等。因此,我们可以创建一条自动命令,
在每次保存文件时自动调用 ctags:
:autocmd BufWritePost * call system("ctags -R")

通过版本控制工具的回调机制自动执行 ctags:
每当提交代码改动时,自动更新代码库的索引。此法很好地兼顾了前两种方式的优缺点。

使用 Vim 的标签跳转命令,浏览关键字的定义:
按下 <C-]> 展示了实际的操作过程:光标将会从当前所在的关键字跳转到它的定义处。
Vim 会为我们访问过的标签维护一个历史列表。
在浏览标签历史记录时,<C-t> 命令会充当“后退按钮”的角色。

我们还可以用 g<C-]> 命令来代替 <C-]>。如果当前关键字只有一处匹配,
这两条命令的行为将完全一致,但如果发生了多处匹配的情况,g<C-]> 命令会从标签匹配列表
中挑出可选项供我们选择.
:tselect 命令,调出标签匹配列表
也可以用:bnext、:tprev、:tfirst、:tlast

其实,我们不必非得将光标移到关键字上,才能进行标签跳转,也可以用 Ex 命令达到同样的目的。
:tag {keyword} 与 :tjump {keyword} 就分别等同于<C-]>与g<C-]>的功能。

浏览所有以 phone 为结尾的关键字定义:
:tjump /phone$

浏览Quickfix列表命令:
:cnext 跳转到下一项
:cprev 跳转到上一项
:cfirst 跳转到第一项
:clast 跳转到最后一项
:cnfile 跳转到下一个文件中的第一项
:cpfile 跳转到上一个文件中的最后一项
:cc N 跳转到第 n 项
:copen 打开 quickfix 窗口
:cclose 关闭 quickfix 窗口

当 quickfix 窗口处于活动状态时,我们可以像平常一样使用 :q 将其关闭。 
但如果其他窗口是活动窗口的话,我们也可以通过 :cclose 将其关闭。


:grep 命令是外部 grep 程序的包装器。 通过配置‘grepprg’ 与‘grepformat’ 这两个选项,
我们可以对 Vim 查找的行为进行定制。
ack比grep快,强大
ack --nogroup --column Waldo *
:set grepprg=ack\ --nogroup\ --column\ $*
:set grepformat=%f:%l:%c:%m
grep 采用的是 POSIX 风格的正则表达式,而 ack 则采用的是 Perl 风格的正则表达式。
如果 :grep 命令在后台调用 ack,可能会引起误导。与其这样,
你为什么不创建一条名为 :Ack 的命令,使其名副其实呢?Ack.vim插件恰好符合以上需求。

:vimgrep 命令允许我们使用 Vim 自带的正则表达式引擎,实现跨文件的查找功能。


触发自动补全:
通过 <C-p> 与 <C-n> 这两个组合键,我们不仅可以在插入模式下触发 Vim 的自 动补全,
而且还可以用它们在补全列表中反向或正向选择。
<C-n> 普通关键字
<C-x><C-n> 当前缓冲区关键字
<C-x><C-i> 包含文件关键字
<C-x><C-]> 标签文件关键字
<C-x><C-k> 字典查找
<C-x><C-l> 整行补全
<C-x><C-f> 文件名补全
<C-x><C-o> 全能(Omni)补全  内置插件 filetype plugin on

<C-n> 可能会产生更多的补全建议,因为除了当前缓冲区以外,它还用其他来源来填充补全列表。
<C-e> 来终止本次自动补全。

:set spell 来激活 Vim 的拼写检查功能
z=  获取 Vim 提供的更正建议列表
1z=  直接改成建议列表的第一项

<C-x><C-f>  补全当前文件名

指定某个语言的区域性变体:
Vim 的拼写文件本身就支持英语的几种区域性变体。缺省设置 spelllang=en 
意味着所有被以英语为母语的地区所认可的单词都是合法的。
:set spell
:set spelllang=en_us
设置Vim 只接受美式拼法

为专业术语创建拼写文件:
setlocal spelllang=en_us 
setlocal spellfile=~/.vim/spell/en.utf-8.add 
setlocal spellfile+=~/books/practical_vim/jargon.utf-8.add

更多阅读学习资料: