Vim 解决问题的方式
理想的编辑模式:用一次按键移动,用另外一次按键执行。
Important
从本质上讲,我们的编辑工作是重复性的,不论是修改文档的不同地方,还是在文档内移动,我们都会有很多重复操作。Vim 对重复操作进行了优化,它之所以能高效地重复,是因为它会记录我们最近的操作,让我们用一次按键就能重复上次操作。要想利用这个强大的功能,首先要求我们能够学会规划按键动作,使得重复时可以完成一项有用的工作。这一理念是高效使用 Vim 的关键。
面对重复性的工作,我们的口诀就是:修改、重复 .
、回退 u
。
原则
- 用好
Esc
键,把撤销单元切成块,使撤销命令作用于单词、句子、段落。一次思考对应一次插入模式
- 构造可重复的修改,最好让一次修改是最小原子性的,方便重复任意次,反例,
d2w
无法删除 3 个单词
- 能重复就别用次数,只有在必要时使用次数。因为次数很容易数错,而不小心多按的重复操作用 u 很容易恢复
- 操作符 + 动作命令 = 操作
- 只要可能,最好用操作符命令,而不是可视命令
- Ex 命令的强大之处在于可以在多行同时执行,而普通模式一般操作当前光标处
h
和 l
键只有 “ 差一误差 ” 时才使用,平时应该用其他键移动光标更高效
- 面向字符串的移动更快,面向单词的移动更细粒度
- 像 scrabble 玩家那样思考,查找低频字母更高效
- 可以用
{motion}
的地方都可以用文本对象,文本对象处理代码更高效
- 浏览文件前用
m{A-Z}
可以标记全局位置,方便跳转回原地
- 录制宏时确保光标位置是正确的(比如行首),以保证每条命令都可以被重复执行
- 替换操作一般分两步实现解耦,第一步写正则表达式匹配,第二步进行替换
第一部分 模式
普通模式
操作 |
含义 |
80<C-a> |
数字增加 80 |
80<C-x> |
数字减少 80 |
操作符命令列表:
操作 |
含义 |
c |
修改 |
d |
删除 |
y |
复制到寄存器 |
g~ |
反转大小写 |
gu |
转化为小写 |
gU |
转化为大写 |
> |
增加缩进 |
< |
减少缩进 |
= |
自动缩进 |
! |
使用外部程序过滤 {motion} 所跨越的行 |
插入模式
操作 |
含义 |
<C-h> |
删除前一个字符 |
<C-w> |
删除前一个单词 |
<C-u> |
删至行首 |
<C-o> |
切换到插入 - 普通模式(普通模式下 = 回跳前一个跳转位置) |
<C-r>{register} |
不离开插入模式,粘贴 register 中的文本 |
<C-r>= |
使用表达式寄存器,进行计算 |
R |
切换到替换模式,替换字符 |
可视模式
操作 |
含义 |
gv |
重选上次高亮选区 |
o |
切换选区的活动端 |
命令行模式
操作 |
含义 |
<C-w> |
同普通模式 |
<C-u> |
同普通模式 |
<C-r>{register} |
同普通模式 |
:[range]delete[x] |
删除指定范围到寄存器 [x] 中 |
:[range]yank[x] |
复制指定范围到寄存器 [x] 中 |
:[range]copy{address} |
复制指定范围到 {address} 行下面 |
:[range]normal{commands} |
对指定范围内执行普通模式命令 |
:[range]substitude/{patten}/{string}/[flags] |
对指定范围内的 patten 替换为 string |
:[range]global/{patten}/[cmd] |
对指定范围内匹配 pattern 的行执行 cmd |
:{start},{end} |
指定范围 |
. |
当前行 |
% |
当前文件中的所有行 |
'< |
高亮区域的首航 |
'> |
高亮区域的尾行 |
:copy |
简写 :t |
:move |
简写 :m |
@: |
重复上次命令 |
:shell |
启动一个临时 shell 会话,用 exit 退出 |
<C-z> |
挂起 vim |
fg %[id] |
唤醒作业,移到前台 |
第二部分 文件
管理多个文件
操作 |
含义 |
+ |
缓冲区被修改过 |
a |
活动缓冲区 |
h |
隐藏缓冲区 |
% |
哪个缓冲区在当前窗口可见 |
# |
轮换文件 |
<C-^> |
在当前文件和轮换文件之间快速切换 |
<C-w>s |
水平切分 |
<C-w>v |
垂直切分 |
<C-w>= |
等宽等高 |
<C-w>- |
最大化高度 |
<C-w>| |
最大化宽度 |
[N]<C-w>- |
高度设置为 N |
[N]<C-w>| |
宽度设置为 N |
<C-w>T |
移动到新标签页 |
gt |
切换到下一个标签页 |
gT |
切换到前一个标签页 |
打开及保存文件
操作 |
含义 |
:pwd |
打印工作目录 |
:set path+=dir/** |
设置 path |
:find filename |
查找打开文件(必须先设置 path) |
:e % |
补全当前文件完整路径 |
:h |
去除文件名,保留路径其他部分 |
:e %:h |
补全当前文件所在目录 |
第三部分 更快地移动及跳转
文件内跳转
操作 |
含义 |
0 |
光标移动到行首 |
^ |
光标移动到第一个非空白字符 |
$ |
光标移动到行尾 |
ge |
光标移动到上一个单词的结尾 |
f{char} |
移动到下一个 char 字符上,; 跳转到下一个匹配项,, 跳转到上一个匹配项 |
t{char} |
移动到下一个 char 之前的字符上,比如删除特定字符 / 符号前的内容等,非常有用 |
/ |
查找操作是开操作,不包含当前字符,d/th<CR> 命令会删除当前位置到 th 之前的内容,保留 th 字符 |
m{a-zA-Z} |
大写标记全局可见,小写只能本文件可见 |
% |
在匹配括号之间跳转,修改成对括号前先执行 %,修改完后用 `` 跳转到对应括号 |
gi: |
从普通模式返回到上次修改的地方,并进入插入模式继续编辑 |
文本对象:
操作 |
含义 |
a) |
包含圆括号在内 |
a] |
包含方括号在内 |
a> |
包含尖括号在内 |
a' |
包含单引号在内 |
a" |
包含双引号在内 |
a` |
包含反引号在内 |
at |
包含 XML 标签在内 |
i) |
圆括号内部 |
i] |
方括号内部 |
i> |
尖括号内部 |
i' |
单引号内部 |
i" |
双引号内部 |
i` |
反引号内部 |
it |
XML 标签内部 |
自动标记位置:
操作 |
含义 |
`` |
当前文件上次跳转动作之前位置 |
`. |
上次修改的地方 |
`^ |
上次插入的地方 |
`[ |
上次修改 / 复制的起始位置 |
`] |
上次修改 / 复制的结束位置 |
`< |
上次高亮选区的起始位置 |
`> |
上次高亮选区的结束位置 |
文件间跳转
操作 |
含义 |
<C-o> |
后退 |
<C-i> |
前进,插入模式下 = <Tab> |
gf |
跳转到当前光标下的文件 |
寄存器
复制与粘贴
操作 |
含义 |
"{register}y{motion} |
指定复制到特定寄存器 |
<C-r>{register} |
在插入模式中使用寄存器 |
寄存器:
操作 |
含义 |
- |
黑洞寄存器 |
" |
无名寄存器 |
0 |
复制专用寄存器,只有 y{motion} 才会改变它的值 |
a-z |
有名寄存器,覆盖原始内容 |
A-Z |
有名寄存器,追加到寄存器 |
+ |
系统剪切板 |
* |
主剪切板,鼠标中键 |
= |
表达式寄存器 |
特殊只读寄存器:
操作 |
含义 |
% |
当前文件 |
# |
轮换文件 |
. |
上次插入的文本 |
: |
上次执行的 Ex 命令 |
/ |
上次查找的模式 |
宏
操作 |
含义 |
q{register} |
开始 / 结束录制 |
@{register} |
使用宏 |
@@ |
最近使用的宏 |
100@a |
重复调用 100 次 a 中的宏 |
'<, '>normal @a |
选中区域,并行执行 a 中的宏 |
qA |
追加到寄存器 a 中 |
:put a |
把 a 中的宏复制到文本中,方便编辑 |
"ay$ |
修改后的宏内容复制到 a 中 |
模式(正则表达式)
查找
操作 |
含义 |
\v |
激活 very magic 搜索模式,假定模式中除 -, 大小写字母,0-9 之外的所有字符都有特殊含义 |
\V |
激活 very nomagic 搜索模式,假定模式中只有 \ 有特殊含义 |
< , > |
单词定界符 , example: /\v<the><CR> 只会匹配单词 the,忽略 these, they 等 |
/ |
正向查找 |
? |
反向查找 |
替换
:[range]s/{pattern}/{string}/[flags]
替换域
操作 |
含义 |
\r |
换行符 |
\t |
制表符 |
\\ |
反斜杠 |
\={vim script} |
执行 vim script,并把返回结果作为替换 string |
/{pattern} |
第一步匹配 |
:%s//{string}/g |
第二步替换 |
:%s//<C-r>0/g |
把寄存器 0 中的内容作为 string |
g& |
重复上次替换 |
global 命令
:[range]g[!]/{pattern}/[cmd]
操作 |
含义 |
:g/re/p |
g 是 global 简写,re 指正则表达式,p 是 print 简写,整个命令即 grep 的含义 |
工具
操作 |
含义 |
:! ctags -R |
对当前目录递归生成 tag 文件 |
<C-]> |
跳转到定义处 |
<C-t> |
跳转回退 |
g<C-]> |
弹出标签列表供选择,适用于多个匹配项 |
Quickfix
操作 |
含义 |
:make |
再 Vim 内编译 |
:cnext |
下一项 |
:cprev |
前一项 |
:cfirst |
第一项 |
:clast |
最后一项 |
:copen |
打开 quickfix 窗口 |
:cclose |
关闭 quickfix 窗口 |
grep, vimgrep
操作 |
含义 |
:grep |
调用外部 grep |
:vimgrep |
调用内部 grep |
自动补全
操作 |
含义 |
<C-n> |
普通关键字补全 |
<C-x><C-l> |
整行补全 |
<C-x><C-f> |
文件名补全 |
拼写检查
操作 |
含义 |
:set sepll |
打开 |
[s |
前一个拼写错误 |
s] |
后一个拼写错误 |
z= |
为当前词提供更正建议 |
zg |
把当前词加入到拼写文件中 |
zw |
把当前词从拼写文件中删除 |
<C-x>s |
在插入模式下触发自动补全,完成拼写更正 |
Ref
Pratical Vim