最近学习了VIM的编辑模式,没想到这个软件居然是如此的强大。虽然学习曲线有点陡峭,但是一旦掌握了以后发现真的是对于输入和修改的效率的提升那也是相当可观。因此我真的觉得每个以代码为主要工作的程序员来说,都有必要掌握这个技能.

VIM高效的特点

VIM的多模式

VIM是为没有鼠标的命令行界面进行文本编辑而生,无需使用鼠标这是它和当前主流的利用鼠标进行操作的编辑软件最大的区别。 在支撑鼠标软件中,我们往往是利用鼠标来准选择要修改的内容,然后进行修改(插入可以理解成对选中长度为零的文本进行修改)。而VIM的操作则可以理解成利用了键盘来实现对修改内容的定位和选择。所以VIM需要通过不同的模式来对按键的功能进行区分,也就是说同一个按键在不同的模式下实现的功能会不一样。多模式下极大的扩展了按键的功能。例如在插入模式下按键主要是实现输入的功能,而普通模式下按键则是实现光标移动和对文本内容进行修改的功能。

VIM操作本身是一种命令输入

而除此之外,VIM最强大的是让用户感觉是用一种命令式样的方式来进行文本的修改,例如我们可以利用键盘简单输入指令来执行“删除4行”,或者是“删除括号内所以内容”,甚至“把括号内全部变成大写”这样的操作,而这些操作如果用鼠标来完成则相对繁琐,这也是VIM为什么特别高效的原因。 不用着急理解,后续会仔细讲解。

谁适合使用VIM

VIM特别适合多数时候在浏览,阅读,少量编辑。当然,VIM也是可以实现大量文字连续输入 但VIM不适合大量的中文输入,因为需要频繁切换中文输入,会使得在使用VIM时候输入命令变得麻烦,严重降低效率,而且VIM对于word(英文单词)的概念在中文中实现得很不好,也不利于高效操作。

所以VIM对于程序员来说是特别合适的。

VIM的模式

让VIM变得不那么容易掌握的一个重要原因是它的几种模式的切换,但这也是VIM高效的原因。

如果我们归纳一下进行文本操作的行为,大致就是如此几种:浏览,修改,输入,和文件操作等。VIM的几种模式也就是对应了这几种行为场景。在使用VIM时候,也就是这几种模式下不断切换并进行相应行为操作。

普通模式 NOMAL MODE

  • 在任何模式下可以通过esc来返回普通模式
  • 这是VIM最核心的模式,也可能是停留时间最长的状态。刚开启的VIM文档就处于这种模式。在普通模式下用户主要的工作是通过键盘操作精确移动光标,并对光标所在位置的文本进行操作,例如删除,剪贴,也可以随时切换到插入模式进行文字输入。这个模式的核心就是用移动光标到指定位置然后执行某个操作或命令。

插入模式 INSERT MODE

  • 普通模式下按i/I分别代表在光标当前位置/行首插入新的文字输入
  • 在这种模式下可以输入文字,此时VIM就化身成一个最普通的编辑器,用户可以像在其他任意编辑器中那样输入文字,可以用删除键删除文字,方向键来移动光标。在一篇文章刚开始或者对现有文档进行编辑,在光标移动到预定位置时候就可以切换到插入模式,此时光标会变成一条闪烁竖线,表示这个模式下输入文字。

    还有其他更多进入插入模式的方法后续补充

命令模式

  • 在普通模式下通过按:进入命令模式。命令模式中通过输入命令可以执行相应操作,例如保存,退出。

其他模式

VIM最重要的是上面三个模式,另外还有

  • 替换模式:类似于插入模式,也可以在光标处输入文字,区别是新输入的文字会替换光标当前的文字。
    • 普通模式下按r键会进入单个字符替换模式,此时输入的内容会替换光标当前位置的字符,替换完成并返回普通模式
    • 普通模式下按R键会进入连续字符替换模式,此时输入的内容会不断替换光标位置的字符,直到按esc返回普通模式
  • 视觉模式:普通模式下按v键可以进入视觉模式,这种模式其实是类似于用键盘控制光标来模拟鼠标的范围选择,选中范围内的字符可以执行和普通模式下相应的操作,例如删除,剪切等。

后面这两种模式相对应用范围小,可以在掌握上面三种后再进一步扩展掌握。

VIM的常规操作

常规操作是:移动光标位置(光标范围选择)+执行命令/操作

普通模式下光标移动

大部分时候VIM都应该是在普通模式。

VIM在这种模式下实现的主要功能是对光标的移动,定位到需要修改的位置,然后切换到相应的模式,进行插入,增加修改,或者是视觉模式来选择更多的区域。一旦修改完成,立刻切换回普通模式进行下一操作位置的导航。

为实现光标精确移动,VIM设计了相当丰富的键盘操作功能,光标移动指令如下:

基本方向键

  • 基本移动的四个按键hijk 对应左下上右

基于文本格式

  • 基于词:w/b上下一个词首e/ge词尾, W/B也是上下词首,但是基于空格的词
  • 基于行:0行初, ^第一个非空格字符, $行尾
  • 屏幕:H屏幕行首, M屏幕中央,L 屏幕底部
  • 页面:ctrl+u上翻, ctrl+d下翻
  • 文件:gg文件头, G文件尾
  • 行数:{linenumber}G直接定位到该行, 或者命令模式下输入行数回车

