Vim解决问题的方式
.
命令
- 通过
.
命令重复之前的操作 - 通过
x
命令删除当前光标所在字符 - 通过
u
命令撤销修改 - 通过
dd
命令删除整行 >G
命令增加从当前行到文档末尾处的缩进层级
不要自我重复
A
命令可以进入插入模式并把光标移动至行尾(相当于a$
)
如果想在每行末尾添加一个分号可以执行A j . . .
C = c$
删除光标到行尾字符,并进入插入模式s = cl
删除光标所在字符,并进入插入模式S = ^c
删除整行,并进入插入模式I = ^i
将光标移至行首,并计入插入模式o = A<CR>
另起一行(在当前行下方),并进入插入模式O = ko
在当前行上方
以退为进
- 通过
f{char}
来快速跳转到特定字符 - 通过
;
来重复之前的f
命令3
执行、重复、回退
目的 | 操作 | 重复 | 回退 |
---|---|---|---|
做出一个修改 | {edit} | . | u |
在行内查找下一指定字符 | f{char}/t{char} | ; | , |
在行内查找上一指定字符 | F{char}/T{char} | ; | , |
在文档中查找下一处匹配项 | /pattern | n | N |
在文档中寻找上一处匹配项 | ?pattern | n | N |
执行替换 | :s/target/replacement | & | u |
执行一系列修改 | qx{changes}q | @x | u |
查找并手动替换
- 在单词上使用
*
命令可以查找当前光标下的单词 - 使用n可以移动到下一个
- 使用cw可以删除从光标位置到单词结尾间的字符
认识.范式
用一次按键移动,另一次按键执行
普通模式
停顿时请移开画笔
在其他编辑器中大多数时间都处于类似vim的插入模式中,而在vim中大多数时候处于普通模式,作者使用了一个非常好的比喻:用画笔作画就像是插入模式,而作家在思考构图,选择颜色时是不会把画笔停在画布上的。
普通模式很明显与思考的情况很契合,所以使用vim应该适应普通模式带来的变化。
把撤销单元切成块
在其他编辑器中,输入一些词后使用撤销命令,可能会撤销最后输入的词或字符,然而在Vim中,我们自己可以控制撤销的粒度。
u
键会触发撤销命令,它会撤销最新的修改。一次修改可以是改变文档内文本的任意操作,其中包括在普通模式、可视模式以及命令行模式中所触发的命令,而且一次修改也包括了在插入模式中输入(或删除)的文本,因此我们也可以说,i{insert some text}<Esc>
是一次修改。
所以养成输入完一些内容后退出插入模式也是应该养成的习惯。
构造可重复的修改
如何删除一个单词(当前光标在单词尾部)
db
删除从光标起始位置到单词开头的内容x
删掉剩余的字母b
将光标移动到单词开头dw
删除从光标到结尾的单词内容daw
删除整个单词
用次数做简单的算数运算
很多命令我们都可以通过在命令前面加数字来重复命令
*<C-a>
和<C-x>
命令分别对数字执行加和减操作,如果当前光标位置不是数字它会在本行向后查找第一个数字
- 如果在上面的两个命令前加数字就可以实现增加减少对应数值
yyp
命令可以复制当前行vim遇到0开头的数字会按8进制分析
能重复,就别用次数
通常来说重复能带来更多的复用性和可操作性(方便撤销),但是如果是确定的操作,比如一个数字加减多少或者将两个单词改成其他单词,这种情况下使用次数就要优于重复了。
双剑合璧,天下无敌
操作符 + 动作命令 = 操作
d{motion}
命令可以对一个字符(dl)、一个完整单词(daw)或一整个段落(dap)进行操作,它作用的范围由动作命令决定。c{motion}
、y{motion}
以及其他一些命令也类似,它们被统称为操作符(operator)。可以用:h operator
命令来查看完整列表,下面是一些比较常见的操作符。
命令 | 用途 |
---|---|
c | 修改 |
d | 删除 |
y | 复制到寄存器 |
g~ | 反转大小写 |
gu | 转换为大写 |
gU | 转化为大写 |
|增加缩进
<|减小缩进
=|自动缩进
!|使用外部程序过滤{motion}所跨越的行
下面是一些比较常见的动作命令
命令 | 用途 |
---|---|
l | 一个字符 |
w | 从当前位置到光标末尾 |
b | 从当前位置到单词首部 |
aw | 整个单词 |
ap | 整个段落 |
$ | 到行尾 |
^ | 到行首 |
it | 标签中内容 |
当一个操作命令被重复两次时会作用于当前行,所以dd
是删除当前行,>>
是缩进当前行。gU
命令(gu
)是特殊情况,你既可以使用gUgU
也可以使用gUU
。
输入操作符后等待接受动作命令的状态可以被称为待决模式,当这个模式被激活时也可以通过
<Esc>
键退出
插入模式
在插入模式中可即时更正错误
在插入模式下,退格键的作用如你所愿,它删除光标前的字符。另外,还可以用下面这些组合键。
按键操作 | 用途 |
---|---|
<C-h> |
删除前一个字符(同退格键) |
<C-w> |
删除前一个单词 |
<C-u> |
删至行首 |
返回普通模式
返回普通模式的经典方式是使用<Esc>
键,但是它不太好按,作为替代可以使用<c-[>
。
按键操作 | 用途 |
---|---|
<Esc> |
切换到普通模式 |
<c-[> |
切换到普通模式 |
<c-o> |
切换到插入-普通模式 |
插入普通模式是可以让用户在插入模式中临时切换到普通模式,然后在输入一个命令后回到插入模式
例如zz
命令可以重绘屏幕,并把当前行显示到屏幕正中,使用<C-o>zz
可以很好的滚动屏幕。
不离开插入模式,粘贴寄存器中的文本
使用yt
命令可以将文本复制到寄存器中,通过<C-r>
命令可以从相应的寄存器中粘贴文本。<C-r>
命令会粘贴换行和缩进,如果想要粘贴纯文本可以使用<C-p>
命令。
随时随地做运算
使用<C-r>=
可以访问表达式寄存器,它可以执行vim命令并返回结果,也就是说我们可以通过它来完成计算如6*35
然后使用回车让它插入到文档中
插入非常用字符
按键操作 | 用途 |
---|---|
以十进制字符编码插入字符 | |
以十六进制字符编码插入字符 | |
按原义插入非数字字符 | |
插入以二合字母{char1}{char2} 表示的字符 |
用二合字母插入非常用字符
二合字母用起来很方便。在插入模式中,只需输入<C-k>>{char1}{char2}
即可。因此,如果想输入以二合字母?I
表示的“¿”字符,可以简单地输入<C-k>?I
。
Vim在选择组成二合字母的两个字符时,尽量使之具有描述性,这样就更容易记住它们,甚至也能猜出其含义。例如,左右书名号《和》分别以二合字母<<及>>表示,普通分数(或常用分数)½、¼和¾则分别以二合字母12、14和34来表示。
用替换模式替换已有文本
使用R
命令可以进入替换模式,进入替换模式可以使用输入的字符替换掉已有字符。
在vim中tab的长度是8位,使用R
进入的替换模式会把tab当成一个字符,而使用gR
可以进入虚拟替换模式,他会像屏幕显示的那样进行替换(前7位为空,第八位为tab)
vim也提供了单次替换模式r{char}
和gr{char}
可以在替换一个字符后回到普通模式
可视模式
深入理解可视模式
某些可视模式命令执行的基本功能与普通模式相同,但操作上有些细微的变化。例如,在这两种模式中,c
命令的功能是一样的,都是删除指定的文本并切换到插入模式。不过,要指定其操作的范围,二者的方式却不甚相同。在普通模式中,先触发修改命令,然后使用动作命令指定其作用范围。在可视模式中,要先选中选区,然后再触发修改命令。这种次序颠倒的方式对所有的操作符命令都适用。对大多数人来说,可视模式的做法感觉起来更自然。
在一个典型的文本编辑器环境中,当选中一段文本后,再输入任意可见字符时,这些选中的文本将会被删除。虽然Vim的可视模式未遵从此惯例,但是其选择模式(Select Mode)却按此方式工作。根据Vim的内置文档所述,选择模式“类似于Microsoft Windows的选择模式”。在此模式下,输入的可见字符会使选中的文本被删除,同时Vim会进入插入模式,并插入这个可见字符。
选择高亮区域(三种可视模式)
Vim有3种可视模式。在面向字符的可视模式中,我们能够选择任意的字符范围,不论它是单个字符,还是位于一行内,或是跨若干行的指定字符范围,都没问题。该模式适用于操作单词或短语。如果我们想对整行进行操作,可以改用面向行的可视模式。而面向列块的可视模式则允许对文档中的列块进行操作。
激活可视模式
命令 | 用途 |
---|---|
v |
激活面向字符的可视模式 |
V |
激活面向行的可视模式 |
<C-v> |
激活面向列块的可视模式 |
gv |
重选上次的高亮区域 |
在可视模式间切换
按键操作 | 用途 |
---|---|
<Esc>/<C-[> |
回到普通模式 |
v/V/<C-v> |
切换到普通模式(在对应的面向字符可视模式时、面向行的可视模式和面向列块的可视模式中使用时) |
v |
用途 |
V |
用途 |
<C-v> |
用途 |
O |
用途 |
切换选区的活动端
高亮选区的范围由其两个端点界定。其中一端固定,另一端可以随光标自由移动,可以用 o 键来切换其活动的端点。在定义选区时,如果定义到一半,才发现选区开始的位置不对,此时用这个键会很方便,不用退出可视模式再从头开始,只需按一下 o ,然后重新调整选区的边界即可。
重复执行面向行的可视命令
在可视模式下执行完一次操作会回到普通模式而.
命令可以重复之前执行的命令
只要可能,最好用操作符命令,而不是可视命令
当一条可视模式命令重复执行时,它会影响相同数量的文本
作为一般的原则,在做一系列可重复的修改时,最好首选操作符命令,而不是其对应的可视模式命令
用面向列块的可视模式编辑表格数据
1 | Chapter Page |
像这样一个格式我们可以使用如下操作:
- 将光标移动到第一行中间
- 使用
<C-v>3j
选中3列 - 使用
x...
删除一个空格并重复三次 - 使用
gv
重复选择刚才的高亮区域 - 使用
r|
将选中的空格替换为|
- 使用
yyp
添加一行 - 使用
Vr-
将添加的行替换为-
修改列文本
vim进入列选择模式可以同时操作很多列,如果使用c
进入插入模式也可以同时在多行添加内容,但是在插入模式时变动并不会添加到屏幕上,在退出插入模式后他们才会出现
在长短不一的高亮块后添加文本
为长短不一的高亮块后添加文本可以采用如下方式
- 使用
<C-v>
进入块列可视模式 - 使用
j
选中多行 - 使用
$
选择到行尾 - 使用
A
进入插入模式
如果是想在行首只需用
^
替换$
,用I
替换A
命令行模式
认识Vim的命令行模式
命令 | 用途 |
---|---|
:[range]delete [x] |
删除指定范围内的行[到寄存器x中] |
:[range]yank [x] |
复制指定范围的行[到寄存器x中] |
:[line]put [x] |
在指定行后粘贴寄存器x中的内容 |
:[range]copy {address} |
把指定范围内的行拷贝到{address} 指定的行之下 |
:[range]move {address} |
把指定范围内的行移动到 {address} 指定的行之下 |
:[range]join |
连接指定范围内的行 |
:[range]normal {commands} |
对指定范围内的每一行执行普通模式命令 {commands} |
:[range]substitute/{pattern}/{string}/[flags] |
把指定范围内出现{pattern}的地方替换为{string} |
:[range]global/{pattern}/[cmd] |
对指定范围内匹配{pattern}的所有行执行Ex 命令{cmd} |
vim命令行模式中的特殊按键
有些命令在插入模式和命令行模式中可以通用。例如,可以用<C-w>
和<C-u>
分别删除至上个单词的开头及行首,也可以用<C-v>
或<C-k>
来插入键盘上找不到的字符,还可以用<C-r>{register}
命令把任意寄存器的内容插入命令行。然而,有些命令行模式中的组合键在插入模式中不存在。
在一行或多个连续行上执行命令
用行号作为地址
如果输入一个数字vim会把它当做行号并移动到指定行,比如删除第三行命令模式是:3d
而普通模式是3Gdd
用地址指定一个范围
:2,5
这代表2到5行.
可以代表当前行,$
代表最后一行,如:.,$
代表从当前行到最后一行%
代表当前文件中的所有行
用高亮选区指定范围
可以用高亮选区选定一个范围然后再使用:
执行一个命令
在按下:
后会显示:'<,'>
,符号'<
是代表高亮选区首行的位置标记,'>
则代表高亮选区的最后一行,这些位置标记即使在退出可视模式后仍然存在。如果尝试在普通模式下直接运行 :'<,'>p
,它会始终回显上一次高亮选区选中的内容。
用模式指定范围
可以用模式来指定范围,:/<html>/,/<\/html>/p
,这个指令指定的范围是连个html标签中的内容。
用偏移对地址进行修正
假设想对位于<html></html>
之间的每一行都运行一条Ex
命令,但是不想包括<html>
及</html>
标签所在的行,那么可以为之加上偏移。
1 | :/<html>/+1,/<\/html>/-1p |
这样选中的就是html标签中的内容
总结
符号 | 地址 |
---|---|
1 | 文件第一行 |
$ | 文件最后一行 |
0 | 虚拟行,位于文件第一行上方 |
. | 光标所在行 |
‘m | 包含位置标记m的行 |
‘< | 高亮选区的起始行 |
‘> | 高亮选区的结束行 |
% | 整个文件 |
使用:t
和:m
命令复制和移动行
命令 | 用途 |
---|---|
:6t. |
把第六行复制到当前行下方 |
:t6 |
把当前行复制到第六行下方 |
:t. |
为当前行创建一个副本(类似于普通模式的yyp) |
:t$ |
把当前行复制到文本末尾 |
:'<,'>t0 |
把高亮选中的行复制到文章开头 |
:t.
命令会创建一个当前行副本,另外一种做法则是用普通模式的复制和粘贴命令(yyp
)来达到同样的效果。这两种复制当前行的技术有个需要关注的差别:yyp
会使用寄存器,:t.
则不会。因此,当我不想覆盖默认寄存器中的当前内容时,有时会使用:t.
来复制行。
先跳到想复制的行上(6G
),复制该行(yy
),快速跳回原先的位置(<C-o>
),然后再用粘贴命令(p
)创建一个副本。由此可见,在复制距离较远的行时,:t
命令通常更加高效。
用:m
命令移动行
将某一行移动到行尾可以这么操作:
- 高亮选区
:m$
也可以使用dGp
使用@:
可以重复上次的ex命令
在指定范围上执行普通模式命令
如果想在一系列连续行上执行一条普通模式命令,可以使用:normal
命令。
如果想在所有行后加入分号可以如下操作:
- A
- jVG
- :normal
也可以直接使用
:%normal A;
命令来完成操作
重复上次的Ex命令
@:
命令可以重复上次的Ex命令
自动补全Ex命令
使用<Tab>
可以自动补全命令,并且使用<C-d>
可以查看可用的补全列表
把当前单词插入命令行
在Vim命令行下,<C-r><C-w>
会复制光标下的单词并把他插入到命令行中。
例如我们想把所有的tally换成counter可以这么操作:
- 在tally上使用
*
- 使用
cw
更改单词为counter - 使用
:%s//<C-r><C-w>/g
回溯历史命令
使用<Up>
和<Down>
键可以回到更早的历史命令
结识命令行窗口
使用q:
可以进入命令行窗口
运行shell命令
在命令行模式给命令加一个!
即可运行外部shell命令
在编辑器中无法使用,不过多介绍
批处理运行Ex命令
在编辑器中无法使用,不过多介绍