If you've been following my series on Vim, it should be clear now that Vim has a pretty clear philosophy of how text editing should work. It's based on the Unix philosophy of small composable tools, and doesn't necessarily match up with the conventions that other editors use for common commands. So it's probably not surprising that Vim has its own way of handling copy and paste operations, and in fact doesn't even use those terms. Vim's copy and paste handling is minimalist, composable, and powerful, but most people take some time to adjust to it. I'm going to walk through the basics here, along with a few advanced features that are worth knowing about.

The primary Vim commands for copying something are y (yank) which acts like most people's view of copy, and the delete/substitute commands d (delete),c (change), x(single character delete), and s (substitute), which unintuitively all act like the more common concept of "cut". These can be composed with motion commands to select different regions.

Any Vim command that deletes text will also save a copy of that text unless you specifically tell it not too. The idiomatic Vim method of deleting without copying is "_d, which probably sounds bizarre. We'll come back to that later, and you'll see that it makes sense in the bigger scheme of Vim's copy and paste system.

The basic Vim commands for paste are p (put) which pastes after of the current character/line and P which pastes before the current character/line. Vim auto detects whether you've yanked text on a line by line basis or a character by character basis, and pastes accordingly. Basically, if you select only full lines it will paste line by line and not break on the cursor position, if you select any partial lines it will paste at the character level, starting or ending at the current cursor location. Note that p also works in visual mode, where it will replace the current selection.

All of this leads to a very common annoyance for new Vim users. They're editing a document and yank some text. Then they go to a new location, delete a few lines, and hit p to replace them with the copied text. Do you see the problem? The text that is "put" is not what they originally yanked, but instead it's the contents of their last delete action. Obviously this can be worked around by changing the order of the actions, but it's frustrating to users who are used to being able to easily delete without blowing away their paste action. Even more frustrating is when an experienced Vim user comes by and tells them the answer to their problem is to just type"0p instead. Which will in fact put the correct text. So what's going on with the weird syntax for these basic action?

Registers

What we're missing is a clear understanding of how Vim handles copy and paste operations. So let's clarify. Unlike most modern systems, which have a clipboard that holds a single value, Vim can store the values of yank and delete commands in one of many registers. It has 26 normal registers, which correspond to the letters of the alphabet, and several "special" registers. One of those special registers is the default register, which is where yank and delete commands store their content by default. Other registers can be accessed with the "<char> prefix that we've already seen. So in the above example, the text from the initial example is moved into the default register, and then replaced there by the deleted text. But it remains in the 0 register, which always points to the last "yanked" text, ignoring text gained by deleting.

The 26 alphabetical registers serve as great "medium term" storage. You can use them to yank something that you want to have around for a while, and then put it in a few different places, even if you're yanking and deleting other things in the meantime. These will even persist across sessions as long as you have the nocompatible option set in your vimrc file. However if you overwrite one, there's no easy way to get it back.

One cool feature of registers is the built in ability to append to the end of them. If you want to add text to an existing register, for instance if you missed part of the text you wanted to yank, you can do so by capitalizing the register. So if you had deleted a line and put it in thea register with "add, but meant to include a second line, you could then delete the next line and append it to the register with "Add"ap would then put the 2 lines back into the document.

Special Registers

In addition to the alphabetical registers, there are several special registers that are worth knowing about. I already mentioned the default register, which most Vim users know about, even if they don't understand exactly how registers work. Other important registers are the clipboard register, the black hole register, and the numbered registers.

If you have to learn one special register, learn the clipboard register. One of the first things people notice about copy and paste in Vim is that it doesn't interact nicely with other applications' copy and paste by default. If you yank a line of text in Vim, it's not added to the system clipboard. If you copy some code from Stack Overflow and try to paste it in Vim with p, it won't work1. But, since we know about registers, it makes sense that the default register might not be mapped to the clipboard, which we don't want getting blasted away everytime we delete a character.

Vim isn't completely disconnected from the system clipboard though. The clipboard register + is Vim's proxy to your system clipboard. So "+y<motion> and "+p act like traditional copy and paste. Your version of Vim does have to be compiled with clipboard support in order to use the + register. You can check to see if you have clipboard support with :echo has('clipboard').2 On OSX you can use MacVim to get clipboard support, since the default version of Vim shipped with OSX is not compiled with it. On other operating systems you'll have to investigate the easiest way to install with clipboard support if your version doesn't have it. It should be enabled for most modern mainstream distributions.

Another register to quickly note is the black hole register_. The black hole register, as you would expect, doesn't retain what's passed to it. So "_y and "_p are no-ops, and "_d is "true delete", as opposed to the delete commands default "cut" like behavior. Of course since most people don't use all 26 alphabetical registers, you can also achieve effective true delete by deleting to any unused register.

Finally, the number keys also have special register functionality. You can't yank text directly to a numbered register. Instead the 0 register contains the last yanked text, and the 1 through 9 registers contain the last 9 deleted chunks of text. This feature is a cool idea, but unfortunately the implementation is inconsistent and a bit weird. For one thing the distinction between yanked and deleted text seems arbitrary, and since they act the same in other ways, puts an added cognitive load on the user to remember which one they used. Secondly, for whatever reason, deletions that span less than a line get special behavior. If you delete these to an alphabetical register, they're saved to "1 just like any other delete. But if you delete them to the default register, they're saved to "- and not put in "1. The logic is complicated enough that the numbered registers become tough to use in day to day tasks, and I'll have to agree with Drew Neil in labeling them one of Vim's"bad parts."

Macros

