Vim教程博大精深,本文更多属于自我理解性质,请悉知。
Vim的学习曲线非常陡峭,作者认为“面向操作学习Vim”是科学合适的学习途径,能够降低学习Vim的难度。具体来说,“Vim操作”被设计有详细用法,详细用法中涉及到了“适用模式,是否支持重复执行N次操作,限定范围形式,是否支持文本对象”等内容,“Vim操作”是核心,它串联了这些内容,跟学习使用Linux中“Linux命令”是核心一样。
可通过:help topic
查看关于某个“topic”的帮助内容。
一、操作
1.1、模式切换
操作 | 简单描述 |
---|---|
i | 从普通模式切入插入模式,在当前光标处插入 |
A | 从普通模式切入插入模式,在当前行行尾插入 |
v | 从普通模式切入可视模式,按照字符选取 |
V | 从普通模式切入可视模式,按照行选取 |
连续按Esc一次或者两次 | 从插入模式、命令模式、可视模式切回普通模式 |
1.2、移动
操作 | 简单描述 | 适用模式 | 是否支持重复执行N次操作 | 限定范围形式 | 是否支持文本对象 |
---|---|---|---|---|---|
gg | 定位到文件头部 | 普通模式,可视模式 | [普通]不支持 [可视]不支持 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
G | 定位到文件尾部 | 普通模式,可视模式 | [普通]不支持 [可视]不支持 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
NG | 定位到第N行 | 普通模式,可视模式 | [普通]不支持 [可视]不支持 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
0 | 定位到行首 | 普通模式,可视模式 | [普通]不支持 [可视]不支持 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
^ | 定位到行首第一个非空字符 | 普通模式,可视模式 | [普通]不支持 [可视]不支持 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
$ | 定位到行尾 | 普通模式,可视模式 | [普通]不支持 [可视]不支持 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
h | 左移一个字符 | 普通模式,可视模式 | [普通]支持 [可视]支持 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
l | 右移一个字符 | 普通模式,可视模式 | [普通]支持 [可视]支持 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
k | 上移一个字符 | 普通模式,可视模式 | [普通]支持 [可视]支持 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
j | 下移一个字符 | 普通模式,可视模式 | [普通]支持 [可视]支持 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
f<X> | 快速定位到本行当前光标右侧第一个X字符处 | 普通模式,可视模式 | [普通]支持 [可视]支持 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
F<X> | 快速定位到本行当前光标左侧第一个X字符处 | 普通模式,可视模式 | [普通]支持 [可视]支持 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
t<X> | 快速定位到本行当前光标右侧第一个X字符处左侧 | 普通模式,可视模式 | [普通]支持 [可视]支持 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
T<X> | 快速定位到本行当前光标左侧第一个X字符处右侧 | 普通模式,可视模式 | [普通]支持 [可视]支持 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
w | 右移一个单词,停在单词头 | 普通模式,可视模式 | [普通]支持 [可视]支持 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
e | 右移一个单词,停在单词尾 | 普通模式,可视模式 | [普通]支持 [可视]支持 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
b | 左移一个单词,停在单词头 | 普通模式,可视模式 | [普通]支持 [可视]支持 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
% | 定位到匹配的括号处(包括“花括号{},圆括号(),方括号[]”,不包括“尖括号<>”) | 普通模式,可视模式 | [普通]不支持 [可视]不支持 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
]m | 快速定位到下一个方法的“{”字符处(方法体使用“{}”字符对定义) | 普通模式,可视模式 | [普通]支持 [可视]支持 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
[m | 快速定位到上一个方法的“{”字符处(方法体使用“{}”字符对定义) | 普通模式,可视模式 | [普通]支持 [可视]支持 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
Ctrl+f | 向下移动一页,即PageDown | 普通模式,可视模式 | [普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
Ctrl+b | 向上移动一页,即PageUp | 普通模式,可视模式 | [普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
1.3、编辑
操作 | 简单描述 | 适用模式 | 是否支持重复执行N次操作 | 限定范围形式 | 是否支持文本对象 |
---|---|---|---|---|---|
u | 撤销操作 | 普通模式,可视模式(撤销选取并返回普通模式) | [普通]支持 [可视]不支持 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
Ctrl+r | 反撤销操作 | 普通模式 | [普通]支持 | [普通]未探究 | [普通]未探究 |
dd | 删除当前行 | 普通模式 | [普通]支持 | [普通]不支持 | [普通]不支持 |
d | 删除字符 | 普通模式,可视模式(删除选取内容并退回到普通模式),命令模式 | [普通]不支持 [可视]不支持 [命令]不支持 |
[普通]操作End [可视]不支持 [命令]Range操作 |
[普通]支持 [可视]不支持 [命令]不支持 |
x(即“dl”) | 删除字符 | 普通模式,可视模式(删除选取内容并退回到普通模式) | [普通]支持 [可视]不支持 |
[普通]不支持 [可视]不支持 |
[普通]不支持 [可视]不支持 |
yy | 复制当前行 | 普通模式,可视模式(复制选取内容并退回到普通模式) | [普通]支持 [可视]支持 |
[普通]不支持 [可视]不支持 |
[普通]不支持 [可视]不支持 |
y | 复制字符 | 普通模式,可视模式(复制选取内容并退回到普通模式),命令模式 | [普通]不支持 [可视]不支持 [命令]不支持 |
[普通]操作End [可视]不支持 [命令]Range操作 |
[普通]支持 [可视]不支持 [命令]不支持 |
p | 在光标后粘贴 | 普通模式,可视模式(替换选取内容并退回到普通模式) | [普通]支持 [可视]支持 |
[普通]不支持 [可视]不支持 |
[普通]不支持 [可视]不支持 |
r | 替换字符 | 普通模式,可视模式(替换选取内容并退回到普通模式) | [普通]支持 [可视]支持 |
[普通]不支持 [可视]不支持 |
[普通]不支持 [可视]不支持 |
~ | 字母大小写互换 | 普通模式,可视模式(转换选取内容并退回到普通模式) | [普通]支持 [可视]不支持 |
[普通]不支持 [可视]不支持 |
[普通]不支持 [可视]不支持 |
gu | 切换字母为小写 | 普通模式,可视模式(转换选取内容并退回到普通模式) | [普通]支持 [可视]不支持 |
[普通]操作End [可视]不支持 |
[普通]支持 [可视]不支持 |
gU | 切换字母为大写 | 普通模式,可视模式(转换选取内容并退回到普通模式) | [普通]支持 [可视]不支持 |
[普通]操作End [可视]不支持 |
[普通]支持 [可视]不支持 |
1.4、查找替换
操作 | 简单描述 | 适用模式 | 是否支持重复执行N次操作 | 限定范围形式 | 是否支持文本对象 |
---|---|---|---|---|---|
/ | 查找 | 命令模式 | [命令]不支持 | [命令]未探究 | [命令]未探究 |
? | 反向查找 | 命令模式 | [命令]不支持 | [命令]未探究 | [命令]未探究 |
n | 下一个查找命中 | 普通模式 | [普通]支持 | [普通]未探究 | [普通]未探究 |
N | 下一个反向查找命中 | 普通模式 | [普通]支持 | [普通]未探究 | [普通]未探究 |
*和# | 基于光标当前所在的单词作匹配,移动光标到下一个(或上一个)匹配单词(*是下一个,#是上一个,支持循环) | 普通模式 | [普通]支持 | [普通]未探究 | [普通]未探究 |
:%s/from/to/gc | 全局替换,替换前询问 | 命令模式 | [命令]不支持 | [命令]Range操作 | [命令]未探究 |
1.5、书签跳转
操作 | 简单描述 | 适用模式 | 是否支持重复执行N次操作 | 限定范围形式 | 是否支持文本对象 |
---|---|---|---|---|---|
m<NAME> | 定义名为“NAME”的书签 | 普通模式,可视模式 | [普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
‘<NAME> | 跳转到名为“NAME”的书签指向行 | 普通模式,可视模式 | [普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
`<NAME> | 跳转到名为“NAME”的书签指向字符 | 普通模式,可视模式 | [普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
[普通]未探究 [可视]未探究 |
:marks | 查看所有书签 | 命令模式 | [命令]不支持 | [命令]未探究 | [命令]未探究 |
备注:
名为a-z
的书签不支持跨文件跳转,名为A-Z
的书签支持跨文件跳转,其他名称的书签不作探究。
1.6、文本对象操作
操作 | 简单描述 | 适用模式 | 是否支持重复执行N次操作 | 限定范围形式 |
---|---|---|---|---|
aw | 选取一个单词 | 可视模式,普通模式中置于另外一个操作后面(比如daw) | [普通]支持 [可视]支持 |
[普通]未探究 [可视]未探究 |
as | 选取一个句子 | 可视模式,普通模式中置于另外一个操作后面(比如das) | [普通]支持 [可视]支持 |
[普通]未探究 [可视]未探究 |
ap | 选取一个段落 | 可视模式,普通模式中置于另外一个操作后面(比如dap) | [普通]支持 [可视]支持 |
[普通]未探究 [可视]未探究 |
a] | 选取一个[]结构 | 可视模式,普通模式中置于另外一个操作后面(比如da]) | [普通]支持 [可视]支持 |
[普通]未探究 [可视]未探究 |
a) | 选取一个()结构 | 可视模式,普通模式中置于另外一个操作后面(比如da)) | [普通]支持 [可视]支持 |
[普通]未探究 [可视]未探究 |
a} | 选取一个{}结构 | 可视模式,普通模式中置于另外一个操作后面(比如da}) | [普通]支持 [可视]支持 |
[普通]未探究 [可视]未探究 |
a> | 选取一个<>结构 | 可视模式,普通模式中置于另外一个操作后面(比如da>) | [普通]支持 [可视]支持 |
[普通]未探究 [可视]未探究 |
at | 选取一个<xxx></xxx>结构 | 可视模式,普通模式中置于另外一个操作后面(比如dat) | [普通]支持 [可视]支持 |
[普通]未探究 [可视]未探究 |
a” | 选取一个””结构 | 可视模式,普通模式中置于另外一个操作后面(比如da”) | [普通]不支持 [可视]不支持 |
[普通]未探究 [可视]未探究 |
a’ | 选取一个’’结构 | 可视模式,普通模式中置于另外一个操作后面(比如da’) | [普通]不支持 [可视]不支持 |
[普通]未探究 [可视]未探究 |
a` | 选取一个``结构 | 可视模式,普通模式中置于另外一个操作后面(比如da`) | [普通]不支持 [可视]不支持 |
[普通]未探究 [可视]未探究 |
备注:
另外还有“i(w,s,p,],),},>,t,”,’,`)”,它与“a(w,s,p,],),},>,t,”,’,`)”大同小异。
1.7、文件
操作 | 简单描述 | 适用模式 | 是否支持重复执行N次操作 | 限定范围形式 | 是否支持文本对象 |
---|---|---|---|---|---|
:w | 保存 | 命令模式 | [命令]未探究 | [命令]未探究 | [命令]未探究 |
:w! | 强制保存 | 命令模式 | [命令]未探究 | [命令]未探究 | [命令]未探究 |
:q | 退出 | 命令模式 | [命令]未探究 | [命令]未探究 | [命令]未探究 |
:q! | 强制退出 | 命令模式 | [命令]未探究 | [命令]未探究 | [命令]未探究 |
:wq | 保存并退出 | 命令模式 | [命令]未探究 | [命令]未探究 | [命令]未探究 |
1.8、环境
操作 | 简单描述 | 适用模式 | 是否支持重复执行N次操作 | 限定范围形式 | 是否支持文本对象 |
---|---|---|---|---|---|
:set number/nonumber | 显示/取消显示行号 | 命令模式 | [命令]未探究 | [命令]未探究 | [命令]未探究 |
:set list/nolist | 显示/取消显示特殊字符 | 命令模式 | [命令]未探究 | [命令]未探究 | [命令]未探究 |
:set ic/noic | 在查找时,不区分/区分字母大小写 | 命令模式 | [命令]未探究 | [命令]未探究 | [命令]未探究 |
1.9、功能
操作 | 简单描述 | 适用模式 | 是否支持重复执行N次操作 | 限定范围形式 | 是否支持文本对象 |
---|---|---|---|---|---|
ga | 显示光标所在字母的ASCII编码值,表示形式有十进制,十六进制和八进制 | 普通模式 | [普通]未探究 | [普通]未探究 | [普通]未探究 |
Ctrl+p或者Ctrl+n | 在插入模式下,在你输入单词的开头字符后,通过Ctrl+p 或者Ctrl+n 快捷键可获得自动补全选项(自动补全数据基于所在文件生成) |
插入模式 | [插入]未探究 | [插入]未探究 | [插入]未探究 |
gt | 跳转到右侧一个标签页 | 普通模式 | [普通]不支持 | [普通]未探究 | [普通]未探究 |
gT | 跳转到左侧一个标签页 | 普通模式 | [普通]不支持 | [普通]未探究 | [普通]未探究 |
:sp | 水平分割 | 命令模式 | [命令]未探究 | [命令]未探究 | [命令]未探究 |
:vsp | 垂直分割 | 命令模式 | [命令]未探究 | [命令]未探究 | [命令]未探究 |
:q | 在分屏环境中,退出当前分屏 | 命令模式 | [命令]未探究 | [命令]未探究 | [命令]未探究 |
Ctrl+w h/l/k/j | 分别表示跳到左侧/右侧/上侧/下侧分屏 | 普通模式 | [普通]未探究 | [普通]未探究 | [普通]未探究 |
1.10、限定范围操作
1.10.1、“Range操作”形式
“Range”表示一个行范围,可以是单行。表示由“数字,特殊字符,书签,查找结果”元素构成。
示例如下。
行范围 | 描述 | 例子 |
---|---|---|
21 | 行21 | :21s/old/new/g |
1 | 行1 | :1s/old/new/g |
$ | 最后一行(注意,虽为同一个字符,上述体系中“$”表示最后一个字符,这里体系中“$”表示最后一行) | :$s/old/new/g |
. | 当前行 | :.w single.txt (把当前行的内容写到文件“single.txt”) |
% | 所有行,等价于“1,$” | :%s/old/new/g |
21,25 | 行21到行25 | :21,25s/old/new/g |
21,$ | 行21到最后一行 | :21,$s/old/new/g |
.,$ | 当前行到最后一行 | :.,$s/old/new/g |
.+1,$ | 当前行的下一行到最后一行 | :.+1,$s/old/new/g |
.,.+5 | 当前行到第6行 | :.,.+5s/old/new/g |
‘<,’> | 选取行范围(本质上也是书签指定的行范围,详细可参见“2.1、模式”小节) | :'<,'>s/old/new/g |
‘a,’b | 书签a到书签b指定的行范围 | :'a,'bd |
.,’b | 当前行到书签b指定的行范围 | :.,'bd |
.,/BODY/ | 当前行到接下来第一次包含“BODY”的行范围 | .,/BODY/d |
1.10.2、“操作End”形式
“End”表示操作范围的一端,另外一端为当前光标所在位置。当“End”表示“行”范畴时,范围为“行到行”;当“End”表示“字符”范畴时,范围为“字符到字符”。
比如:
1 | y0:从行首开始复制(字符范畴) |
特别需要注意的是:
1、“ggguG”和“gggUG”逻辑上都分为两部分:gg和guG(gUG),而不是一个独立的整体从而被进一步误以为出现了“Start操作End”的限定范围操作形式
2、书签跳转语境中,“`a”是字符范畴,“’a”是行范畴
1.11、跳转操作
跳转行为包括:gg,G,NG,书签跳转等。
可通过:jumps
查看跳转记录列表,小三角所指跳转记录表示当前所处跳转记录,如果小三角所指跳转记录为空行,表示还未有跳转记录。
Ctrl+o是跳转回退,相应的小三角往上移动,Ctrl+i是跳转前进,相应的小三角往下移动。
1.12、宏操作
录制宏:录制一系列动作,以备重复执行。
录制宏具体步骤如下:
1 | 按下q{0-9a-zA-Z"}开始录制,{0-9a-zA-Z"}为宏录制目的寄存器名字 |
通过@{0-9a-zA-Z"}
执行指定宏,支持“重复执行N次操作”。
二、几个概念
2.1、模式
Vim编辑器提供多种模式,常见的模式有4种:普通模式,可视模式,插入模式,命令模式。
模式名称 | 描述 |
---|---|
普通模式 | 日常模式 |
可视模式 | 主要用于选取内容供后续操作,选取完成后本质上是划定了一个限定范围 |
插入模式 | 主要用于插入数据 |
命令模式 | 主要用于执行命令 |
备注:
1、本质上,可视模式中选取时定义了两个特殊的书签,书签表示位置范围对应于选取限定范围,这两个特殊书签分别为:“<”和“>”,“<”对应于“限定范围开头”,“>”对应于“限定范围结尾”,因此'<
和'>
分别指向限定范围第一行和最后一行,`<
和`>
分别指向限定范围开头字符和结尾字符
2.2、重复执行N次操作
在操作前辅以一个表示数字的“N”,表示“重复执行N次操作”。需要注意的是,“NG”中的“N”并不是这个含义。
比如:
1 | 4h:执行4次h操作,即向左移动4个字符 |
五、常见需求实现
5.1、快速选中Java方法
快速选中Java方法步骤描述如下:
1、光标定位到方法定义首行,即具有方法名称的行
2、按下^
字符,定位到所在行行首第一个非空字符
3、按下v
字符,进入可视模式
4、按下/{<Enter>
字符组合,查找到第一个“{”字符
5、按下%
字符,查找到与上述“{”字符匹配的“}”字符,完成选中
根据上述描述,我们可在“.vimrc”配置文件中,通过如下语句配置快捷键“cm”:
1 | nmap cm ^v/{<CR>% |
5.2、Java源文件中快速定位到类名
Java源文件中快速定位到类名步骤描述如下:
1、按下gg
,光标定位到文件首行
2、按下/^public<Enter>
字符组合,查找到第一个“public”字符串,且该字符串位于行首
3、按下f{
字符组合,找到右侧第一个“{”字符
4、按下?class\|interface\|enum<Enter>
字符组合,向后找第一个“class/interface/enum”字符串
5、按下w
字符,定位到右侧类名
根据上述描述,我们可在“.vimrc”配置文件中,通过如下语句配置快捷键“cc”:
1 | nmap cc gg/^public<CR>f{?class<Bslash><BAR>interface<Bslash><BAR>enum<CR>w |
5.3、去掉Windows文件中的^M符号
去掉Windows文件中的“^M”符号的命令如下:
1 | %s/^M//g |
如果想生成“^M”符号,可用Ctrl-v Ctrl-m
命令。
5.4、剪切
进入可视模式后,选取内容,按下x
或者d
字符,然后在目的地按下p
字符完成剪切,以上过程能够完成剪切的根本原因是:x
和d
操作在删除内容之前会在寄存器复制一份内容,p
操作会从寄存器复制粘贴内容。
5.5、g命令
删除所有以“#”字符开头的行:
1 | :g/^#/d |
删除所有空行:
1 | :g/^$/d |
**参考文献:** [1]:help mark-motions [2]:help text-objects [3]:help q [4]:help jumps [5]:help various-motions [6]https://zh.wikipedia.org/wiki/Vim [7]http://vim.wikia.com/wiki/Ranges [8]http://www.cnblogs.com/abeen/archive/2010/07/28/1786594.html [9]https://www.maketecheasier.com/vim-keyboard-shortcuts-cheatsheet/ [10]https://www.fprintf.net/vimCheatSheet.html [11]https://gist.github.com/awidegreen/3854277 [12]https://coolshell.cn/articles/5426.html