首页 Vim 学习笔记
文章
取消

Vim 学习笔记

最近和大师兄聊天,他非常推荐我们平时写代码使用 Vim。Vim 也是久仰大名了,但之前一直没实际用过,觉得就是换个文本编辑器,没什么必要。但这几天我决定入坑,学起来用起来。

我的参考书籍是《Practical Vim (2nd Edition)》,中文名《Vim 实用手册》。不再单独开读书笔记了。

为什么决定用 Vim?

Vim

Vim 就是一个文本编辑器,但它是以命令行的形式操作的,这是与其他编辑器的直观的不同点。它的设计哲学是只使用键盘、不使用鼠标,目的是提高编辑文本的效率。

Vim 的核心思想是引入了多个模式,把原来为防止键位冲突而不得不引入 Ctrl、Shift 的组合快捷键,全部划到单独一个非输入的模式下,变成单个按键的快捷键。可输入文本的称为插入模式,非输入模式称为普通模式。 普通模式就是为大量快捷键腾出地方的。

另外,Vim 通过一套“语法”将一些简单元素组合为复杂操作,记这种语义的组合比一个硬性规定的快捷键更直观。Vim 还有一些非常强大的命令和功能,可以用非常方便的方式实现。

mode

通过一段时间对 Vim 的学习,我发现 Vim 确实很适合代码这种文本,能很好地解决我曾经写代码时烦过、也思考过、但懒于研究的一些重复性劳动,这是我决定学用它的主要原因。

虽然 Vim 是通用的文本编辑器,但主要还是写代码文本方便,写其他类型的文本可能就鸡肋了。以我博客的 Markdown 文件为例,Vim 的不足之处有:

  • 光标移动问题:Vim 和普通的文本编辑器在行的概念上有区别,见“移动光标”一节的 tips。这个逻辑符合代码习惯,却不符合一段段的 Markdown 笔记;
  • 中文输入法问题:中文输入法下是打不出 Vim 命令的,来回切换输入法反而让 Vim 不方便了;(虽然有插件 SmartIM可以解决这个问题,但 VSCode 配置 Vim 插件也很麻烦。)
  • 冗余功能:Vim 中很多提高效率的操作是普通笔记用不上的,例如各种重复操作、复制操作等。

因此在博客等非代码文本中,我会在 VSCode 中禁用 Vim 插件(仅限博客文件夹的工作区),方法是去扩展中右击 Vim,点 Disable (Workspace)。

配置 Vim + VSCode

Vim 是类 Unix 系统自带的软件,所以我的苹果电脑直接就能用:在终端敲 vim 就能打开了。虽然方便,但它最大的问题是单纯的文本编辑器,没有 IDE 所拥有的运行、调试代码功能,这样写代码和运行调试代码在两个地方,切换很不方便。这个问题可以通过安装插件解决,但想想就很麻烦,而且装了这些东西 Vim 就不纯粹了,我只是想用 Vim 在文本编辑的方便功能而已!

我平时最常用的是 VSCode,它的各种插件使其具备了 IDE 的功能,我也早已习惯了这个方便的图形界面环境。所以想到一个好点子:Vim 能不能看成一个插件,仅是对 VSCode 文本编辑功能的扩展呢?这样既能在编辑文本时用 Vim 提高效率,也能在不编辑文本时继续享用 VSCode 直观的图形界面。

事实上大部分 IDE 都有 Vim 插件,VSCode 也有!直接去扩展中搜 Vim 安装即可,启用插件后, VSCode 打开的任何文本文件就都开了 Vim。

以下开始介绍 Vim 的用法,都是 VSCode 环境中必要的功能,不会涉及不必在 VSCode 中用的 Vim 命令,如保存文件、切换窗口等。

模式

Vim 主要有 4 个模式,VSCode 左下角会提示当前的模式:

  • --INSERT--插入模式,和平时输入文本无差别,所以不想用 Vim 的话就一直开着这个模式好了;
  • --NORMAL--普通模式,Vim 的主要功能;
  • :命令模式,在普通模式下输入冒号后跟上相应的命令;
  • --VISUAL--可视模式,类似于 Word 打开了只读文件的效果。经常选则文本使用。

