vim 命令
Vim 的几种模式
Vim 和普通的编辑器有一点非常大的区别,或者是是本质的区别:Vim 是有不同的模式(状态)的
。
普通的编辑器,你一打开就可以进行输入(打字)了,很符合直觉,打开就会用,就好像使用 Word 一样。
但是 Vim 和他们不一样,你打开 Vim 之后,是处于一种无法编辑的状态中的,这是 Vim 的普通模式,在这种状态下,你是无法输入文字的,只能执行一些指令。
在普通模式(默认模式)下,你可以使用 h,j,k,l
这几个按键来移动光标,这四个键分别代表 左,下,上,右。
如果想输入文字,你需要按下键盘上的 i
键,才能进入可编辑的状态,即 Vim 的插入模式,才能像使用普通编辑器一样打字。
可以说,正是由于 Vim 有不同的模式,才使得 Vim 的编辑效率远超其他编辑器。
模式是 Vim 的基础,这里有必要先介绍一下 Vim 的几种模式。
Vim 五种模式:
- 普通模式 / 默认模式:执行 Vim 的指令,如移动光标,复制 / 删除 / 粘贴文本等等,不能进行输入(打字).
- 插入模式 / 编辑模式:进行文本输入(打字), 和普通编辑器一样
- 替换模式:进行字符替换
- 可视模式 / 选择模式:进行文本选择
- 命令模式:在 Vim 底部最后一行中输入命令,按回车并执行
接下来介绍以下 如何进入 / 退出这几种状态,我会把所有方式都列举出来,但是现在你只需使用最简单的一种方式即可。
在开始之前,请连续按几次 Esc 键,保证你处于普通模式
无论你现在在任何模式下,按 Esc 键可以让你回到普通模式,这句话一定要记牢!遇事不决 Esc!
普通模式 > 插入模式
要从普通模式进入插入模式,最简单的方法就是按 i
键,你可以理解为 "insert"
. 按过 i
键之后,你就可以打字了。
除此之外,你还可以:
i/I
: 在光标前面 / 行首插入a/A
: 在光标后面 / 行尾插入o/O
: 在下 / 上一行行首插入- 在插入模式下按
Ctrl-o
可进入普通模式,在此模式下可以运行一次普通模式命令,然后就又回到插入模式。
在继续学习之前,请先输入一些文本(最好是英文), 以供后续的操作使用。
另外,如果操作过程中,你不知道自己处于什么模式了,那就连续按几次 Esc, 回到普通模式,再继续进行操作。
普通模式 > 替换模式
在普通模式下,按 r
键(小写)可进入替换模式,你可以理解为"replace"
. 此时你再次输入的字符,可以替换光标处的那个字符。
如果你想连续替换多个字符,则按 R
键(大写,即 Shift+r), 此时你的输入会不断地替换光标处的字符。
想退出持续替换模式,按 Esc 即可。
除此之外,你还可以:
- 数字 r: 将光标所在向后 n 个字符都替换掉,例如 3rs 可以把光标向后的三个字符都替换成 s
- 在持续替换模式中可使用 Insert 键在持续替换模式和插入模式中切换
普通模式 > 可视模式
在普通模式下,按 v
键可进入可视模式(选择模式), 你可以理解为"visual"
. 进入可视模式后,你可以选择一些文本,此时你使用 h,j,k,l
键,可以改变选择的区域,
当你选择了一些文本后,可以使用一些执行操作你选择的文本,这个后面再介绍。
要退出可视模式,按 Esc
键或者 v
键。
除此之外,你还可以:
- V: 进入行选择模式,整行整行地进行选择
- Ctrl-q: 进入块选择模式。在这个模式下,你可以以"块" 或者说 “列” 的方式选择文本。本来快捷键是 Ctrl+v, 但是在 Windows 上,Vim 会模仿 Windows 快捷键,Ctrl-v 是粘贴,所以使用 Ctrl-q 进入块选择模式。
普通模式 > 命令模式
在普通模式下,按 :
键(即 Shift+;
) 即可进入命令模式,此时光标会跑到编辑器的最底部;
你可以输入一些命令,按回车执行,执行完命令之后自动回到普通模式,或者你可以直接按 Esc 回到普通模式。
其他模式 > 普通模式
任何模式下,你都可以按 Esc 回到普通模式,一次不行就多按几次,遇事不决 Esc.
OK, 现在你想一下记住这么多模式以及进入方法,肯定是比较困难的。
这里说一下,Vim 不是学会的,是用会的。
与其学怎么操作,不如按照教程自己多做几次,多用几次自然就记住了,不用担心把 Vim 折腾坏了,大不了重装。
普通模式
接下来我们就来学学普通模式下的一些指令。
普通模式是进入 Vim 后的默认模式,在这种模式下,无法输入,只能移动光标或对文本进行操作。
在进行下面的操作之前,请先保证你输入了一定量的文本(请一定保证是英文,中文会遇到一些小情况,影响效果).
另外,下面的指令非常多,不可能背下来,要通过"用"去记忆。
移动
- h/j/k/l: 左 / 下 / 上 / 右移动,这几个键就在你的右手手指下,很方便。h 在最左边,表示向左,l 在最右边,表示向右,j 像个向下的箭头,表示向下,k 则是向上。多用用,自然可以记住。
- 数字 h/j/k/l: 左 / 下 / 上 / 右移动 n 下,n 为输入的数字,例如 3l 表示向右移动 3 次,3j 表示向下移动三行
- w: 移动到下一个单词开头。同上,也可以在前面加数字来重复多次,例如
- e: 移动到当前或下一个单词结尾
- ge: 移动到上一个单词结尾
- b: 移动到当前或上一个单词开头
- f/t: 在当前行,移动到下一个出现某字符的位置 / 前,例如 fa, 光标会移动到下一个字母 a 的位置
- F/T: 在当前行,移动到上一个出现某字符的位置 / 前,例如 Fa, 光标会移动到上一个字母 a 的位置
- 数字 f/t: 在当前行向后移动到第 n 次出现 a 的位置 / 前,例如 3fa, 光标会向后移动到第三次出现字母 a 的位置
- 数字 F/T: 在当前行向前移动到第 n 次出现 a 的位置 / 前,例如 3Fa, 光标会向前移动到第三次出现字母 a 的位置
- 0/$: 光标移动到行首 / 行尾
- ^: 光标移动到到非空格的行首
- %: 在两个匹配的符号 (, “, { 等等中切换,光标需先移动到其中一个符号,如果不在,则会向后找到最近的一个
- gg: 光标移动到第一行行首
- G: 光标移动到最后一行行首
- 行号 G: 光标移动到对应行号行首
- 数字 %: 光标移动到指定百分比的文档位置,例如 80%, 光标会移动到文本的 80% 处
- {/}: 光标移动到上一段 / 下一段 (Paragraph) 的行首
- g;/g,: Vim 内部维护着一个编辑位置历史,使用这两个指令可在编辑位置历史中跳转。
- H: 光标移动到当前屏幕的最上边 (High)
- M: 光标移动到当前屏幕的中间 (Middle)
- L: 光标移动到当前屏幕的最下边 (Low)
- zt/zb/zz: 把当前行置为屏幕正顶部 / 底部 / 中间
- ``: 在两次 非行内移动 的位置之间跳转,例如你现在在第一行,使用 G 到达文件末尾,此时按``, 就可以回到第一行,另外注意,这个指令只能在非行内的移动之间跳转,如果你的上一次移动是行内移动,则无效
- J: 将下一行移动到这一行末尾(合并当前行和下一行)
注意:数字 + 指令表示执行多次指令,数字一般放在指令之前,很多指令前面都可以加数字,这个技巧很重要。
复制
在普通模式下,可以进行文本的复制,剪切和粘贴,这里要注意的是,在 Vim 中,剪切和删除的表现效果是一样的,剪切或删除的文本都会进入到 Vim 的寄存器里(寄存器是什么鬼,以后会讲).
- y: 开始复制
- yy/Y: 复制当前行
- 数字 yy: 从当前行开始,复制多行,例如:3yy 表示复制三行。
- yh/yl: 向左 / 向右复制一个字符,即 y 指令后面可以跟"移动指令”
- y0/y$: 从光标处复制到本行开头 / 末尾
- yw/ye: 复制一个单词,或从光标处复制到本单词末尾
- yt: 从光标处开始复制,直到遇见某字符。例如 yta, 表示从光标处开始复制,直到遇见 a, a 不复制,同理可使用 yf, yF, yT
- yG: 从当前行开始复制直到最后一行
- ygg: 从当前行开始复制直到第一行
剪切
- d: 开始剪切,之后仍留在普通模式,其用法和 y 类似,请自行尝试
- D: 从光标处开始剪切,直到行尾
- x: 剪切光标所在的字符,之后仍留在普通模式
- 数字 x: 剪切从光标开始往后的 n 个字符,之后仍留在普通模式,例如 3x, 表示向后剪切 3 个字符
- X: 剪切当前光标左边的字符
- 数字 X: 剪切从光标开始往前的 n 个字符,之后仍留在普通模式,例如 3X, 表示向前剪切 3 个字符
- c 开始剪切,之后进入插入模式,用法和 d 类似,请自行尝试
- 数字 c: 剪切从光标开始往后的 n 个字符,并进入插入模式
- C 剪切至行尾,并进入插入模式
- s 剪切光标所在字符,并进入插入模式,和 x 类似
- S 剪切当前行,并进入插入模式
粘贴
- p: 将复制 / 剪切的内容粘贴到光标后面,如果复制 / 剪切的内容是整行的,则粘贴到当前行的下面
- P: 将复制 / 剪切的内容粘贴到光标前面,如果复制 / 剪切的内容是整行的,则粘贴到当前行的上面
- 数字 p/P: 粘贴多次
- ddp: 其实就是剪切当前行再粘贴了,但是你会发现,当前行和下一行换位置了
- xp: 其实就是剪切当前光标所在字符再粘贴,但是你会发现,两个字符交换位置了
注意:几乎所有的移动,复制,粘贴命令前面都可以加数字,表示重复的次数,复制和剪切指令也几乎都可以加上移动指令,表示向某个方向复制 / 剪切。
查找
在普通模式下输入 /
, 即可对当前文件进行文本查找。
- /xxx: 在全文中查找 xxx, 并高亮显示,字符
.*[]^%/?~$<>
等有特殊意义,需要用 \ 转义 - ?xxx: 和 / 效果一样,只是查找方向反向
- N/n: 在查找到的高亮位置之间前后切换,前面可以加数字,表示第 n 次出现的位置
/\\<xxx\\>
: 匹配完整的单词,如果某单词中只是包含 xxx, 则不会被匹配上,由于 > 有特殊含义,所以需要转义,由于 \ 也有特殊含义,需要二次转义。..#/*
: 在某个单词上使用这两个指令,可以移动到上一个 / 下一个与光标所在单词相同的单词上,同时高亮所有相同单词,这个指令很有用
PS. Vim 会记录已经查找过的内容,再次查找时,可通过上下键来切换之前的输入 注意:一个有用的命令:nohlsearch, 此命令可以取消当前的查找的高亮,简写 nohl
文本操作
在普通模式下,可以使用如下指令进行简单的文本操作:
>>/<<
: 当前行向右 / 向左缩进一个 Tab行号 1 行号 2 >>
: 从行号 1 到行号 2 向右缩进一个 Tab行号 1 行号 2 <<
: 从行号 1 到行号 2 向左缩进一个 Tab- gU/gu/g~: 将选中的内容转化为大 / 小写 / 大小写切换
- u: u 指令可以对之前的操作进行 Undo, 即撤销操作
- Ctrl-r: Ctrl-r 这个快捷键可以对之前的操作进行 Redo, 即撤销上次撤销。
其他
.
: 普通模式中按 . (即句号键)可以重复上次的指令,除了 u 指令。除此之外,从进入插入模式开始,到回到普通模式为止,这个过程中发生的所有操作 也可以使用 . 来回放。. 本质上是一个"宏"(什么鬼,后面会详细讲"宏").ZZ
: 退出当前的文件。我在查看不可编辑的文件时,经常用这个指令退出文件,比如 git log.
可视模式
普通模式中按 v 键可进入可视模式(选择模式), 按 Esc 或 v 退出,选择过程中可使用普通模式的移动指令改变选择区域,选择之后可以对选择的内容进行复制 / 删除等操作。
普通模式中按 V 键进入整行可视化选择,再按 Esc/V 退出,以"行"为单位进行选择。
可视模式下的一些技巧:
- o: 在可视化选择模式下,使光标移动到选择区域的另一头
- O: 在块可视化选择模式下,使光标移动到这一行的另一头
- gg, 然后 vG, 就可以全选。
- Ctrl-q: 块可视化选择,其实应该是 Ctrl-v, 但是对于 Windows 的 gVim, Ctrl-v 是粘贴,所以改为 Ctrl-q.
- gg, 然后 Ctrl-q(Ctrl-v), 然后按 G, 就可以选择文本的第一列
命令模式
在普通模式下按 : 进入命令模式,可以执行一些 Vim 命令,也可执行系统命令。
在我这系列 Vim 的文章中,我会将普通模式下的操作称之为 “指令”, 而命令模式下的操作称之为 “命令”,
虽然在英文中,它们都是 “command”, 但是我这里还是想区分开来,以后我只要说 “指令”, 指的就是普通模式的操作,而 “命令”, 指的就是命令模式下的操作。
常用命令
:w
: 保存当前文件,但不退出。注意,如果你是直接打开 Vim, 然后开始编辑,你是无法直接使用 w 命令保存的,Vim 会提示你没有文件名,要解决这个问题,你需要在 w 命令后面跟上一个路径及文件名,比如::w d:/temp/test.txt, 这样你才能保存当前文件。这就好比你在其他编辑器里新建个文件,当你要保存时,其他编辑器会弹一个对话框,让你选择保存路径,只是 Vim 把这个过程命令化了。:q
/:q!
: 退出 / 强制不保存退出,在任何命令后加 ! 表示强制执行此命令。:wq
: 保存并退出当前文件:e!
: 放弃所有修改,载入文件的初始状态,慎用!:pwd
: 显示当前目录:行号
:定位到对应行号,例如 :20 可定位到第 20 行,和普通模式下的 20G 效果一样。行号1,行号2 d
: 删除从行号 1 到行号 2 的内容,例如::3,5 d 表示删除第 3 行到第 5 行,y 指令也同样适用。行号1,行号2 >>
: 从行号 1 到行号 2 向右缩进一个 Tab, 同理,也可以向左缩进:! shell 指令
:执行 shell(dos) 指令,例如::! ipconfig- :
r! shell 指令
:将 shell(dos) 指令的执行结果写到当前行的下面
PS: 在命令模式里按上下箭头可以切换之前输入的命令
替换命令
在普通模式下,按 /
可以进行查找操作,在命令模式下,可使用一些替换命令,将查找到的文本的进行替换。
替换的基本表达式 [range]s/from/to/[flags]
, 表示将 range 范围的 from 替换成 to, flags 表示替换范围。替换指令使用起来很复杂,暂时不需要掌握。
:%s/aaa/bbb/g
: 把全文中的所有 aaa 替换成 bbb, %s 表示全部行 (range), g 表示所有匹配的 (flags):s/aaa/bbb/
: 把当前行的第一个 aaa 替换成 bbb, s 表示当前行 (range), 不指定 flag 就只替换第一个:行号 1, 行号2s/aaa/bbb/g
: 把行号 1 和行号 2 之间的 aaa 替换成 bbb.:行号 1, 行号2s/^/aaa/g
: 把行号 1 和行号 2 之间的行前面都加上 aaa(即可以使用正则,^ 表示行首):行号 1, 行号2s/^/\/\//g
: 从行号 1 和行号 2 之间的行都加上 // 注释 (/ 需要转义):行号 1, 行号2s/\/\//g
: 从行号 1 和行号 2 之间的行都去掉 // 注释
PS. 在替换命令中 . 代表当前行,$ 表示最后一行
参考:https://juejin.im/post/5cf4e91ff265da1bc14b1387