5 分钟 Vim:复制、剪切、粘贴、寄存器以及如何使用它们

2025-06-07

5 分钟 Vim:复制、剪切、粘贴、寄存器以及如何使用它们

本文最初发布于barbarianmeetscoding.com。抱歉,耗时约 5 分钟。😊

在这 5 分钟的 Vim 精彩内容中,我们将学习如何利用 Vim 寄存器和一个酷炫的插件,在 Vim 中高效地复制、剪切和粘贴内容。开始吧!

复制粘贴。听起来没什么意思,对吧?你可能习惯用鼠标选择文本,然后复制或剪切,最后粘贴到其他地方。就是这样,没什么好兴奋的。

Vim 通过以下几种方式增强复制、剪切和粘贴的功能:

  1. 它为你提供了新的闪亮操作符和命令,你可以将它们与迄今为止学到的所有动作结合使用
  2. 它提供了一些寄存器,您可以在其中保存内容以供以后粘贴,从而实现有趣的工作流程

复制和粘贴的两个主要命令是yp。您可能想知道为什么**c ycopy不使用 和?好吧,如果您熟悉 Vim,您可能知道c已被占用,它是更改命令。因此,vi 工程师必须想出一种合适的方式来描述复制,并确定了y ank 这个丰富多彩的名称(因为工程师比乍一看的人们想象的要有趣得多)。因此在 Vim 中您不是复制东西,而是抽出它(很棒的命名......如此直观)。p代表put,因此在 Vim 中,您从某处抽出一些文本并将其放在其他地方。如果您习惯于p从粘贴的角度来思考,那么请随意使用任何让您高兴的助记符。

从现在开始,我不会说“复制”,而是说“猛拉”,这样你就能习惯它,并能轻松地在大脑和肌肉记忆中将它与字母联系起来y。猛拉!猛拉!猛拉!