One last important thing to know about registers is that along with being used for copy and paste, they serve as a place to save macros, Vim's reusable command language. You can save a macro by typing q<register key><commands>q, and the macro will be saved to the register. Like yank and delete, capitalizing the register name will let you append to the register instead of replacing it. So there's a few things you should know about that. One, if you use macros, don't save macros to the same registers that you use for copy and paste. If you use the y register a lot for the convenience of "yy<motion>, don't use qy to save your macro unless you're ok with it being blown away by your next yank. Two, the sharing of registers allows you to copy text to use as a macro. So if you for instance wanted to have a file with a list of common operations, it would be easy to go to that file, copy a line, and then execute it as a macro. This isn't the first thing most people will want to do, but it illustrates the power and flexibility that come when you start combining Vim's tools.


More Resources

  • For a more in depth look at Vim's special registers, including a bunch I didn't cover here, you can check out this great roundup

  • Vimcasts has a whole series of posts on copy and paste in Vim.


Subscribe

This was the seventh entry in a series of posts on learning Vim in a modern way. If you enjoyed the post, please consider subscribing by using the feedTwitter or my mailing list. Also check out the next post in the series.

  1. Of course some people would probably see that as a feature, not a bug 

  2. Thanks to schweinschmeisser on Reddit for reminding me to add a way to check for support. 

orign url:http://benmccormick.org/2014/07/28/learning-vim-in-2014-copy-and-paste-the-vim-way/

vim 的寄存器的更多相关文章

  1. 终于掌握vim的寄存器和系统剪贴板的使用了- 要安装vim-X11包

    vim的系统剪贴板 vim的 加号寄存器 "+ 是和系统剪贴板 相关联的. 加号寄存器和系统剪贴板之间的内容, 可以互相切换. 要把 加号寄存器中的内容, -> 放到/转移到系统剪贴板 ...

  2. vim的寄存器和剪贴簿操作?

    vim 复制/ 删除 多行? 有确定序号的行: :10,15m20, 10,15co20 没有确定序号的行: ndd, nyy. 其中的n表示, 从当前行开始算起(当前行本身要包含!!!), 向下共删 ...

  3. 了解VIM的寄存器

    VIM下的删除:delete; 复制:yank; 粘帖:put; 都会用到VIM下的相关寄存器,今天就说说这个寄存器的问题: VIM中有多种寄存器:包括: 有名寄存器,用名字("a-&quo ...

  4. vim 计算器寄存器使用

    我们可能会在vim的使用中,碰到下面的情况 当我正在写一周预算的时候,我想计算下每天我买菜花2.7,每天买两顿,周死晚上出去吃,周六额外买1.5斤14.8一斤的猪肉... 这时候你打算怎么办呢,是不是 ...

  5. <转载>Vim的寄存器(复制黏贴要用)

    https://blog.csdn.net/hk2291976/article/details/42196559 消除高亮 :noh

  6. 0050 Linux VIM 命令

    1.  模式切换 vim的模式 $ vi filename 进入normal 模式,这是命令模式,用于执行大多数常用的编辑命令,不能输入 敲i 进入 insert 模式,这是正常的编辑模式,按Esc ...

  7. vim常用命令总结 (转)

    vim 选择文本,删除,复制,粘贴   文本的选择,对于编辑器来说,是很基本的东西,也经常被用到,总结如下: v    从光标当前位置开始,光标所经过的地方会被选中,再按一下v结束. V    从光标 ...

  8. VIM编辑命令的技巧

    vim 选择文本,删除,复制,粘贴   文本的选择,对于编辑器来说,是很基本的东西,也经常被用到,总结如下: v    从光标当前位置开始,光标所经过的地方会被选中,再按一下v结束. V    从光标 ...

  9. 程序员的编辑器——VIM

    from:http://blog.chinaunix.net/uid-11278770-id-148579.html Chinaunix首页 | 论坛 | 认证专区 | 博客 登录 | 注册      ...

随机推荐

  1. thread msg

    提取的nordic rf51xx/rf52xx sdk中的线程间消息通信机制,非常简洁 demo.c #include <stdio.h> #include <stdlib.h> ...

  2. C语言字符串/数组去重

    输入: hello 输出: helo 第一种实现: 不新开数组, 也就是原地去重. #include <stdio.h> #include <string.h> void re ...

  3. Spring基本功能-依赖注入

    一.Spring的依赖注入(DI) 1.1 xml形式注入 (1)普通变量的注入 //普通变量的注入,xml配置property,实体类配置set方法注入 <bean id="pers ...

  4. php 通过http user-agent判断是否为手机浏览器

    <?php/*** 判断是否是通过手机访问* @return bool 是否是移动设备    */public function isMobile() {  //判断手机发送的客户端标志  if ...

  5. hdu5558 Alice's Classified Message

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=5558 题目: Alice's Classified Message Time Limit: 1 ...

  6. TOSCA自动化测试工具--识别元素唯一性的控件

    当Modules模块通过Scan识别出页面元素后,选择需要测试的对象,然后判断对象唯一性

  7. SQL学习笔记之MySQL索引知识点

    0x00 概述 之前写过一篇Mysql B+树学习,简单的介绍了B+数以及MySql使用B+树的原因, 有了这些基础知识点,对MySql索引的类型以及索引使用的一些技巧,就比较容易理解了. 0x01 ...

  8. 一道C++练习题,替换一个字符串里所有实例

    做了一道C++练习题,替换一个字符串里面的所有实例. #include <iostream> #include <string> using namespace std; co ...

  9. HAL编译问题

    1 make:进入目录'/opt/FriendlyARM/tiny4412/android/android-4.1.2'make: *** 没有规则可以创建“out/target/product/ge ...

  10. Ubuntu 12.04下安装QQ 2012 Beta3

    Ubuntu 12.04下安装QQ 2012 Beta3   由于wine的发展非常迅速.现在网上的利用老版本的wine来安装QQ2012的教程已经有些过时了.实际上操作起来非常简单: 第一步:Ctr ...