有办法删除在vim不覆盖你的最后yank?

我喜欢vim,但一个常见的问题是:

  • 拉起一条线
  • 去你想粘贴的地方
  • 删除已有内容
  • 粘贴你的yank,却发现它粘贴了你刚刚删除的内容

显然,工作流是先删除,再删除。但是如果我没有到,那就太好了。有人有诀窍吗?vim是否有一个工作良好的粘贴缓冲区,或者是否有一个我可以更改的.vimrc设置?

60181 次浏览

传递到_寄存器,即黑洞。

删除一行而不将其插入寄存器:

"_dd

另见:help registers

这可能是最安全的,如果你想要一遍又一遍地粘贴某个东西,把它拉到一个“命名”寄存器中。

"aY

将一行插入a寄存器。用"ap粘贴它。

你可以使用寄存器:"<register><command>

例如:

这将把一行插入寄存器a,删除另一行,然后粘贴寄存器a

"ayy` (move) `dd"aP

对于你的具体问题是问,你不能交换最后两步的顺序吗?

  • yank line (相同)
  • 移动到新位置(相同)
  • 粘贴拖拽行(第四步)
  • 删除你不想要的行(是第三步)

当然,我通常使用命名寄存器来处理这类事情,但有时解决方案比最初想到的要简单。

我使用下面的映射使删除黑洞寄存器更容易一些:

nnoremap R "_d

这样,dd变成了Rdd$变成了R$。注意,R通常被绑定进入替换模式,但我发现我从未使用过它,所以它是“真正删除”功能最容易记住的键。

另一种可能性如下:

  1. 像平常一样拉你的线
  2. 转到你想要粘贴它们的地方,进入可视线条模式(V)
  3. 选择要替换的行
  4. p粘贴你的行。

这也有额外的好处,缓冲区是“交换”的。替换的内容,我觉得很方便

你也可以尝试以下脚本:在vim.org/scripts/替换withregister

你的被拉拽的行应该仍然在寄存器0中。所以做

"0p

粘贴这一行(并随时删除)

我写了这个插件(yankstack.vim)来解决这个问题。它为vim提供了类似Emacs的杀人戒指的东西。您可以删除或删除多个内容,进行粘贴,然后在删除/删除文本的历史记录中来回循环。我发现这比记住我把东西放进哪个寄存器要容易得多。

在我的.vimrc中,我有这些映射:

nmap <M-p> <Plug>yankstack_substitute_older_paste
nmap <M-P> <Plug>yankstack_substitute_newer_paste

它可以让我按ALT-p或ALT-SHIFT-p在粘贴历史中来回循环。

我发现所有这些组合键都很麻烦。相反,我编写了一个函数来切换vim的“副作用”行为,即从删除操作覆盖缓冲区。这样你就可以关闭它,自由删除,然后在你完成后切换回来。

在这里看到我的答案:https://stackoverflow.com/a/12649560/778118

使用它只需把它放在你的。vimrc

默认情况下,所有的yank和delete操作都写入未命名寄存器。然而,最近的yank和最近的delete总是存储在有编号的寄存器中(分开)。寄存器0保存最近的yank。寄存器1-9保存了最近的9个删除(其中1是最近的)。

换句话说,在其他答案中提到的黑洞寄存器技巧("_dd)是有效的,因为它可以防止覆盖未命名的寄存器,但这不是必要的。

你可以使用双引号引用一个寄存器,所以可以像这样粘贴最近拉出的文本:

"0p

这是一个很好的参考:

  • < a href = " http://blog.sanctum.geek。新西兰/ advanced-vim-registers noreferrer“rel = > http://blog.sanctum.geek.nz/advanced-vim-registers/ < / >

如果您是一个恶意用户,您可以考虑重新映射X,以实现与“_d”等价的功能。然而,完善实现对我来说有点棘手。尽管如此,我还是发现

(define-key evil-normal-state-map "X" 'evil-destroy)
(define-key evil-visual-state-map "X" 'evil-destroy)


(evil-define-operator evil-destroy (beg end type register yank-handler)
"delete without yanking text"
(evil-delete beg end type 95 yank-handler)
)

积分很好。例如,输入XX将类似于dd, X$对于d$, X0对于d0,等等……

如果你好奇它是如何工作的,“95”代表“_寄存器”,所以它只是重新路由你的删除调用,就好像“_已经被按下了寄存器。

诀窍是你知道你想要抓取一些东西并移动,你正在使用“lazy”第一个寄存器(它会被你刚刚删除的东西所取代)。

你需要学会在vim中“切割”。

在删除之前,指定与"不同的任何寄存器。提示:用:reg检查寄存器

现在,通过在任何命令之前按"来选择一个新寄存器(显然是在命令模式下)

  1. 选择你想要“切割”的部分(或者在步骤2中指定一个范围)
  2. 将寄存器更改为任何东西(这里是1)并删除:"1d"1x甚至"1c
  3. 去新的地方,删除更多
  4. 现在你已经准备好粘贴你剪切并存储在寄存器1:"1p"1P中的内容

完成了。这也有解决用例的优势:从一个地方删除5个不同的东西,每一块都去了不同的目的地……只是把一个放在"1中,另一个放在"2中,等等……转到每个目标并粘贴。

" map paste, yank and delete to named register so the content
" will not be overwritten
nnoremap d "xd
vnoremap d "xd
nnoremap y "xy
vnoremap y "xy
nnoremap p "xp
vnoremap p "xp