基于查找

  • f/F{content}在同一行内向后/前查找并移动光标至查找内容处
  • t/T{content}在同一行内向后/前查找并移动光标至查找内容并靠近原光标位置的相邻一个字符处
  • 搜索:/{Regix} 查找表达式内容并将光标放置在内容首字符, n/N用于匹配向后/向前的下一个

光标的移动,我们也可以称之为Motion。Motion过程中光标原位置和光标新的位置会产生一个范围,而这个范围会成为VIM高级操作的重要组成,后续再讲。

插入模式下编辑

通过移动光标到了相应的位置选择了相应的字符,这时候就可以进入插入模式进行编辑了。

  • 通过光标位置进入插入模式:
    • i/I 在光标当前位置前/行首进入插入模式
    • a/A 在光标当前位置后/行m进入插入模式
    • o/O 在光标所在行的下/上一行新建一行,并进入插入模式

命令模式下退出

插入模式编辑完成后,按esc可以返回普通模式,然后按进入命令模式。

在进入命令模式下,光标会移动到编辑区域左下角一行,此时输入命令执行操作,例如

  • w表示保存
  • q表示退出vim编辑应用
  • wq表示保存当前更改并退出q!表示不保存强制退出
  • 更多…

至此,通过三个模式的切换,我们就可以实现一个文件的完整编辑过程了。而且全程通过键盘完成,无需使用鼠标。

但VIM的功能显然不止于此。我们继续!

VIM的进阶操作

VIM高效操作的另一面是其编辑命令的操作模式。大部分编辑命令都在普通模式下执行,并通过给予命令具体的执行方式或范围来实现复杂的操作。而这些复杂命令的操作只需要几个按键的组合

编辑命令的完整结构

< # > < Action | Operator > < text-object | motion >
  • < Action | Operator >:命令的主题,往往是一个动作或操作,例如光标移动指令,或删除,修改等操作
  • < # >:命令执行的次数
  • < text-object | motion >:命令执行的方式或范围

这三者组合起来,就能构建处复杂的处理命令。

Action

Action包括了所有例如:普通模式下光标移动 中提及移动光标的行为,在行为前加上数字,表示改行为执行的次数。例如:

  • 4j光标向下移动4行
  • 8l表示光标向右移动8个字符
  • 4e 光标向后移动到4个单词的末尾

Operator

在普通模式下,可以直接执行如下操作。而这些操作往往会需要一个对象或者范围。

  • d 是删除操作(准确说是剪切),后面需要提供一个操作执行方式的描述
    • dd 删除整行
    • dw 删除光标至当前单词尾,w表示移动光标至单词尾。后续范例同理
    • d$ 删除光标至当前行尾
    • dO 删除光标至当前行首
    • 删除单个字符无需添加描述:
      • x删除光标位置的字符
      • X删除光标前的字符
  • 拷贝粘贴
    • y 拷贝操作,后面也需要提供一个操作执行方式的描述:
      • yy 拷贝当前行
      • yw 拷贝当前光标至单词尾
      • 更多拷贝操作方式…
    • 粘贴无需添加描述词:
      • p 在当前光标后粘贴
      • P 在当前光标前粘贴
  • c 表示修改,和d的删除其实非常类似,也可以提供操作执行方式的描述来实现对不同范围的内容的修改。和删除的区别在于:删除目标内容后会进入插入模式,可以直接开始输入文字。
  • 还有些其他很有用的工具,例如
    • ~可以用来切换光标处字符的大小写
    • gu/gU表示对选定内容改成小写/大写,例如guw 表示把当前光标至词尾改成小写。

对< text-object | motion >的进一步解释

在编辑命令中操作符后面表示命令执行方式或范围的补充词可以分成两大类:

  • text-object 表示文本内容,文本内容由修饰语和文本名词共同组成。
    • 修饰语主要有i/a,分别表示在里面或者周围
    • 文本名词例如:w 表示光标所在单词,s 表示所在的句字,p 表示光标所在的段落,t表示html文档中的tag
    • 修饰语和名词组合起来表示文本内容,描述前面操作符的实施对象。例如:
      • ci( 改变当前括号内的内容
      • da' 表示删除单引号内的内容,包括周围的单引号
      • dit 表示删除tag之间的所有内容,这对于HTML或XML代码简直太友好
      • die 表示删除当前文件所有内容
  • motion则是表示一个范围内所有字符,这个范围是指从光标开始位置到执行光标移动动作后之间。例如
    • dw 表示删除从光标当前位置到下一单词词首之前所有字符
    • d2w 表示删除从光标当前位置到下2单词词首之前所有字符,这个和2dw效果相同
    • y4j 表示往下复制4行
    • cfs 表示删除从光标当前位置到下一个‘s’字符前,并进入编辑模式

VISUAL MODE实现光标范围选择

除了上面普通模式的Motion操作移动光标,还可以通过视觉模式来批量选中字符。这是一种可视化选择模式,选中的内容用来执行操作。

进入选择模式后,通过移动光标action,会创建基于原光标位置和新光标位置的选中区域。以下不同类型操作体验一下即可理解。

  • 普通:v
  • 行类型:V
  • 块类型:Ctrl+V

总结

通过以上的内容,大致可以了解到VIM强大在于

  • 通过键盘进行光标导航和选择范围的控制,然后对光标或选择的内容执行操作
  • 执行编辑命令的时候可以通过一定计数词或修饰词让其执行的更高效

附上一张VIM键位图,仔细品味

键位图