Vim 是一种多模式的编辑器,不同于一般的编辑器进入便是编辑模式,可以在编辑模式下对文本进行各种编辑,Vim 进入之后是在普通模式 (Normal mode) 下,需要通过不同的按键进入不同的编辑模式。在《Vim 使用技巧》这本书中,作者有一个非常贴切的比喻,如果画布之于画家,那么 Vim 之于程序员,画家在画布上真正作画的时间必然不应该,也不会超过一半时间,在真正落笔之前,画家可能会构图,调整光线,配置画笔颜色等等操作,等一切准备就绪之后再在画布上作画。Vim 这款编辑器的原理也大致如此,大部分的时间我们都会在 normal mode(普通模式) 下,进行浏览,移动光标等等,而真正要进入编辑的时候再切到 insert mode,进行文本编辑。

当然 Vim 还有其他,比如可视模式,选择模式,命令模式等等其他模式,在不同的场合使用。当你熟悉了这些常用的编辑模式之后,可能就再也回不到无模式的编辑了。因为这些模式的划分,使得不同模式下专注于该模式的使用方式,结果便使得每一种模式下对文本编辑的效率都要远远超出于无模式编辑器。

基本模式

普通模式 Normal mode

和大多数无模式编辑器不同,Vim 默认启动就是普通模式,在该模式下不能够像普通编辑器一样可以插入编辑。在普通模式中,用户可以执行一般的编辑器命令,比如移动光标,删除文本等等。这也是 Vim 启动后的默认模式。这正好和许多新用户期待的操作方式相反 (大多数编辑器默认模式为插入模式)。

在 《Practical Vim》书中,作者将 Vim 比喻为画板,使用 Vim 的用户比喻为画家,你想想画家用了多长时间用笔刷在画板上画画?画家可能在落笔之前会花很长时间研究绘画的对象,调整光线,混合颜料,等等,当真正落笔的时候也不一定是使用画笔,也可能使用调色刀来给画面增加纹理,或者使用棉棒来优化画面。画家并不依赖着画笔休息,对于 Vim 同理,画家花费零碎的时间绘画,programmers 同样花费零散的时间编写代码。更多的时间用来思考,阅读和浏览。当真正需要调整代码时,也不一定是插入,也可能是重新格式化代码,复制,移动,删除等等,在 Normal Mode 下有很多方法可以使用 (at our disposal)。

Vim 强大的编辑能力中很大部分是来自其普通模式命令。普通模式命令往往需要一个操作符结尾。例如普通模式命令”dd”删除当前行,但是第一个”d”的后面可以跟另外的移动命令来代替第二个”d”,比如用移动到下一行的”j”键就可以删除当前行和下一行。另外还可以指定命令重复次 数,”2dd”(重复”dd”两次),和”dj”的效果是一样的。学习了各种各样的文本间移动/跳转的命令和其他的普通模式的编辑命令,并且能够灵活组合使用的话,能够比那些没有模式的编辑器更加高效的进行文本编辑。

在普通模式中,有很多方法可以进入插入模式。比较普通的方式是按”a”(append/追加,光标移动到行尾并进入插入模式)键或者直接使用”i”(insert/插入)键进入。

插入模式 Insert mode

插入模式最好理解,在这个模式下用户输入的任何字符都会直接出现在编辑器中,这是大多数文本编辑器的默认模式,也是大多数新用户希望文本编辑器编辑过程中保持的模式。

在普通模式下按下 “i” 键进入,在这个模式中,大多数按键都会向文本缓冲中插入文本。但是 Vim 的设计哲学告诉我们,只有在真正输入文本的时候进入该模式,否则立即按下 ESC 退出到普通模式。

在插入模式中,可以按 ESC 键回到普通模式。