y是一个运算符。你可以将它与我们学过的任何动作和文本对象组合,随心所欲地提取内容:

  • yl 一封信
  • yaw y anks 一个
  • yas 拉恩克斯句子
  • yi( y感谢其中的一切(等等...

如果同时使用yas in ,yy则会得到一个类似and 的逐行操作符,并拉出整行。该命令也会拉出整行。ddccY

为了粘贴内容,您可以使用该p命令及其变体:

  • p在光标后粘贴内容
  • P在光标前粘贴内容
  • gp相同,p但将光标放在粘贴的选择之后
  • gP相同P,并将光标放在粘贴的选择之后

Vim 中的粘贴功能比较特殊, 和 的行为p取决于P你复制的是字符还是行。如果你复制的是字符,那么粘贴会将这些字符放在光标之后或之前(这并不奇怪)。然而,如果你复制的是,那么粘贴会将这些行放在光标所在行之后或之前。这种行为乍一听可能有点奇怪,但在实际操作中却很有意义。

想象一下,你正在思考一段古代文献中强有力的摘录:

Hither came Conan, the Cimmerian, black-haired, sullen-eyed, sword in hand, a thief, a reaver, a slayer, with gigantic melancholies and gigantic mirth, to tread the jeweled thrones of the Earth under his sandaled feet.
Enter fullscreen mode Exit fullscreen mode

如果你想要给这段文字增添更多的强度,你可以决定抽出一些the粒子并将其散布到各处:

v
Hither came Conan, the Cimmerian, black-haired, sullen-eyed, ...
Enter fullscreen mode Exit fullscreen mode

首先跳转到具有的粒子f,w

       v                  v
f,w    Hither came Conan, the Cimmerian, black-haired, ...
Enter fullscreen mode Exit fullscreen mode

然后提取带有 的单词yaw,跳转到下一个放置带有 的位置粘贴;w带有P

                         v                 v
;w    Hither came Conan, the Cimmerian, the black-haired, ...
Enter fullscreen mode Exit fullscreen mode

然后再次跳转到下一个位置;w并输入.以重复上次的更改:

Hither came Conan, the Cimmerian, the black-haired, the sullen-eyed, ...
Enter fullscreen mode Exit fullscreen mode

想复制一行吗?只需输入 即可yyp。想象一下,你有一个 JavaScript 数组字面量,里面充满了神奇的元素:

const chest = [
  {name: 'sword', weight: 2.1, state: 'well kept'},
  {name: 'rusty dagger', weight: 0.4, state: 'worn out'},
];
Enter fullscreen mode Exit fullscreen mode

现在你想在这个箱子里添加更多物品。你可以使用任何现有物品作为模板,然后键入yyp以下内容进行复制:

const chest = [
  {name: 'sword', weight: 2.1, state: 'well kept'},
  {name: 'rusty dagger', weight: 0.4, state: 'worn out'},
  {name: 'rusty dagger', weight: 0.4, state: 'worn out'},
];
Enter fullscreen mode Exit fullscreen mode

然后输入ci'将其名称更改为其他内容:

const chest = [
  {name: 'sword', weight: 2.1, state: 'well kept'},
  {name: 'rusty dagger', weight: 0.4, state: 'worn out'},
  {name: 'scepter of fire', weight: 0.4, state: 'worn out'},
];
Enter fullscreen mode Exit fullscreen mode

想要复制一行吗?(是的,我确信这是个真正的词)只需输入 即可yy{count}p没错!计数也适用于复制和粘贴,因为它们只是命令!让我们重试上面的例子,但这次输入yy5p

const chest = [
  {name: 'sword', weight: 2.1, state: 'well kept'},
  {name: 'rusty dagger', weight: 0.4, state: 'worn out'},
  {name: 'rusty dagger', weight: 0.4, state: 'worn out'},
  {name: 'rusty dagger', weight: 0.4, state: 'worn out'},
  {name: 'rusty dagger', weight: 0.4, state: 'worn out'},
  {name: 'rusty dagger', weight: 0.4, state: 'worn out'},
  {name: 'rusty dagger', weight: 0.4, state: 'worn out'},
];
Enter fullscreen mode Exit fullscreen mode

哇!令人印象深刻,不是吗?

好的。那么y,如果 yank 命令复制了一些东西……那如何在 Vim 中剪切东西呢?啊哈!惊喜来了!

在 Vim 中剪切内容

你可能熟悉Vim 中的d(delete) 和c(change) 命令?顾名思义,它们可以在 Vim 中删除更改文本。但鲜为人知的是,除了删除和更改文本之外,它们还可以剪切文本。

想象一下,除了chest我们之前拥有的一切之外,现在我们还有一位勇敢的冒险家,准备探索世界,直面危险。可惜的是,我们的冒险家几乎一无所有,甚至缺少许多她赖以生存的冒险工具:

const chest = [
  {name: 'sword', weight: 2.1, state: 'well kept'},
  {name: 'rusty dagger', weight: 0.4, state: 'worn out'},
  {name: 'rusty dagger', weight: 0.4, state: 'worn out'},
];

const sonja = {
  name: 'Sonja',
  inventory: [
  ],
};
Enter fullscreen mode Exit fullscreen mode

让我们给她一些帮助,将保存完好的剑从箱子中移到她的库存中:

v
const chest = [
  {name: 'sword', weight: 2.1, state: 'well kept'},
  {name: 'rusty dagger', weight: 0.4, state: 'worn out'},
  {name: 'rusty dagger', weight: 0.4, state: 'worn out'},
];
Enter fullscreen mode Exit fullscreen mode

我们输入2jdd以下两行并删除(并切断)我们的剑:

const chest = [
  v
  {name: 'rusty dagger', weight: 0.4, state: 'worn out'},
  {name: 'rusty dagger', weight: 0.4, state: 'worn out'},
];
Enter fullscreen mode Exit fullscreen mode

然后/in<ENTER>将光标移动到inventory

const sonja = {
  name: 'Sonja',
  v
  inventory: [
  ],
};
Enter fullscreen mode Exit fullscreen mode

现在我们输入内容p并准备开始冒险:

const sonja = {
  name: 'Sonja',
  inventory: [
  v
  {name: 'sword', weight: 2.1, state: 'well kept'},
  ],
};
Enter fullscreen mode Exit fullscreen mode

现在您可以保存文件,如果您有自动格式化程序设置,它将修复您的缩进,或者您可以键入==以手动格式化该行。

Vim 中的剪切粘贴还能做什么?你是否遇到过打字错误,需要交换两个字符的情况?输入dlp(或xp)。想交换几行?输入ddp想交换几个段落?输入dapp

太棒了!现在你已经提升了 Vim 中拖拽、剪切和粘贴的知识。但还有一个关键元素我们还没讲到:强大的寄存器

一个展示寄存器影响的绝佳方法是在 Vim 中交换两个值。我经常会做类似这样的操作。

想象一下,您有几个 CSS 变量,它们代表您刚刚设计的漂亮网站的颜色主题中的几种颜色:

:root {
  --red: #0F0;
  --green: #F00;
}
Enter fullscreen mode Exit fullscreen mode

你很快就发现颜色不对。你把它们弄混了。红色弄成了绿色,绿色又弄成了红色。糟糕!怎么办?

所以你尝试用我们刚刚学到的知识来交换它们。你输入/#<Enter>并将光标放在十六进制值的上方:

  --red: #0F0;
         ^
Enter fullscreen mode Exit fullscreen mode

你用以下方法剪断它daW

  --red:
       ^
Enter fullscreen mode Exit fullscreen mode

键入n以移动到下一个十六进制值,用 删除它daW并尝试用 粘贴红色p,但是......

:root {
  --red:
  --green: #F00;
}
Enter fullscreen mode Exit fullscreen mode

什么!?这完全出乎我的意料。我做错了什么?

您可能在执行示例时注意到了此交换的问题,但如果还没有,我会告诉您:问题在于删除操作也会剪切。当我们在上一步删除绿色的十六进制值时,我们实际上覆盖了红色的十六进制值。这就是为什么当我们p在最后输入时,粘贴的字符会出现问题,#F00而不是#0F0我们最初预期的那样。

但我们究竟覆盖了什么呢?大多数系统都有剪贴板的概念,它可以用来存放你复制和剪切的内容。Vim 没有剪贴板,Vim 有寄存器

Vim 寄存器

Vim 寄存器相当于剪贴板,但由于您拥有大量寄存器,因此它们的功能更加强大。

y当我们使用诸如、dc类的命令时,p我们正在与 Vim 的未命名寄存器进行交互。不过,你并不局限于这一个,你还有 26 个命名寄存器,每个字母对应一个,你可以随意使用它们。

明确访问给定寄存器的方式是在命令前加上前缀"[a-z]。因此:

  • "ayy将一行写入a寄存器
  • "adda在登记册上划一条线
  • "apa从登记册粘贴

使用相同的模式,我们可以访问那个神秘的未命名寄存器,它毕竟有名字。它的名字是 ,如果你想写得更多,"也可以用 来代替y。但我们不会这么做。""y

使用命名寄存器的小写名称会覆盖其内容,而如果我们使用该名称的大写版本,我们将把我们提取或剪切的内容附加到寄存器中(当我们想要将文本收集到寄存器中以便以后粘贴时,这非常有用)。

使用命名寄存器提供了一种方法来解决我们之前交换颜色时遇到的问题。与其单独使用未命名寄存器,不如将它与以下a寄存器结合使用:

  1. /#<Enter>将光标移动到第一个十六进制值
  2. daW剪切未命名寄存器中的绿色值
  3. n移动到第二个十六进制值
  4. "adaW将其切入a命名寄存器
  5. p将第一个十六进制值粘贴到写入位置
  6. k上升
  7. "ap现在从收银机粘贴a​​,我们就完成了

太棒了!如果您忘记了将数据放入哪个寄存器,可以使用:registers(或:reg)命令。它:registers会将所有寄存器的值打印到缓冲区中。如果您只对特定寄存器的内容感兴趣,也可以将其指定为参数。例如,在上一个示例之后输入:reg a将得到以下内容:

--- Registers ---
"a    #F00;
Enter fullscreen mode Exit fullscreen mode

与命名寄存器交互的另一种有用方法是利用大写命名寄存器附加到寄存器而不是替换其内容这一特性。例如,我们可以通过不断将标题附加到a寄存器来构建 Markdown 文档的大纲:

  • /^#.*<ENTER>跳转到下一个标题
  • "ayy将标题复制到a寄存器中
  • n跳转到下一个标题
  • "Ayya将标题附加到寄存器的内容
  • 然后n直到"Ayy你收集了所有你想要的标题
  • "ap粘贴 Mardown 文档的大纲

除了命名寄存器和未命名寄存器之外,还有更多有时会有用的寄存器:抽出寄存器0)、删除寄存器1-9)和黑洞寄存器_)。

