vim 从嫌弃到依赖(15)——寄存器
在计算机里面也有寄存器,计算机中的寄存器是看得见,摸得着的实体,寄存器中存储需要经常访问的一些数据。而vim中也有寄存器的概念,vim中的寄存器是一个虚拟的概念,更像是一块专门用来存储数据的内存缓冲区。在使用vim的过程中离不开寄存器,而且我们很早就用到了寄存器,只是没有发现罢了。这篇文章将深入介绍寄存器,这样我们对之前使用的命令将会有更深的认识。
几种寄存器类型
无名寄存器
在之前介绍过,可以使用d来删除一段内容,使用p来粘贴,使用y来复制, vim中其他的带有删除功能的operator 像 x、c、s 之类的,vim在删除之前会将被删除内容先放到无名寄存器中,然后执行删除操作。严格意义上来说,他们并不是删除而是剪切。后续可以通过p 命令来粘贴之前被删除的内容
例如
print("hello world")
print("")
改为
print("hello world")
print("")
就可以在第一行通过di",将被删除的内容存储到无名寄存器中,然后在第二行对应位置执行 p (或者P) 命令取出无名寄存器中的内容。

这里在使用h 移动光标之后,光标所在位置在后一个引号的位置,为了减少一次光标移动,我直接使用P 在光标所在位置之前进行粘贴操作。
这里插一个题外话,vim中的命令都是某些有意义的单词的首字母或者几个字母的缩写,像d代表delete、y代表yank,那么p又代表什么呢,粘贴的英文是paste,但是知道寄存器以及复制粘贴在vim的表现,我觉得应该是put,就是将寄存器中的内存拿出来。好在他们的首字母相同,不影响记忆。
有名寄存器
它是对应无名寄存器来说的,无名寄存器虽然说使用方便,但是有一个很大的问题,那就是如果我们连续两次执行了删除或者复制操作,那么前一次保存的内容将会被后一次的给覆盖掉。为了解决这个问题,一个思路就是使用有名寄存器。
vim中提供了由a到z的有名寄存器,可以在使用operator 的操作前面指定需要使用的寄存器,引用一个寄存器可以使用 " + 寄存器名的格式。这个时候我们之前的公式就又可以扩展了
" + regester + operator + motion
例如在执行删除的时候 "add 将一行删除的内容放到a寄存器中,再次执行"bdd将内容放到b寄存器中,执行粘贴的时候,可以使用"ap和 "bp来分别使用 a和b寄存器的内容。

无名寄存器有一个专用的符号,使用 "来表示。也就是说dd 命令其实等效为 ""dd。但是为了偷懒和方便,还是少输几个字符的好。
复制寄存器
前面说到使用 dd 之类的命令会将被删除的内容放到无名的寄存器中,它的行为有点像普通编辑器中的剪切,那它是不是剪切呢,那么多教程都把它叫做删除,是不是有问题呢。它确实是删除指定,教程说的也没错,vim中有专门存储复制内容的寄存器。普通的删除命令会把被删除的内容保存到无名寄存器中,但是这些内容不会被保存到复制寄存器中。复制寄存器使用 0来表示。即我们可以使用 "0p来将复制寄存器的内容取出。也可以通过命令 :reg 0来查看这个寄存器的内容。

在上述例子中,我们先在第一行执行 yy 操作进行复制,这个时候数据会被同时保存到无名寄存器和复制寄存器。然后在第二行执行 dd 删除,这个时候第二行的数据会被保存到无名寄存器,之前保存的第一行的数据就被删除了,但是不会被保存到复制寄存器,第一行的数据仍然存储在赋值寄存器。接着立即执行p 它会从无名寄存器中中取出我们之前删除的第二行的数据。接着再执行"0p 会从复制寄存器中取数据,这个时候取出的仍然是第一行的数据。
黑洞寄存器
前面说到 dd会将被删除内容放入到无名寄存器中,如果这段内容我确实不想要了,也不想它占用寄存器,有没有什么办法彻底删除呢,答案是使用黑洞寄存器,顾名思义,放入该寄存器中的内容都被吸走丢失了,无法使用了。黑洞寄存器使用 _作为标识符,执行删除指令的时候可以使用 "_dd这样就再也访问不到之前删除的内容了。