从普通模式切换到插入模式有非常多的方式,最简单最直白的便是上面提到的 i 键,直接进入插入模式,但实际上你可以用 A 将光标直接跳到行尾,再进入插入模式,或者使用 I 跳转到行首再直接进入插入模式。在之后的文章中会提到更多的切换方式,这里只需要记住从普通模式切换到插入模式的方式有非常多样的选择,如何选择切换的方式也会非常重要。

可视模式 Visual mode

Vim 的可视模式让用户可以选择一些文本,并在上面进行一些操作。这个模式大部分的编辑器也同样拥有,但是 Vim 的可视模式则有一些非常的不同,Vim 拥有三种不同类型的 Visual mode,分别操作字符,行,和块。

在普通模式下按下 “v” 键进入,使用“V”可按行选择,这个模式与普通模式比较相似。但是移动命令会扩大高亮的文本区域。高亮区域可以是字符、行或者是一块文本。当执行一个非移动命令时,命令会被执行到 这块高亮的区域上。Vim 的”文本对象”也能和移动命令一样用在这个模式中。

  • v命令进入的字符可视化模式(character-wise visual mode)。文本选择是以字符为单位的。
  • V命令进入的行可视化模式(line-wise visual mode)。文本选择是以行为单位的。
  • Ctrl-V进入的块可视化模式(block-wise visual mode)。可以选择一个矩形内的文本。(注意:在 Windows 中,Ctrl-V可能已经被影射为粘贴操作,可以使用Ctrl-Q进入块可视化模式。)

简单的记住,v 是通向可视模式的大门,上面的每一个操作都可以和 count 结合使用,比如要选择 104 行内容,可以直接 104V

  • [count]v
  • [count]V
  • [count]Ctrl-v

另外一相关的是 gv 表示选择上一次选中的区域。因此也能看到 v 键是 Visual mode 的入口了。可视模式一般有一个固定的开始,一个可以自由移动的结束符,在 Visual mode 中可以使用 o 来在开头和结尾之间切换。

在 Vim 中使用如下命令查看更多官方帮助

:h 04.4

选择模式 Select mode

这个模式和无模式编辑器的行为比较相似(Windows 标准文本控件的方式)选中内容之后敲击其他按键会直接删除选中内容并输入敲击的内容。选择模式与可视模式相似,这个模式中,可以用鼠标或者光标键高亮选择文本,不过输入任何字符的,Vim 会用这个字符替换选择的高亮文本块,并且自动进入插入模式。选择模式更多在 MS-Windows 中用到,其他系统如需启动选择模式,首先需要激活:

:set selectmode+=mouse

如果熟悉 Vim 的模式特征,那么应该很少会用到选择模式,这一模式的存在,只是为了迎合那些想要让 Vim 更像其他编辑器的用户。

在 Vim 中使用如下命令查看更多官方帮助

:h 09.4

选择模式和可视模式在状态栏提示符有差别,可视模式会显示 -- VISUAL -- 而选择模式则是 -- SELECT --。 在这两个模式下可以使用 Ctrl-g 来在可视模式和选择模式之间切换,切换的时候能看到下方 -- VISUAL ---- SELECT -- 切换。

命令行模式 Command line mode

Vim 可以追溯到 Vi,也就是那个时候产生了现在的多模式的编辑器。而依次追寻下去,vi 可以追溯到他的祖先,行编辑器 ex,所以这也就是为什么现在 Vim 中还保留这 ex 命令。那些原始 Unix 文本编辑器的 DNA 被保留到了现代的 Vim 中。对于一些面向行的编辑任务, Ex 命令依然是执行这些任务的最好工具。

因为历史原因,在命令行模式中执行的命令又被称为 Ex 命令。Ex 命令可以包括搜索,或者一个表达式,或者操作 buffer 等等。

在命令行模式中可以输入会被解释成并执行的文本。例如执行命令(:键),搜索(/?键)或者过滤命令(!键)。在命令执行之 后,Vim 返回到命令行模式之前的模式,通常是普通模式。当输入 : 之后 Vim 就进入了 Command Line mode。

Ex Commands That Operate on the Text in a Buffer

