Vim 寄存器的使用

编辑器之神可不是浪得虚名

0X00 遇到了一些问题

如果你看到了这篇文章那么我可以认为你至少已经掌握了vim基本用法。在我个人使用vim的过程中遇到了一些问题,这次就挑“寄存器”这部分出来说一下吧。

我这里贴一段代码过来,这段代码出自我在学校时写的一个小项目open_disframe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
if slave_method == 'handshake':
process_handshake_request(slave_id)
slave_socket.send("handshake success".encode('utf-8'))
continue
elif slave_method == 'heartbeat':
process_heartbeat_request(slave_id)
slave_socket.send("heartbeat success".encode('utf-8'))
continue
elif slave_method == 'submit_message':
process_submit_message_request(message['message_list'])
slave_socket.send("submit success".encode('utf-8'))
continue
elif slave_method == 'get_message':
send_message_list = process_get_message_request(slave_id, 10)
slave_socket.send(send_message_list.encode('utf-8'))
continue
elif slave_method == 'exit':
process_exit_request(slave_id)
slave_socket.send("exit success".encode('utf-8'))
continue
else:
slave_socket.send(("not found request: " + slave_method).encode('utf-8'))

现在我们在编辑编辑这段代码的时候需要将其中的部分内容替换掉,比如将第一个if中的slave_socket.send.....和第二个if中的process_heartbeatxxx和第三个if中的continue替换成break。虽然这么做可能有点诡异,不过这里实在没找到完美的适用场景,公司的代码也不能贴出来,又懒得编造一个完美适用场景,就先这样看吧。

通常我们与到这种情况都会是下面的操作流

  1. 手动替换第一处的break
  2. 复制break
  3. 找到下一处需要替换的地方选中
  4. p粘贴过去
  5. 找到下一处需要替换的地方选中
  6. p粘贴过去
  7. 发现“剪贴板”被上面那次被替换掉的数据覆盖了,以至于将上次删掉的内容贴过来了,而不是自己想要的break
  8. 沮丧中。。一个个复制粘贴替换过来

这个问题困扰了我还是挺久的,一度认为vim居然这么蠢,后来才发现是我自己太蠢了,vim中有一个“寄存器”机制是我们均大多数人要么没用过要么听都没听过的,而这个“寄存器”就是用来解决这种问题的。

0X01 什么是vim中的寄存器

我们可以大致将vim中的寄存器想像成系统使用的剪贴板,我们平时用的剪贴板只有一个格子,每次复制/剪切了新的数据就会覆盖掉之前格子里的数据。而vim中的寄存器有多种,每种有不同的功能特性,而且每种寄存器又有一个到多个不等。总的来说vim中有下述十种寄存器。

  1. 匿名寄存器 ""
  2. 编号寄存器 "0"9
  3. 小删除寄存器 "-
  4. 26个命名寄存器 "a"z
  5. 3个只读寄存器 ":, "., "%
  6. Buffer交替文件寄存器 "#
  7. 表达式寄存器 "=
  8. 选区和拖放寄存器 "*, "+, "~
  9. 黑洞寄存器 "_
  10. 搜索模式寄存器 "/

在命令模式下: register就可以看到各个寄存器的值了

0X02 如何使用这些寄存器

这些寄存器种类较多,只挑选一些我个人常用到的吧,更完善的一篇博客可以看这里

如何使用寄存器

先简单说一下,下面会具体介绍的。当你选中一坨内容后想要复制他到命名寄存器"a中,那就需要在选中后依次按下"ay。其中"a相当于是选中了一个寄存器,而y就是当前选中内容与寄存器之间的操作。因为是y所以就是将当前选中的内容复制到"a中,如果是"ap的话就是将命名寄存器"a中的内容粘贴到选中的位置上来。

匿名寄存器

匿名寄存器基本就是我们最常用的那个,平时d/x的删除操作都会将被删除的内容存到这个匿名寄存器中,而通过y复制的内容则会放到"0的编号寄存器上,不过这个"0寄存器会一直保持与匿名寄存器""相同的内容。正因为如此才会出现上面提到的现象:“复制了一段内容A,选中B粘贴,原来B的位置就被A替换了;再选中C粘贴,替换C位置的不是A而是B”,因为在B被A替换时,匿名寄存器""中就已经是内容B了。

编号寄存器

编号寄存器中,"0保存的是你复制的内容,"1~`”9`保存的是删除的内容、上次删除的内容、上上次删除的内容等历史9次删除的内容。

这也正是解决上述问题的关键所在了。下面我们来尝试这解决上面的问题,前三步是一样的,从第四步开始就有区别了。

  1. 手动替换第一处的break
  2. 复制break
  3. 找到下一处需要替换的地方选中
  4. 在命令模式下输入"0p
  5. 找到下一处需要替换的地方选中
  6. 再命令模式下输入"0p
  7. 重复操作直到完成

其中"0p操作就是从编号为0的编号寄存器中粘贴内容。如果直接p的话是从默认的匿名寄存器中粘贴的,内容也就是刚刚被删掉的内容了。

小删除寄存器

不足一行的删除操作会将被删除的内容放到小删除寄存器"_

命名寄存器

命名寄存器就很好理解了,就相当于一些贴了标签的小盒子。"ay就是复制内容到命名寄存器"a中,"bp就是从命名寄存器"b中粘贴内容出来。

当你选中了一坨内容"ay后,再选中另一坨"ay,如你所想,之前的内容被替换了;但是需要注意的一点是,如果你选中了一坨内容"ay后,再选中另一坨"Ay就会将当前内容追加到"a中。也就是说当使用大写字母表示命名寄存器复制时,是会追加而非覆盖的。

黑洞寄存器

默认情况下删除内容时会将被删除的内容放到"1""两个寄存器中,但是如果选中后使用"_x或者"_d的方式删除,则会将被删除的内容丢到黑洞中,也就是说并不会覆盖"1""。所以使用黑洞寄存器也能解决上述问题

  1. 手动替换第一处的break
  2. 复制break
  3. 找到下一处需要替换的地方选中
  4. "_x删除
  5. p粘贴过去
  6. "_x删除
  7. p粘贴过去
  8. 重复操作直到完成

0X03 后记

vim果然是真的编辑器之神