另外,这些模式的光标是不一样的,插入模式是细光标,其他是粗光标(会盖住一整个字符)。

如何切换模式可以一图以蔽之:

mode

普通模式是 Vim 的主要功能,因此所有模式的“家”,正如其名字一样,打开 Vim 后默认也是普通模式。其他模式都可通过 Esc “一键回城”。其他模式间的切换现在去死记是没有意义的,我会在下文穿插在用到的地方讲。

入门级操作:移动光标后进入插入模式

这是基本操作,无论什么文本编辑器,最自然的输入方式就是移动光标后插入文本

Vim 下无论是什么模式,移动光标都可以通过上下左右或鼠标点击完成。但一定要养成在普通模式下移动光标的习惯,先移动再进插入模式。有句话说的好,插入模式,最大的职责就是进行字符的插入。

普通模式下,Vim 还有另一套按键映射:h = 左,j = 下,k = 上,l = 右。由于其位置比方向键更方便,最好是练习使用这一套键位。

上下左右键位在 hjkl 其实是历史原因造成的,早期的电脑键盘没有方向键。其方便性可能只是巧合。

上面是基本的,当然还有大量的移动光标的快捷方式:

  • 按行:0,^,$ 分别为移到行开头、行不算空白符的开头、行结尾;
  • 按单词:w,b,e,ge 用一张图可解释: mode
  • 行内查找字符:f{char},t{char} 为向后查找本行第一个为 char 的字符,并移动光标到该位置,区别是前者移动到该字符的下一个位置,后者移动到该字符。F{char},T{char} 为向前查找;
  • 跨行查找字符串:/{string}<CR> 为向后查找为 string 的字符串,以回车键 <CR> 标识字符串结束;
  • 寻找括号的另一半:在光标移到括号的一半时,按 % 可以跳转到它的另一半;
  • `系列
    • ``:跳转到上一次光标的位置
    • `.:上次修改的位置
    • `^:上次插入的位置
    • `{字母}:跳转到标记的位置,标记的方法是在标记位置打 m{字母},可以标记多个位置(字母作为标识符)

关于行: Vim 中的行默认是真实的行(以行号标示),而普通文本编辑器是实际显示的行。这种不同点会影响 j,k,0,^,$ 等涉及行概念的行为。在这些按键前加 g 会按实际显示的行来。

此外,Vim 的左右无法跨行。

移动好光标后,就可以进入插入模式编辑文本了。应注意普通模式进插入模式有很多方法,有的甚至不需要精确移动到确切的插入位置:

  • a:在光标后面进入;
  • i:在光标前面进入;
  • A:在行末进入;
  • I:在行开头进入;
  • o,O:在下 / 上另起一行进入;

另外,修改操作 c 也是会由普通模式进入插入模式的,下一节再讲。

不理解光标哪是前哪是后?注意普通模式的粗光标是盖住一整个字符的。

快捷修改操作:普通模式下的 “操作符 + 动作”

Vim 当然不只为了移动光标方便,这样的话它还多一个模式切换问题,还不如普通的编辑器呢。Vim 有大量快捷的编辑操作可在普通模式下按几个键实现。

有些小操作(一般是字符级别的)只需一个按键即可完成,列举如下:

  • x:删除光标处的字符;
  • p:在光标处粘贴;

大部分操作分为 “操作符 + 动作” 两部分,这里动作(motion)应理解为操作的范围。这个逻辑类似计算机体系结构讲的指令系统,只是 Vim 对命令做了极大的简化。

用法:先敲操作符,会发现光标变成下划线,等待输入动作。再输入动作,输完后操作会自动执行,不需敲回车等。以复制当前单词 yiw 为例,y是操作符,iw 是动作,直接在普通模式下打 yiw 就能立即执行。

因为不需要敲回车,所以后面只能跟一个动作!