命令 解释
:[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} 在指定行执行 normal 模式下命令
:[range]substitude/{pattern}/{string}/[flags] 在指定行中用 string 替换匹配 pattern 的内容
:[range]global/{pattern}/[cmd] 在匹配 pattern 的所有行中执行 Ex 命令 cmd

其他

  • 读写文件 :edit:write
  • 创建新标签页 :tabnew
  • 分割窗口 :split
  • 操作参数列表 :prev/:next
  • 缓冲区列表 :bprev/:bnext
  • 替换,比如使用 :%s/a/b/g 将文本中所有的 a 替换成 b。
  • 搜索 /abc 来搜索文本中的 abc 字符串

Vim 为几乎所有功能功能都提供了 Ex 命令,参考 :h ex-cmd-index点击查看所有 Ex 命令

Ex 模式

这和命令行模式比较相似,在使用”:visual”命令离开 Ex 模式前,可以一次执行多条命令。我至今没用过,如果需要 Google 关键词:Vim Ex 模式。

普通模式下按 Q 进入 Ex 模式,多行 Command Line 模式

派生模式

Normal, Insert, Visual 模式都是显而易见,顾名思义的。但是 Vim 中存在一些模式经常会被忽视,在日常使用中可能经常会用到,经常一闪而过,所以我们可能根本没有意识到。

操作符等待模式 Operator-pending mode

比如操作符等待模式,比如当我们执行命令 dw 时,在按下 dw 两个按键中间短暂的时间就是操作符等待模式。

所以操作符等待模式指的是普通模式中,执行一个操作命令后 Vim 等待一个”动作”来完成这个命令这个时间的模式。当我们把 Vim 想象为有限状态机,那么操作符等待模式就是在只接受 motion 命令的那个状态。当 operator 命令被按下该模式就被激活,此时没有任何事情发生,直到提供一个 motion,完成一整个操作。

这边提及的 Operator 和 Motion 在后面的文章中会经常提及,这边先简单介绍,Vim 支持命令组合,比如 daw 表示的是 delete a word 那么这里的 d 是 Operator 而 aw 是 Motion

Operator + Motion = Action

Vim 自带 Operator

Vim 也支持在操作符等待模式中使用”文本对象”作为动作, 包括”aw”一个单词(a word)、”as”一个句子(a sentence)、”ap”一个段落(a paragraph)等等。

比如,在普通模式下”d2as”删除当前和下一个句子。在可视模式下”apU”把当前段落所有字母大写。

有一些 Operator 有多个按键比如 g 开头 z 开头 Ctrl-W[ 这些按键第一个按键不会进入操作符等待模式。

插入普通模式 Insert Normal mode

对于初学者来说,经常在切换模式间变得疲惫,但是通过练习一切都会变得自然。但是 Vim 的模式在一种特殊场景下会显得笨拙:当在插入模式下,想要执行一条 Normal 模式命令,然后继续在 Insert 模式下编辑。Vim 提供了一个利落的解决方法来消除这一类的问题,这就是插入普通模式 Insert Normal mode。

插入普通模式是一种特殊的 Normal mode,这种模式下只给我们执行一次命令的机会,执行结束后就返回到 Insert mode。这个模式是触发的条件:在插入模式下按下 Ctrl-o 键的时候进入,这时暂时进入普通模式,执行完一个命令之后,Vim 返回插入模式

插入可视模式

这个模式是在插入模式下按下 ctrl-o 键并且开始一个可视选择的时候开始。在可视区域选择取消的时候,Vim 返回插入模式。

插入选择模式

通常这个模式由插入模式下鼠标拖拽或者 shift 方向键来进入。当选择区域取消的时候,Vim 返回插入模式。

替换模式

这是一个特殊的插入模式,在这个模式中可以做和插入模式一样的操作,但是每个输入的字符都会覆盖文本缓冲中已经存在的字符。在普通模式下按”R”键进入。

vim key command