第九章:寄存器与剪贴板
前面几章里,我们反复提到"Vim 剪贴板"这个词,比如 dd 会把删除的内容存进剪贴板, yy 会把复制的内容存进剪贴板。但你有没有遇到过这种尴尬:你 yy 复制了一行,然后 顺手 x 删了几个字符,等你 p 粘贴时,粘出来的却是刚刚删掉的字符,而不是那一行!
问题的根源在于,Vim 的"剪贴板"其实不止一个 —— 它有一整套寄存器(Registers)。 搞懂寄存器,你就能真正掌控复制粘贴。
查看寄存器
:reg或:registers查看所有寄存器的内容:reg a只查看寄存器a的内容
先执行
:reg看一眼,你会看到一长串以"开头的寄存器,下面我们逐类介绍。
无名寄存器
"" 是无名寄存器,也就是我们平时说的"默认剪贴板"。所有没有指定寄存器的删除 (d、x)、修改(c)、复制(y)都会写进这里,p / P 默认也是从这里粘贴。
这就解释了开头的尴尬:yy 之后又 x,x 覆盖了无名寄存器,p 自然粘出了 x 删掉的内容。
命名寄存器
"a 到 "z 是 26 个命名寄存器,你可以手动指定内容存到哪、从哪取,互不干扰。
"ayy把当前行复制到寄存器a"ap从寄存器a粘贴"add把当前行删除并存进寄存器a
用大写字母则是追加而非覆盖:
"Ayy把当前行追加到寄存器a已有的内容后面
Tips:回到开头的问题,只要一开始用 "ayy 把那行存进 a,中间怎么 x 都不怕, 最后 "ap 稳稳粘出来。
复制寄存器
"0 是复制专用寄存器。它只保存最近一次 y 复制的内容,不会被 d、x 污染。
"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 高效复制粘贴的地基。掌握了它,回头再看第七章的宏, 你会发现宏其实就是把一串操作录进了寄存器 —— 一切都串起来了。
下一章将介绍跳转与标记。