在上面的例子中,我们先执行普通的dd 命令,它会将删除内容放入到无名寄存器中,第二次执行的是 "_dd ,它会将内容放到黑洞寄存器中直接丢弃,后面执行p 的时候只会粘贴第一次删除的内容。有小伙伴可能会说,这个跟我使用其他有名寄存器效果是一样的。看不出什么区别,那么我们可以试试使用 :reg 命令来查看有名寄存器和黑洞寄存器的值,我们发现黑洞寄存器的值永远为空,而有名寄存器此时多了一条记录。
系统剪切板
之前我们在vim中复制粘贴的内容,只能在vim中使用。同样的系统中复制粘贴的内容只能在系统其它程序中使用,无法直接粘贴到vim中。我们可以在vim中使用系统剪切板。vim可以使用+来访问系统剪切板。例如使用 "+yy将内容复制到系统剪切板中,供其他程序使用。
但是在有好的shell工具的加持下,我更喜欢用<Ctrl+v>这样的方式直接粘贴一大段文字到vim中。或者配合vim的可视模式,直接使用shell中的快捷键从vim中粘贴选中的内容到系统剪切板
表达式寄存器
前面介绍的几种寄存器都是被动的存储静态的内容,只有存储功能。表达式寄存器则可以接受一段vim脚本并执行它并输出结果。表达式寄存器使用 =来表示。
例如在插入模式中可以使用 <Ctrl+r>=6*6 来进行数学计算并输出。

到此已经介绍完了vim中几种主要的寄存器,是不是觉得挺抽象的,而且用起来也不是那么方便。下面我们还是以例子来展示相关用法。
示例
示例1:复制粘贴的使用
假设我们要将如下代码
print("hello world")
print("hello vim")
修改为
print("hello world")
print("hello world")
可以在第一行使用 yi"来复制引号内的内容,但是如果在第二行先使用 ci"再使用 p进行粘贴的话会发现粘贴的仍然是hello vim这是因为后面使用c操作的时候,已经将原来的给覆盖掉了。现在我们来解决这个问题。
第一种解法:y指令可以额外产生一个动作,它会将内容放入到复制寄存器中,那么在执行了ci"之后使用 "0p来使用复制寄存器中的内容

第二种解法:可以手动指定ci"删除的内容放入到黑洞寄存器中,即执行"_ci"这样就不会产生覆盖问题。

前两种方法虽然解决问题了,但是都引入了新的寄存器,按键比较繁琐,如果不想引入新寄存器,就得使用接下来介绍的第三种方法了,它也是我最喜欢的方法了。
解法三:由于我们需要先删除之前的内容再复制,为了快速删除,所以会发生覆盖问题,我们只要不执行删除操作就不会覆盖了,为了一次性完成粘贴替换的操作,可以使用选择模式,之前介绍选择模式的时候说过,在选择模式下operator 会将选中部分作为操作区域。可以使用 vi" 来选中引号内容,然后直接使用 p 完成复制

示例2:插入模式中使用寄存器
之前已经在介绍表达式寄存器的时候已经介绍了如何在插入模式中使用寄存器,可以使用 <Ctrl + r> + register 例如上面的例子可以使用 <Ctrl + r>0来将复制寄存器中的内容写入到光标所在位置。

