Vim中的寄存器:Register
刚接触vim时,相信多多少少都会遇到关于复制粘贴的问题,例如以下两个问题
- Vim编辑的内容如何复制到其他地方?
- Vim中如何复制(y)一段内容后,多次复用,而不会被替换内容覆盖?
其实这些问题都可能跟Vim中的寄存器有关,寄存器可以想象成内存中存储某些文本的空间,类似于粘贴板。在使用y
,p
,d
等命令时,都会不经意间的操作Vim的寄存器。
基本用法
Normal模式下,使用"{register}{command}
, 例如"add
,表示删除当前行内容,并将内容保存至"a
寄存器中,而使用"ap
,则可以粘贴"a
寄存器中的内容。而插入模式下,使用ctrl-r a
来表示粘贴"a
寄存器中的内容。
Vim中输入:register
,会输出使用中的寄存器以及其保存的值,或者:register x
指定输出某些寄存器。
寄存器类型
Vim中输入 :help registers
,其中介绍了vim中10种类型的寄存器
1 | There are ten types of registers: *registers* *{register}* *E354* |
匿名寄存器
当使用d
,c
,s
,x
,y
等操作时,内容会存储在匿名寄存器""
中,如果操作指定寄存器"add
,除了"a
寄存器,内容也会存入匿名寄存器中。p(aste)默认使用匿名寄存器。
数字寄存器
“0至”9,其中”0会保留最近一次复制的内容,而”1至 “9则会保存最近9次删除操作的内容。当指定拷贝操作的寄存器时,不会写入”0中,但删除操作一定会写入”1中。使用y(ank)命令未指定寄存器时,会将内容保存至”0寄存器,同时””具有相同的内容。
短删除寄存器
顾名思义,对于少于一行的内容操作,除非指定寄存器,否则内容都会被存入 "-
寄存器中。
具名寄存器
通过26个英文字母,指定寄存器,例如”add ,如果原有”a寄存器中含有内容,则会被覆盖,而执行”Add则会在原有内容后追加内容。
只读寄存器
":, "., "%
,这三种寄存器读取内容,其中":
表示上次执行的命令行,"%
表示当前编辑文件名,".
表示最近插入的内容。
交替文件寄存器
一般我们会使用ctrl-^
来回切换buffer,其中原理则是在"#
寄存器中存放交替文件。
表达式寄存器
normal模式下,输入"=
,在命令行中输入任何Vim script的表达式,通过使用p(aste),插入表达式结果。
选择拖入寄存器
"*
与 "+
寄存器, 对于maxOS与windows系统都可以表示为系统粘贴板,而在linux中,会有两种不同的意义,使用"+yy
,则可以将vim中的文本,粘贴至其他程序,其他程序复制的内容,也会同步到该寄存器中。而当有文本被拖入Vim中时,文本将会存储在"~
寄存器中
黑洞寄存器
"_
对于所有删除或拷贝到该寄存器的内容,都会消失,从而不会影响其他寄存器;例如删除操作,会影响其他数字寄存器,导致原”9寄存器内容被覆盖,而复制操作,则会改变”0寄存器。
搜索寄存器
normal模式下,通过/{something}
搜索,最近一次的关键词会被存放在"/
寄存器中。
小结
通过简单了解vim中所有类型的寄存器,大致能解答文章开头的两个问题,也可以实现更多的骚操作。
Vim编辑的内容如何复制到其他地方?
通过”+ 或 “* 寄存器,使用系统粘贴板,当然也可以通过设置
1 | set clipboard=unnamed |
Vim中如何复制一段内容后,多次复用,而不会被替换内容覆盖?
前文讲到数字寄存器,复制操作时,会保存内容至匿名寄存器以及”0寄存器,而在每次删除操作时,会更新”1-“9寄存器以及匿名寄存器,而p(aste)时,会使用匿名寄存器,所以如果p(aste)操作时,如果有替换内容,匿名寄存器内容会变为替换的内容,不过”0寄存器还是最近一次y(arn)的内容,所以可以使用"0p
。或者设置一个map
1 | xnoremap p "0p |
不过这样会导致 d(elete)操作的内容无法被p(aste)使用,所以只需要使用p(aste)时,替换内容不覆盖匿名寄存器即可。前文有讲到黑洞寄存器"_
,不保留不需要的内容,所以我们只需要魔改p(aste)操作,将替换内容删除至黑洞寄存器中,再粘贴内容即可。map如下:
1 | xnoremap p "_dP # 这里因为先删除,所以需要使用大写P |
参考
http://einverne.github.io/post/2017/11/vim-registers.html
vim :help registers