Vim复制内容到系统剪切板

查看 Vim 是否支持clipboard

Vim 需要安装带有图形化的版本才会有 clipboard 支持,或重新从源码编译安装

1
vim --version | grep "clipboard"

clipboard 前面有减号(-),说明不支持,+ 表示支持。

Vim 寄存器

Vim 提供了 10 类寄存器,可在 Vim 中通过 :help registers 查看帮助。

查看寄存器内容,在vim中执行

1
:reg
  • 匿名寄存器 : ""

  • 编号寄存器 : "0"9

  • 小删除寄存器 : "-

  • 26 个命名寄存器 : "a"z

  • 3 个只读寄存器 : ":, "., "%

  • Buffer 交替文件寄存器 : "#

  • 表达式寄存器 : "=

  • 选区和拖放寄存器 : "*, "+, "~

  • 黑洞寄存器 : "_

  • 搜索模式寄存器 : "/

匿名寄存器

使用 d, c, s, x 等会删除字符的命令时,被删除字符会进入匿名寄存器 ""。 你可以认为 "" 寄存器是一个指针,指向刚才被存到的寄存器。

如何用 Vim 搭建 IDE ? 一文中提到,Mac 下可通过下列设置来让 Vim 共享系统剪切板, 就是这个原理:所有删除和拷贝操作默认都会到匿名寄存器。

1
set clipboard=unnamed

使用 y 命令未指定寄存器会存到 "0 寄存器中,同时 "" 会与该寄存器保有同样的值。 这意味着你使用 p"p 总会得到同样的结果。

编号寄存器

编号寄存器从 "0"9 共 10 个,其中 "0 保存着拷贝来的字符串,"1"9 保存着删除掉的字符串。

