寄存器的类型
Vim的强大功能有很大一部分体现在它丰富的寄存器上。我们可以灵活使用寄存器存取文本,还能将命令录制于寄存器中。
在Vim中,大部分的修改操作都能够撤销,而这也要归功于背后的寄存器。下面我们来看看Vim这个神器都有哪些神奇的寄存器。
在Vim中,寄存器被分为以下10种类型:
- 未命名寄存器
""
- 10个数字寄存器
"0 ~ "9
- 小型删除寄存器
"-
- 26个字母寄存器
"a ~ "z
或"A ~ "Z
- 3个只读寄存器
":
".
"%
- 交替文件寄存器
"#
- 表达式寄存器
"=
- 选择拖放寄存器
"*
"+
"~
- 黑洞寄存器
"_
- 搜索模式串寄存器
"/
这10个寄存器都有自己的特定使用场景,等下面分析完之后,你就能很清楚地知道它们都是干嘛的了!
寄存器的分析
在正常模式(normal mode)下,我们使用 "reg
来引用某个寄存器。而在其它情况下,我们使用 @reg
来引用某个寄存器。
例如:
#正常模式,使用寄存器a来复制当前行
"ayy
#命令行模式,为寄存器a赋值
:let @a="some text..."
接下来的文章中,我们将使用 "x
的形式来表示 寄存器x
。
OK,下面我们就来分析上述10种寄存器的具体使用场景,以及它们的作用。
1. 未命名寄存器
当我们使用 d, c, s, x
这几个命令修改文本,或者使用 y
复制文本的时候,无论是否指定了寄存器,这些内容会被储存到 ""
寄存器中,除非我们指定了黑洞寄存器 "_
。
2. 数字寄存器
当我们进行文本的复制或删除操作时,内容就会存储到数字寄存器中。
0号寄存器 "0
储存最近一次复制的内容,除非指定了其它寄存器。
1号寄存器 "1
存储最近一次删除或修改的内容,除非指定了其它寄存器,或内容不到一行(此时将会使用小型删除寄存器 "-
)。
如果删除操作与以下移动命令一起使用,那么将总是使用1号寄存器:%
,(
,)
, `
,/
,?
,n
,N
,{
,}
。此时如果内容不到一行,"-
寄存器会被同时使用。
1号寄存器被再次使用时,原先的内容会转移到2号寄存器,而2号寄存器的内容则转移到3号寄存器,以此类推,最后9号寄存器的内容则会被丢弃。
3. 小型删除寄存器
被删除的内容不到一行时,该寄存器将被使用。
如果我们指定了其它寄存器,则该寄存器不会被使用。
4. 字母寄存器
只有当我们手动指定了字母寄存器时,它们才会被使用。
当我们使用小写形式的字母寄存器时,新内容会覆盖掉之前的内容。
当我们使用大写形式的字母寄存器时,新内容会追加到之前的内容后面。
如果 cpoptions
选项中含有 >
标志,则追加内容时会自动添加换行符。
5. 只读寄存器
只读寄存器的内容只能被读取,也就是说,只能使用 p
,P
,:put
或 CTRL-R
命令来获取它的内容。
".
存储最后被插入的内容。(与插入模式下使用CTRL-A
和CTRL-@
命令的插入内容一致)"%
存储当前文件名。":
存储最后一次在命令行中执行的命令。
6. 交替文件寄存器
存储当前视窗中另一个缓冲区文件的名称。也就是当我们按下 CTRL-^
时将会跳转到的那个文件的名称。可手动更改它的值,从而让上述命令跳转到指定文件。
let @# = 'buffer_name'
7. 表达式寄存器
表达式寄存器与其它寄存器不同,它并不存储文本内容,而是用于计算表达式的值。在正常模式下输入 "=
,或在插入模式下按 CTRL-R=
时,会进入到命令行,在这输入的命令会经过计算,然后得出结果。
使用表达式寄存器,我们就可以在编辑文件时方便地让Vim替我们完成计算(可以是算术计算,也可以是函数调用),然后把结果插入到文本中。总之,表达式寄存器可以进一步简化我们的工作,非常方便!关于表达式的详细介绍,可以输入命令 :help expression
查看。
这里有两篇介绍表达式寄存器的文章:
8. 选择拖放寄存器
这是用于存储和获取GUI剪贴板内容的寄存器。当剪贴板不可用时,会自动使用未命名寄存器 ""
来代替。
只读的 "~
寄存器用于存储拖放到Vim的内容。当有内容拖放到Vim中时,还会触发虚拟按键 <Drop>
,可以通过映射该键来完成特定任务。
9. 黑洞寄存器
正如它的名字一样,写入该寄存器的内容都会消失。我们可以使用该寄存器来避免其它寄存器受到影响。
读取该寄存器时,返回的内容为空。
10. 搜索模式串寄存器
该寄存器存储了最后一次搜索的模式串,包括使用 /
以及 :g
、:s
等命令进行匹配的模式串。
手动对该寄存器赋值,也可高亮搜索结果,与 /
命令的效果一样。
关于宏录制的小技巧
我们在正常模式下录制宏的时候,使用的就是上面介绍的寄存器。除了黑洞寄存器和只读寄存器不能用于录制宏以外,其它寄存器都能够用于录制宏。
当我们录制一串较长的命令时,可能因为某个地方出了错,导致录制失败,需要重新开始。不过,既然录制的宏存放于这些寄存器中,那么我们就能够像读取普通文本一样读取它们。
例如,我使用寄存器 "a
录制了一个宏,但是中间有个地方出了错。这时我可以使用 "ap
将这串命令粘贴下来,然后修改出错的地方,最后选择这串命令,通过 "ay
将它们复制回寄存器 "a
。这样,我们不用重新录制命令,就完成了宏的修改,是不是很方便?