Skip to content

第九章:寄存器与剪贴板

前面几章里,我们反复提到"Vim 剪贴板"这个词,比如 dd 会把删除的内容存进剪贴板, yy 会把复制的内容存进剪贴板。但你有没有遇到过这种尴尬:你 yy 复制了一行,然后 顺手 x 删了几个字符,等你 p 粘贴时,粘出来的却是刚刚删掉的字符,而不是那一行!

问题的根源在于,Vim 的"剪贴板"其实不止一个 —— 它有一整套寄存器(Registers)。 搞懂寄存器,你就能真正掌控复制粘贴。

查看寄存器

  • :reg:registers 查看所有寄存器的内容
  • :reg a 只查看寄存器 a 的内容

先执行 :reg 看一眼,你会看到一长串以 " 开头的寄存器,下面我们逐类介绍。

无名寄存器

"" 是无名寄存器,也就是我们平时说的"默认剪贴板"。所有没有指定寄存器的删除 (dx)、修改(c)、复制(y)都会写进这里,p / P 默认也是从这里粘贴。

这就解释了开头的尴尬:yy 之后又 xx 覆盖了无名寄存器,p 自然粘出了 x 删掉的内容。

命名寄存器

"a"z 是 26 个命名寄存器,你可以手动指定内容存到哪、从哪取,互不干扰。

  • "ayy 把当前行复制到寄存器 a
  • "ap 从寄存器 a 粘贴
  • "add 把当前行删除并存进寄存器 a

用大写字母则是追加而非覆盖:

  • "Ayy 把当前行追加到寄存器 a 已有的内容后面

Tips:回到开头的问题,只要一开始用 "ayy 把那行存进 a,中间怎么 x 都不怕, 最后 "ap 稳稳粘出来。

复制寄存器

"0 是复制专用寄存器。它保存最近一次 y 复制的内容,不会被 dx 污染。

  • "0p 粘贴最近一次复制(而非删除)的内容

这是解决开头尴尬的另一个办法:yy 之后随便删,最后用 "0p 就能粘回复制的那行。

特殊寄存器

Vim 还有一批自动维护的只读/特殊寄存器:

  • "+ 系统剪贴板(和其他程序互通,macOS/Linux 常用)
  • "* 选择区剪贴板(X11 的主选择区,macOS 上与 "+ 基本等同)
  • "% 当前文件名
  • ": 上一条命令行命令
  • ". 上一次插入的文本
  • "/ 上一次搜索的内容
  • "- 小删除寄存器(不满一行的删除)
  • "_ 黑洞寄存器,写进去的内容直接丢弃(下面详解)

注意:"+ 是否可用取决于你的 Vim 是否编译了 +clipboard 特性,可用 :echo has('clipboard') 检查,返回 1 即支持。

黑洞寄存器

"_ 很有用:当你想删除一段内容但不想覆盖当前剪贴板时,用 "_d 即可。

  • "_dd 删除当前行且不影响任何寄存器

插入模式中取用寄存器

在插入模式下,按 Ctrl-r 再跟寄存器名,就能把寄存器内容直接插入:

  • Ctrl-r a 插入寄存器 a 的内容
  • Ctrl-r " 插入无名寄存器
  • Ctrl-r % 插入当前文件名

在下面的文本里练习寄存器操作。

第一行:用 "ayy 把我复制到寄存器 a
第二行:用 "byy 把我复制到寄存器 b
现在随便 x 删几个字符污染无名寄存器
在这一行下面分别用 "ap 和 "bp 粘贴,看看是不是各粘各的
再试试:把光标放到本行,"_dd 删掉,然后 p,看看粘出来的还是不是刚才的 x

如果你的 Vim 支持系统剪贴板,试试 "+yy 复制一行,然后切到浏览器或别的编辑器 Cmd/Ctrl-v 粘贴,是不是通了?

寄存器是 Vim 高效复制粘贴的地基。掌握了它,回头再看第七章的宏, 你会发现宏其实就是把一串操作录进了寄存器 —— 一切都串起来了。

下一章将介绍跳转与标记。