删除操作符包括 s, c, d, x,删除掉的字符串会被存到 "1 中,上次删除的则会被存到 "2 中。以此类推,Vim 会保存最近 9 次的删除。

  • 只有整行整行的删除,和通过段落级别的移动指令(包括 % , ( , ) , / , ` , ? , n , N , { , }) 的删除才会被放到 "1 中。
  • 当用户指定拷贝操作的寄存器时(如 "ap),"0 不会被写入;但删除操作一定会被写入到 "1 中。

"0 寄存器很有用,比如我们 copy 了一段文本然后用它替换另一段文本。 这时默认寄存器 "" 中的值就会与被替换的内容进行交换,如果还需要用 copy 的文本继续替换的话就需要 "0p 了。

小删除寄存器

不足一行的小删除则会被放到小删除寄存器中("-),起作用的删除操作符也包括 s, c, d, x。 例如:

1
2
3
dw    # 删除一个词
d9l # 删除9个字符
cb # 向前更改一个词

"0 寄存器类似,当用户指定寄存器并进行删除时,"- 不会被写入。

命名寄存器

命名寄存器有 "a"z 共 26 个,这些寄存器只有当我们指定时才会被使用。 其实我们在录制宏时,所有键盘操作会以字符串的形式存到寄存器中。 例如录制一个宏存到 "a 寄存器中,内容为更改当前行 cc,改为 foo 字符串:

1
qaccfoo

然后执行 :reg 来查看寄存器,可以发现 a 寄存器的值是 ccfoo

小技巧:当使用小写字母进行操作时会覆盖当前寄存器内容,当使用大写字母进行操作时,会追加当前寄存器内容

只读寄存器

只读寄存器共 3 个,它们的值是由 Vim 提供的,不允许改变:

  • ".:上次 insert 模式中插入的字符串。还记得吗? . 命令可以重复上次操作,而 ". 存储了上次插入。
  • "%:当前文件名,不是全路径,也不是纯文件名,而是从当前 Vim 的工作目录到该文件的路径。例如此时 Harttle 的 Vim 中,"%p 的结果为 _drafts/vim-registers.md
  • "::上次命令模式下键入的命令。正如 @a 可以执行 "a 寄存器中的宏一样,@: 可以执行上次命令。

交替文件寄存器

交替文件寄存器 "# 存储着当前 Vim 窗口(Window)的交替文件。交替文件(alternate file)是指 Buffer 中的上一个文件,可通过 Ctrl+^ 来切换交替文件与当前文件。

Window 和 Buffer 有什么区别?参见 Vim 多文件编辑:窗口 一文

表达式寄存器

表达式寄存器 "= 主要用于计算 Vim 脚本的返回值,并插入到文本中。 当我们键入 "= 后光标会移动到命令行,此时我们可以输入任何 Vim 脚本的表达式。 例如 3+2,按下回车并且 p 则会得到 5

这在我们调试 Vim 脚本时非常有用,比如调用一个函数看它是否有正确的返回值。

选择和拖放寄存器

选择和拖放寄存器包括 "*, "+, 和 "~,这三个寄存器的行为是和 GUI 相关的。

"*"+ 在 Mac 和 Windows 中,都是指系统剪切板(clipboard),例如 "*yy 即可复制当前行到系统剪切板。 其他程序中复制的内容也会被存储到这两个寄存器中。 在 X11 系统中(绝大多数带有桌面环境的 Linux 发行版),二者是有区别的:

  • "* 指 X11 中的 PRIMARY 选区,即鼠标选中区域。在桌面系统中可按鼠标中键粘贴。
  • "+ 指 X11 中的 CLIPBOARD 选区,即系统剪切板。在桌面系统中可按 Ctrl+V 粘贴。

上文所述的 Mac 下 set clipboard=unnamed 会使得系统剪切板寄存器 "* 和 Vim 默认的匿名寄存器 "" 始终保有同样的值,即 Vim 和系统共用剪切板。

有文本拖拽到 Vim 时,被拖拽的文本被存储在 "~ 中。Vim 默认的行为是将 "~ 中内容插入到光标所在位置。 当然你可以给 <DROP> 做键盘映射。

黑洞寄存器

黑洞寄存器 "_,所有删除或拷贝到黑洞寄存器的文本将会消失。 这是为了在删除文本的同时不影响任何寄存器的值,"_ 通常用于 Vim 脚本中。

搜索寄存器

搜索寄存器 "/ 用于存储上一次搜索的关键词。Vim 中如何进行搜索呢? 在 normal 模式下按下 / 即进入 search 模式,输入关键字并按下回车即可。

该寄存器是可写的,例如 :let @/ = "harttle" 将会把 "harttle" 写入该寄存器。 下次搜索时不输入搜索词直接回车便会搜索 "harttle"

命令行模式拷贝

值得一提的时,任何寄存器中的值都是可以拷贝到命令模式下的。

比如对于寄存器 "a 中的值,在 normal 模式下可以通过 "ap 来粘贴;在 command-line 模式下通过 <Ctrl-R>a 来粘贴。这一操作存在风险,因为寄存器中的值可能是从网页中拷贝来的。

如果寄存器中的字符串存在 <Esc> 字符或 <CR> 字符,则会时 Vim 回到 normal 模式, 并继续执行寄存器中的命令。为了防范 剪切板劫持,可以添加下列的 Vim 配置:

1
inoremap <C-r>+ <C-g>u<C-\><C-o>"+gP

该命令的解释请移步:http://vim.wikia.com/wiki/Pasting_registers

原文

与系统剪切板交互

通过寄存器表,可与外部交互的寄存器有 "*"+"~

使用快捷键

“+y“+p的输入挺麻烦的,我们直接为他们创建个快捷键吧

vim创建快捷键的原理可以看 jalused的博客

1
2
3
4
" 支持在Visual(视图)模式下,通过C-y复制到系统剪切板
vnoremap <C-y> "+y
" 支持在normal(一般)模式下,通过C-p粘贴系统剪切板
nnoremap <C-p> "*p
-------------本文结束感谢阅读-------------

欢迎关注我的其它发布渠道