复制寄存器 保存0着你复制的最后一段文本。也就是说,它只存储你使用该y命令复制的文本,并且完全不受 或 等剪切操作的影响。如果你想重命名变量dc其他文本片段,这非常有用。使用复制寄存器提供了另一种交换值的方法。

删除寄存器 1-9九个寄存器组成,用于保存您剪切或删除的最后九段文本。它们像一个队列一样工作,每次剪切内容时,它都会被卡在队列的 位置1,之前的内容1会被推送到位置2,依此类推。当您删除了之前的内容并想将其恢复时,删除寄存器非常有用(事实上,它刚刚让我避免了丢失一段写得很美的段落)。就像命名寄存器和复制寄存器一样,您可以利用删除寄存器作为交换值的另一种方式。

黑洞寄存器的名字很贴切,因为它确实能让你彻底删除文本。避免覆盖未命名寄存器的一个好方法是在删除操作符前加上黑洞寄存器:例如,输入"_daw即可将一个单词彻底删除。

要查看 Vim 中所有可用寄存器的列表以及如何使用它们,请查看:h registers

在 Vim 内部和外部复制和粘贴

到目前为止,我们讨论的所有内容都仅适用于 Vim。我们看到的所有命令和寄存器都只允许你在 Vim 内部进行文本的提取、剪切和粘贴。当你想在 Vim 外部复制或粘贴时会发生什么?例如,当你在 StackOverflow 上发现一段精彩的代码并想在程序中尝试它时?

