vim实用技巧|Vim实用技巧_6.复制和粘贴原理(寄存器)

  • 问题:寄存器?vim不是一个程序编辑器吗?怎么还用到了编程中的术语(寄存器)呢?
  • 简单理解:我们平时用的复制、粘贴、剪切都会与剪切板进行交互,在vim里是与寄存器进行交互的
  • 简要总结:
    ddp:是对文本行的剪切与粘贴操作,实际上是调换了两行的顺序
    yyp:是针对行的复制与粘贴操作,即创建一行副本
    "+p:将系统剪切板中的代码或者文字复制到vim中
    "+y:将vim中的代码或者文字复制到剪切板

文章目录
  • 复制和粘贴
    • 技巧059:用无名寄存器实现删除、复制与粘贴
    • 技巧060:深入理解 Vim 寄存器
    • 技巧061:用寄存器中的内容替换高亮选区的文本
    • 技巧062:把寄存器的内容粘贴出来
    • 技巧063:与系统剪贴板进行交互
  • 参考

Vim 的寄存器是一组用于保存文本的简单容器
它们既可像剪贴板那样,剪切、复制和粘贴文本;也可以记录一系列按键操作,把它们录制成宏
复制和粘贴 技巧059:用无名寄存器实现删除、复制与粘贴
Vim 的删除、复制与粘贴命令的设计初衷是帮助人们轻松完成日常工作
接下来,我们将研究几个可用 Vim 无名寄存器轻松解决的问题;最后,我们将看到一个任务,要想完成它,要求我们对 Vim 寄存器的工作原理有更深入的了解才行
剪切、复制与粘贴这 3 组操作时,在 Vim 的术语里,我们操作的是寄存器,而并非剪贴板
part1:调换字符(xp
目的:将两个字符的次序颠倒;下面操作的实用性感觉不大
vim实用技巧|Vim实用技巧_6.复制和粘贴原理(寄存器)
文章图片

part2:调换文本行(ddp
  • 目的:将两行的次序颠倒
  • 实现:是用 dd 命令剪切当前行,从而将其内容存入无名寄存器中,然后p;连起来是ddp
  • 说明:dd不要总是认为是删除,其实是放入无名寄存器了
part3:创建文本行的副本(yyp
  • 目的:想创建一行新的文本,内容与之前某行类似,只有一两处差异。为此,可以先创建一行已有文本的副本,以此作为再加工的模板
  • 实现:有了上面的基础,就明白了,这里直接用yyp命令就行了
ddp:是对文本行的剪切与粘贴操作,实际上是调换了两行的顺序
yyp:是针对行的复制与粘贴操作,即创建一行副本
part4:异常场景:无名寄存器被覆盖
  • 目的:somethingInTheWay替换成collection,修改前的文本如下:
collection = getCollection(); process(somethingInTheWay, target);

  • 思路:复制 collection 至无名寄存器 -> somethingInTheWay
  • 实现步骤(最后一步没有实现效果???看下面的分析)
vim实用技巧|Vim实用技巧_6.复制和粘贴原理(寄存器)
文章图片

yiw:光标一开始就已经位于要复制的单词(collection)之上,yiw 即可将其复制到无名寄存器中
jww:光标移到要粘贴“collection”的位置
diw:在粘贴之前得先清理出一块空白区域,即将 somethingInTheWay 一词删除
P:将无名寄存器的内容粘贴至当前光标前面
  • 问题:somethingInTheWay没有替换成collection???我们做错了什么
  • 原因:当运行 diw 命令时,无名寄存器的内容被覆盖
  • 解决:Vim 的删除、复制与粘贴命令都会用到众多寄存器中的某一个。可以通过给命令加 "{register} 前缀的方式指定要用的寄存器(若不指明,Vim 将缺省使用无名寄存器),详细看技巧60
技巧060:深入理解 Vim 寄存器
Vim 不使用单一的剪贴板进行剪切、复制与粘贴操作,而是为这些操作提供了多组寄存器
当使用删除、复制与粘贴命令时,我们可以明确指定它们中的某一个进行操作
vim中剪切,复制,粘贴的起源如下:
vim实用技巧|Vim实用技巧_6.复制和粘贴原理(寄存器)
文章图片

提示:xd{motion} 经常被当作“删除”命令;这其实是用词不当,把它们理解为“剪切”命令会更合适
part0:引用一个寄存器
可以通过给命令加 "{register} 前缀的方式指定要用的寄存器,下面是一些例子
  • "ayiw:把当前单词复制到寄存器 a 中;之后,可以输入 "ap 粘贴来自寄存器 a 的单词
  • "bdd:把当前整行文本剪切至寄存器 b 中;之后,可使用 "bp 命令粘贴来自寄存器 b 的一整行文本
  • Ex 命令命令也使用,如 :delete c,把当前行剪切到寄存器 c;然后再执行 :put c 命令将其粘贴至当前光标所在行之下
part1:无名寄存器(""
  • 缺省:没有指定要使用的寄存器,Vim 将缺省使用无名寄存器,它可以用双引号表示;例如,""p,它完全等同于 p 命令
  • 修改:xsd{motion}c{motion}y{motion} 命令(以及它们对应的大写命令)都会覆盖无名寄存器中的内容。无论哪一种情况,都可以通过加 "{register}前缀来指定另外一个寄存器
part2:复制专用寄存器("0
使用 y{motion} 命令时,要复制的文本不仅会被拷贝到无名寄存器中,而且也被拷贝到了复制专用寄存器中
  • 提示:只有y{motion}才会修改寄存器0("0),直到我们复制其他文本时才会被覆盖。复制专用寄存器是稳定的,而无名寄存器是易变的(寄存0的内容可以通过:reg "0进行查看)
  • 技巧59中的 无名寄存器被覆盖 解决方法
vim实用技巧|Vim实用技巧_6.复制和粘贴原理(寄存器)
文章图片

Part3:有名寄存器("a"z)和黑洞寄存器
有名寄存器:Vim 提供了一组以 26 个英文字母命名的有名寄存器。这意味着我们可以剪切( "ad{motion})、复制("ay{motion})或者粘贴("ap)多达26 段文本
  • 技巧59中的 无名寄存器被覆盖 解决方法
vim实用技巧|Vim实用技巧_6.复制和粘贴原理(寄存器)
文章图片

  • 小写字母:引用有名寄存器,会覆盖该寄存器的原有内容
  • 大写字母:则会将新内容添加到该寄存器的原有内容之后
黑洞寄存器:是个有去无回的地方,可用下划线。如果我们运行 "_d{motion} 命令,Vim 将删除该文本且不保存任何副本
vim实用技巧|Vim实用技巧_6.复制和粘贴原理(寄存器)
文章图片

part4:系统剪贴板("+)与选择专用寄存器("*
前面讨论的寄存器都是vim内部寄存器,如果想从 Vim 复制文本到外部程序(反之亦然),则必须使用系统剪贴板
  • 外部文本到vim中:使用"+p命令将其粘贴到 Vim 内部
  • 捕获到剪切板:在 Vim 的复制或删除命令之前加入 "+ ,相应的文本将被捕获至系统剪贴板
主剪切板:它保存着上次被高亮选中的文本,可以用鼠标中键(如果有的话)把它们粘贴出来
vim实用技巧|Vim实用技巧_6.复制和粘贴原理(寄存器)
文章图片

part5:表达式寄存器("=
技巧16有介绍
vim实用技巧|Vim实用技巧_6.复制和粘贴原理(寄存器)
文章图片

part6:其他寄存器
可以显式地使用删除与复制命令,来设置有名、无名以及复制专用寄存器的内容, 可以用 :let 命令(参见 :h quote/ )对其进行显式的赋值
Vim 还提供了几组可被隐式赋值的寄存器。它们被称作只读寄存器
vim实用技巧|Vim实用技巧_6.复制和粘贴原理(寄存器)
文章图片

技巧061:用寄存器中的内容替换高亮选区的文本
Vim 的粘贴命令在可视模式下使用时,体现出一些不同寻常的特性。我们将在本节深入挖掘其可用价值
  • 示例1:技巧59中的 无名寄存器被覆盖 解决方法
在可视模式下使用 p 命令时,Vim 将用我们指定的寄存器内容来替换高亮选区中的文本
vim实用技巧|Vim实用技巧_6.复制和粘贴原理(寄存器)
文章图片

效果:直接用ve开启可视模式,且选择一个单词(这个单词会高亮),再用P命令一行会成功
说明:不再把无名寄存器既用于复制又用于删除,因为根本就没有删除这一步;我们把删除和粘贴合成了一步,完成高亮选区的替换(这个方案有在u命令后会有副作用,暂时不影响,就不总结了)
  • 示例2:交换两个词(fish和chips交换)
vim实用技巧|Vim实用技巧_6.复制和粘贴原理(寄存器)
文章图片

说明:不好理解,要对vim很熟练才可以
vim实用技巧|Vim实用技巧_6.复制和粘贴原理(寄存器)
文章图片

技巧062:把寄存器的内容粘贴出来
普通模式下的粘贴命令,根据要插入文本的性质不同,执行结果也不同。确定要粘贴的文本区域是面向行的还是面向字符的,将有助于我们制定不同的策略
在技巧 59 中,我们见识了用 xp 命令调换两字符的次序以及用 ddp 命令调换两行的顺序
问题:p命令旨在将寄存器中的文本粘贴到光标之后,p命令是怎么知道操作的是行还是字符?
这取决于这个指定的寄存器是怎样被赋值的
  • 面向行:复制或者删除操作(例如:dd、yy 或者 dap),将创建面向行的寄存器
  • 面向字符:复制或者删除操作(例如:x、diw 或者 das),则创建面向字符的寄存器
粘贴面向字符的区域
  • 问题:面向字符的文本区域到底是放在光标之前(P)还是之后(p),有时要判断前后也是挺烦的
  • 建议:在插入模式中使用 {register}的映射项,来粘贴面向字符的文本区域,寄存器的文本总会被插入至光标之
# " 来插入无名寄存器的内容 # 0 来插入复制专用寄存器的内容

vim实用技巧|Vim实用技巧_6.复制和粘贴原理(寄存器)
文章图片

粘贴面向行的区域
在复制多行时,结合isip有时效果会很好
vim实用技巧|Vim实用技巧_6.复制和粘贴原理(寄存器)
文章图片

总结:pP 命令对于粘贴多行文本区域非常重要;对于小段的、面向字符的文本来讲,使用 {register} 映射项的方式
技巧063:与系统剪贴板进行交互
除了 Vim 内置的粘贴命令,我们有时也要用到系统粘贴命令。但当 Vim 在终端内部运行时,使用该命令经常会产生意外的结果。为了避免这些问题,可在执行系统粘贴命令之前激活 ‘paste’ 选项
本节所介绍的技巧只适用于在终端内运行 Vim 的情况
  • 是否支持?
1.看看自己的计算机的vim版本(-clipboard表示不支持) # vim --version | grep clipboard2.解决办法(安装完成之后再利用代码检查一次,出现“+clipboard”表示vim没有问题) # sudo apt install vim-gtk

  • 复制
复制(常识:系统剪贴板("+)) # 将vim中的代码或者文字复制到剪切板 "+yy"+nyy # 将系统剪切板中的代码或者文字复制到vim中 "+p"+P

【vim实用技巧|Vim实用技巧_6.复制和粘贴原理(寄存器)】系统的粘贴命令:在 OS X 中,Cmd-v 映射会触发系统粘贴命令;Linux 平台改进的 Ctrl-v 版本用于从系统剪贴板中粘贴文本。也许是 Ctrl-Shift-v,或者是 Ctrl-Alt-v
参考
  • 《Vim实用技巧》

    推荐阅读