如何简化Vim中的“复制和粘贴”操作?

24

我发现在VIM中复制和粘贴的过程有些棘手:

  • 进入可视化模式(Visual mode)
  • 按下Y键
  • 按下p键(或shift+p)
  • 进入插入模式(insert mode)

如果你不小心按下了“删除”键,你会丢失内容(它被你删除的字符所替代),你需要重新复制一遍!

我已经使用Vim工作了几个月,我很喜欢它,但是复制和粘贴机制让我感到烦恼。

有没有一种简化它的方法?或者还有其他更简单的替代方案吗?

谢谢


1
无需进入可视模式复制。只需使用“Yp”即可复制和粘贴当前行。 - Rajendran T
1
我认识Rajendran,但是就像我说的那样,当你编辑时可能会使用“删除”按钮,导致内容丢失,因此您需要重新复制它(无论如何,您都必须进入命令模式进行粘贴:Esc + y + p + i(返回插入模式))。 - Alessandro De Simone
是的 :) 我已经多次感受到这种不便。 - Rajendran T
8个回答

20

Vim会在编号寄存器中维护最近的9次删除记录。因此,"0p将粘贴您最近复制的内容,"1p将粘贴第二新的删除或更改记录(请注意,这不包括仅复制的文本),依此类推,直到寄存器2-9。

如果您想使用超过最近9个删除项目或者想要一种方便地访问以前复制的方法,我建议使用yankring插件。除其他外,该插件还可以查看最近100个复制项,并使用:YRShow命令选择要粘贴的内容。

最后,如果您想在不离开插入模式的情况下粘贴,则可以使用Ctrl-R插入任何寄存器的内容。因此,在插入模式下键入<Ctrl-R>"将插入未指定寄存器时放置复制的文本的无名寄存器"的内容。


3
你是不是指的是“0p”,“1p”等? - Herbert Sitz
3
我已经使用 gVim 几年了,但是编号寄存器和 Ctrl-R 对我来说都不太熟悉。+1 - johnny
我知道Ctrl-o,但不知道Ctrl-R。谢谢你告诉我。+1 - Jason Down
1
"0p会粘贴您最近复制的内容,而不是复制并删除的内容。 "1p将为删除执行此操作,仅适用于已删除的内容,对"2p(第二个最近删除的内容)等也适用。您可以在:h quote_number中找到此信息。 - ZyX
我从未想过复制和粘贴可以是如此广泛和精确的工具。 - eusid

11

虽然并不是“简化版”,但您可以选择将文本复制到与默认删除文本所在的不同寄存器中。这样,当您意外删除某些内容时,就可以保护您复制的内容,避免丢失。

例如,要复制到寄存器a,您需要执行以下操作:

" a y [移动命令]

然后,要粘贴文本,您需要执行以下操作:

" a p

还有一件事可以做。如果您希望在插入模式下粘贴,可以按ctrl+o,然后输入您的粘贴命令(例如我上面提到的寄存器粘贴命令)。ctrl+o命令等同于按下esc,但只能用于一个单独的命令。在这里了解更多信息。

最后,您总是可以选择编写一个vim脚本来更改默认行为以满足自己的需求(或者找到一个插件,例如yankring)。


更新

根据与kellogs在评论中的交谈,我决定研究如何在视觉模式下使用任何寄存器进行复制/粘贴操作(更容易看到您要获取的内容)。结果证明这是可能的。

要将内容复制到寄存器a,但在视觉模式下:

v(进入视觉模式)

然后执行上述相同的操作,但首先执行移动命令:

[移动命令] "ay(通过移动命令突出显示您的选择,然后将其复制到寄存器a中)。

粘贴的方式与上述更新中列出的方式相同。