相比上面介绍的前两种解法,它省去了切换回普通模式的步骤,相对来说更高效一点。但是我觉得它还是比不上第三种解法。
示例三: 处理粘贴混乱的问题
有的时候在粘贴代码的时候发现代码的格式可能会乱,这个时候可以设置 :set paste选项,设置之后复制粘贴将不再出现这个问题,但是它会使我们在其他模式下设置的快捷键失效,在粘贴完了之后可以使用 :set nopaste取消该设置。由于我使用的neovim中没有发现这个问题,就不演示了,各位使用vim的小伙伴可以自行测试。
当然处理该问题的另一种方式是使用之前介绍的在vim中使用剪切板的方法,也就是使用 "+p这样的形式。
vim 从嫌弃到依赖(15)——寄存器的更多相关文章
- vim寄存器与复制粘贴的实现
对于大多数在Ubuntu下使用vim作为常用编辑器的同学来讲,他们遇到的第一个比较大的麻烦来自于vim与外部应用的复制粘贴. 当然,愿意选择ubuntu以及vim的同学肯定是google好手.不幸的是 ...
- vim 计算器寄存器使用
我们可能会在vim的使用中,碰到下面的情况 当我正在写一周预算的时候,我想计算下每天我买菜花2.7,每天买两顿,周死晚上出去吃,周六额外买1.5斤14.8一斤的猪肉... 这时候你打算怎么办呢,是不是 ...
- iconv内容,convmv文件名,unix2dos,dos2unix文件格式转换,od/cut/wc/dd/diff/uniq/nice/du等命令,linux文件名乱码,文件名,文件内容,vim编码设置
1.enconv文件名编码转换,比如要将一个GBK编码的文件转换成UTF-8编码,操作如下 enconv -L zh_CN -x UTF-8 filename enconv -L GB2312 -x ...
- Centos 7中 vim 中文乱码
参考:http://www.myexception.cn/operating-system/1534005.html 一. sudo vim /etc/vimrc 在文件中加入如下几行: s ...
- 【转】vim文件编码和乱码处理
原文网址:http://edyfox.codecarver.org/html/vim_fileencodings_detection.html 在 Vim 中,有四个与编码有关的选项,它们是:file ...
- Vim 实用技术,第 1 部分: 实用技巧(转)
原文链接:http://blog.jobbole.com/20604/ 0. Vim 简介 作为开源世界最重要的编辑器之一(另一个是 Emacs),Vim 以其强大的功能和可定制能力被众多开发者所喜爱 ...
- 转 :Vim文件编码识别与乱码处理
Vim文件编码识别与乱码处理 在 Vim 中,有四个与编码有关的选项,它们是:fileencodings.fileencoding.encoding 和 termencoding.在实际使用中,任 ...
- VIM 文件编码识别与乱码处理(转载)
在 Vim 中,有四个与编码有关的选项,它们是:fileencodings.fileencoding.encoding 和 termencoding.在实际使用中,任何一个选项出现错误,都会导致出现乱 ...
- VIM显示utf-8文档乱码解决方法
1.相关基础知识介绍 在Vim中.有四个与编码有关的选项,它们是:fileencodings.fileencoding.encoding和termencoding. 在实际使用中.不论什么一个选项出现 ...
- VIM使用系列: 复制并移动文本
1 5. 复制并移动文本 *copy-move* 2 3 *quote* 4 "{a-zA-Z0-9.%#:-"} 指定下次的删除.抽出和放置命令使用的寄存器 5 {a-zA-Z0 ...
随机推荐
- 使用 quartz-solon-plugin 开发定时任务(新)
(一)新建一个 maven 空项目 (二)添加 maven 引用 <dependency> <groupId>org.noear</groupId> <art ...
- Python 基于深度学习的 opencv 车牌识别系统,可以准确识别车牌号
大家好,我是程序员徐师兄,6 年大厂程序员经验,点击关注我 简介 毕业设计基于Opencv的车牌识别系统 车牌搜索识别找出某个车牌号 对比识别车牌系统 车牌数据库认证系统 车牌图文搜索系统 车牌数据库 ...
- 解决延迟有 Wi-Fi 6 就够了!
最近二狗子家里的路由器坏了,而家里的数据网络信号又非常差,失去了路由器基本上就等于和世界隔离,所以二狗子打算去附近商城随便买一个新的路由器,结果售货员张口就问:"买 Wi-Fi 6 的路由器 ...
- MIGO生产订单入库写入批次特性增强
一.生产订单入库 MIGO根据生产订单入库时,将生产订单中的字段,写入到批次特性中 二.BADI:MB_MIGO_BADI 调用BADI中的IF_EX_MB_MIGO_BADI~POST_DOCUME ...
- stm32f103 rt-thread fal easyflash移植过程
需求:使用Stm32F103片内Flash进行数据存储 硬件平台:Stm32F103C8t6(由于Stm32F103C8t6的Flash标注为64k实际为128K,64KFlash在使用rt-thre ...
- P1802-DP【橙】
1.又是一道因为写了异常剪枝而调了好久的题,以后再也不写异常剪枝了,异常情况压根不该出现,所以针对出现的异常情况进行补救的异常剪枝是一种很容易出错的行为,做为两手准备也就罢了,但第一次写成的代码必须能 ...
- 万字血书Vue-Vue进阶
Vue进阶 生命周期 组件运行的过程 组件的生命周期是:组件从创建->运行(渲染)->销毁的整个过程,是一个时间段 如何监听组件的不同时刻 vue框架为组件内置了不同时刻的生命周期函数,是 ...
- kafka 的基本概念及使用场景
本文为博主原创,未经允许不得转载: 1. Kafka 的使用场景: 1.日志收集:一个公司可以用Kafka收集各种服务的log,通过kafka以统一接口服务的方式开放给各种 consumer,例如ha ...
- 在线P图工具(基于minipaint开发)
在浏览github过程中,发现一个超级实用的仓库,viliulsle开发的minipaint,类似于photoshop的网页版.基于webpack开发的,打包非常简单,故自己搭建了一套. 在线预览 在 ...
- SV 接口中的clocking
接口 module可以例化模块,可以例化接口 接口不能例化模块 采样和数据驱动 时钟驱动数据,数据会有延迟,RTL仿真的时候,不会仿真出这个延时;RTL仿真的时候,不会仿真出寄存器的延时;只有在门级仿 ...