有两个寄存器作为 Vim 与外界之间的接口寄存器+*

  • 您可以使用+寄存器与 Windows、Mac 和 Linux 中的系统剪贴板进行交互
  • 您可以使用*寄存器与 Linux 中的主剪贴板进行交互,也可以与 Windows 和 Mac 中的系统剪贴板进行交互(因为这两个只有一个剪贴板)

我发现一个非常方便且建议你做的是让系统剪贴板使用未命名的寄存器。这样你就可以在 Vim 和计算机的其他部分之间无缝地复制和粘贴,充分利用最快的命令dcyp而不必指定+*寄存器。

如果您使用 Neovim,则可以在vimrc中启用此行为,如下所示:

set clipboard+=unnamedplus " use system clipboard
Enter fullscreen mode Exit fullscreen mode

同样在传统的 Vim 中:

set clipboard=unnamed " use system clipboard
Enter fullscreen mode Exit fullscreen mode

查看:h clipboard更多信息。

在插入模式下粘贴

本文主要介绍如何在普通模式下复制粘贴内容。不过,有时在插入模式下粘贴内容也会很有帮助。之前您学习了如何使用 命令进行粘贴,但在插入模式p下无法执行此操作(它只会插入字母)。该怎么办?在某些情况下(例如 gvim 和 mvim),您或许可以使用系统的复制/粘贴键绑定,但您始终可以依赖 来从任何给定的 粘贴文本p<C-R>{register}register

  • <C-R>aa粘贴寄存器的内容
  • <C-R>"粘贴未命名寄存器的内容
  • <C-R>0粘贴复制寄存器的内容。

是的,你猜对了,R代表 Register”。用它作为助记符,你永远不会忘记如何在“插入”模式下粘贴内容。

一个非常酷的插件,可以简化 Vim 中的寄存器操作

在我们结束之前,这里有一个非常酷的插件,可以帮助你在 Vim 中使用寄存器:vim-peekaboo。这个插件可以在普通模式和插入模式下扩展,"这样@<CTRL-R>就可以在执行复制、剪切或粘贴操作时看到寄存器的内容:

Vim 用户利用 peekaboo 插件在粘贴之前检查寄存器中的内容

很酷吧?

今天就到这里!保重,祝您拥有美好的一天!

文章来源:https://dev.to/vintharas/5-minutes-vim-copying-cutting-pasting-registers-and-how-to-tame-them-5703
PREV
5 分钟 Vim:学习使用 Vim 帮助
NEXT
WebPack:从零开始到生产环境 第一部分 Webpack:入门