不确定为什么它对你不起作用。我刚打开了一个随机文本文件,移动到任意一行并输入了以下内容:" a y 2 w,这从我的当前光标位置提取了2个单词并将它们存储在寄存器a中。然后我可以通过 " a p 进行粘贴(尝试在几个位置进行,包括同一文件、新选项卡、不同的现有文件)。 - Jason Down
我可能想要重试。有没有视觉确认? - kellogs
不完全是这样。在我的例子中,它与您只键入“y 2 w”(复制两个单词)并使用默认寄存器而不是寄存器“a”的情况相同。您的光标会改变形状(在我的GVIM版本中),并显示状态行中所有按键。一旦您按下最后一个按键(在本例中为“w”),它将光标恢复为正常状态。 - Jason Down
确实可以工作。但是没有可视化模式相当麻烦 :/ - kellogs
很棒。更好的是 - 只需在可视模式下使用箭头,然后键入“a y”和“a p”。 - kellogs
显示剩余2条评论

8

Vim在删除某些内容时并没有完全丢弃复制的文本,它只是覆盖了"寄存器。上一个复制的文本始终存储在寄存器0中,因此您可以将工作流程中的p替换为"0p,或者更好的方法是将其映射到,p并使用:

nnoremap ,p "0p
xnoremap ,p "0p

另一种方法是丢弃已删除的文本(将其删除到黑洞寄存器_):"_dd"_x等。我个人使用,d映射来实现此功能:
nnoremap ,d "_d
xnoremap ,d "_d

在这种情况下,Vim不会覆盖任何寄存器。

第三种方法是使用字母寄存器,正如@Jason Down建议的那样。


不错的想法。为了完整起见: nnoremap,D“_D xnoremap,D“_D nnoremap,x“_x xnoremap,x“_x - Magnus

2
对我来说,最简单的解决方案是创建一个键盘组合映射,可以模态地切换此删除副作用的开或关。
使用我的脚本,我键入“,,”进入“无副作用”模式,因此删除文本不会影响我的复制缓冲区,因此我可以自由高效地进行复制-删除-粘贴。完成后,再次键入“,,”,vim会恢复其默认行为并带有删除键副作用。
我发现这个解决方案非常理想,因为我不需要每次想要复制粘贴时都考虑缓冲区。请参见此处的脚本:vim toggling buffer overwrite behavior when deleting

2
当我不想改变模式时,我只需使用系统剪贴板进行复制和粘贴。
或者,如果我只是从上一行复制字符,我可以使用 CTRL-Y
如果您想要从缓冲区中的其他位置复制整行内容,请输入前几个字符并使用CTRL-X CTRL-L
更多信息请参见:

1
Vi(和Vim)与普通文本编辑器(如Gedit)的工作方式非常不同。 它也具有相当陡峭的学习曲线。 如果要学习一些基本命令,请从此交互式教程开始。但是,为了回答您的问题。系统剪贴板的内容可以通过加号寄存器进行访问。因此,要从系统剪贴板中粘贴某些内容,您可以在Normal模式下按: "+p(不同时,而是一个接一个)。

1

没有太多可以简化的 - 这就是 Vim 的工作方式。嗯,或多或少。

然而,关于您删除(因此替换寄存器内容)的问题 - 您可以使用 YankRing 作为例子。它为 Vim 的复制/粘贴操作提供了一些“用户友好性”。


它是如何工作的?

您进入第一行,并将其拖动(在Windows术语中为“复制”)。 然后,您转到第二行并再次拖动。 然后,您转到第七行并也将其拖动。

然后,您可以去任何地方并粘贴!您会得到最后一个(第七)行。 按下快捷键,最后一个粘贴将被替换为先前的拖动(第二行)。 再次... 第一行 :)

因此,在这种方式下,您不必担心丢失已拖动的内容,这是我所理解的您的主要问题。


0

事情在于,您不应该“返回插入模式”。

编辑(拷贝、删除、替换等)是在正常模式下完成的,插入模式仅用于输入文本。

如果您处于插入模式并想要重复使用文档中已经存在的某些文本,则可以按以下键:

  • <C-n><C-p> 插入以光标左侧字符开头的单词
  • <C-x><C-l> 插入以光标左侧字符开头的行

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接