操作符有:

  • c:修改(change),即删除后进入插入模式;
  • d:删除(delete);
  • y:复制(yank);
  • gU,gu:变成大写 / 小写;
  • >,<,=:左缩进、右缩进、自动缩进。

动作有两类:

  • 一类是选择的一端固定在敲了操作符的位置,另一端通过移动光标的方式确定。上节介绍的移动光标的按键都可用;
  • 另一类是从光标处向左右匹配某种 pattern 的,叫文本对象。总是由 i,a 和一个标识符组成。以括号为例,i),a) 表示从光标处左右选择被小括号括起来的内容,区别在于前者不包含括号,后者包含括号。标识符有:
    • 各种成堆匹配的符号,取右半边:)(=b),],}(=B),>',", ` ` ,t`(表示 HTML 的标签);
    • w,s,p,e:取一个单词、句子、段落、整篇文章。

由于对一行的操作很常用,Vim 设计敲 2 次操作符表示动作为当前行,如 dd 表示删除当前行。

替代方案:在可视模式选中后操作

上面方案的问题是,需要快速确定操作,精准定位范围。有时候我想先漫无目的地随便选点东西,浏览一下,再做修改,”操作符 + 动作“ 就不适用了。平时的编辑思维是选中后再做操作,和上面是反过来的。在某些场景下,这个习惯会更方便。

前面说到可视模式通常是为选择文本设计的,要进入可视模式选择文本。用法:先按 v 进入可视模式,这个时候就将选择的起点定在此处,再移动光标(包括 hjkl 和各种快捷方式)到终点,最后敲操作符。

还有 2 种选择单位更大的可视模式,方便更宏观的操作:

  • V:以行为单位选择的可视模式;
  • Ctrl + V:以块为单位选择的可视模式。

可以看到,用可视模式在选择上更加自由,能处理更精准的范围;相比之下,“操作符 + 动作” 只能有一个动作,但是其更快捷。选择哪种方式应视具体场景而定。

自动化工具

. 可以在当前光标位置重复上一步操作。操作是指上一节的一套 “操作符 + 动作” 或进入可视模式后的操作。移动光标是不算操作。

. 起类似作用的有(见“移动光标”一节):

  • ;,,:重复行内查找字符,; 为向前,, 为向后;
  • n,N:重复跨行查找字符串,n 为向前,N 为向后。

数字也可以用于指定操作的次数,可以夹在很多地方,特别灵活。用法例如 3j 为向下移动 3 行,d2w2dw 为向右删除 2 个单词;等等。

更强大的是键盘宏(Macro),即录制一遍按下的按键,在其他地方重复执行。宏功能本身并不稀奇,Word 等文本编辑器里也有此功能,主要是 Vim 的键盘宏非常方便、简捷。

用法:q{字母} 开始录制,字母是宏的名字;录完之后按 q 结束,将光标移动到合适的位置后,按 @{字母} 执行宏。

其他暂时用不上的功能

到现在还没有介绍四个模式中的命令模式。命令模式的命令有点像微软家的 VBA 编程,甚至能写成脚本,这与普通模式的操作相比完全是另一套东西。普通模式下的操作它都能做,但可以实现更系统的、规模更大的操作,因此也带来的打指令字符更多的麻烦。同样的操作在这里有单独的语法,而且命令比单个按键更难记,需要付出更大的学习成本。因此我决定直接舍弃这一部分。

其他用不上的列举如下。注意很多是利用了 VSCode 的便利,在命令行的 Vim 中还是不可避免要是使用的。

  • 普通模式下 u 是撤销,但其实没有什么特殊的。我还是愿意按 Cmd + Z 实现;
  • 保存是用命令 :w ,还是习惯 Cmd + S
  • 命令行中的 Vim 可以开多窗口同时编辑多个文件,直接用 VSCode 的标签页就行了。
本文由作者按照 CC BY 4.0 进行授权,转载请注明

我使用的网站推荐

《Kards》原创卡组分享(长期更新)