在Vim中有没有一种方法可以在不将文本放入寄存器的情况下删除?

时间:2008-09-10 14:46:35

标签: vim replace vim-registers

使用Vim我经常想用一块我刚刚拉出来的块代替一段代码。

但是当我删除要替换的代码块时,该块本身会进入寄存器,该寄存器会擦除我刚刚移动的块。所以我习惯了yanking,然后插入,然后删除我不想要的东西,但是对于大块的代码,这会变得很乱,试图保持插入的块和块分开删除。

那么在Vim中替换文本的最简单,最快捷的方法是什么?

  • 有没有办法删除文本而不将其放入注册表?
  • 有没有办法说出,例如“替换下一个单词”或“替换为下一个段落”
  • 或者是以某种方式使用多寄存器功能的最佳方式?

28 个答案:

答案 0 :(得分:411)

要删除某些内容而不将其保存在寄存器中,可以使用“黑洞寄存器”:

"_d

当然,您也可以使用其他任何不包含您感兴趣的寄存器。

答案 1 :(得分:100)

是的。它比首先删除“旧”文本稍微复杂一点,但是:

我开始......

line1
line2
line3
line4

old1
old2
old3
old4

shift + v 选择第1行,第2,3和4行,并使用 d 命令删除它们

然后我以同样的方式删除旧的1-4行。

然后,做

"2p

那将粘贴倒数第二条线(第1-4行)。 "3p会做到倒数第三,依此类推......

所以我最终得到了

line1
line2
line3
line4

<强>参考: Vim documentation on numbered register

答案 2 :(得分:71)

VIM docs:编号寄存器0包含最近的yank命令中的文本, 除非命令使用[“x]。

指定另一个寄存器

E.g。我们猛拉“foo”并删除“bar” - 注册表0仍然包含“foo”!因此可以使用"0p

粘贴“foo”

答案 3 :(得分:52)

使用简单的映射很方便,可以用缓冲区替换当前选择。

例如,当你把它放在你的.vimrc

中时
vmap r "_dP       // it's a capital 'p' on the end

然后,在将某些内容复制到寄存器中(即使用“y”)后,您只需选择要替换的文本,然后只需按键盘上的“r”即可。选择将替换为您当前的注册表。

说明:

vmap - mapping for visual mode
"_d - delete current selection into "black hole register"
P - paste

答案 4 :(得分:34)

我在vimrc中添加了以下内容:

noremap  y "*y
noremap  Y "*Y
noremap  p "*p
noremap  P "*P
vnoremap y "*y
vnoremap Y "*Y
vnoremap p "*p
vnoremap P "*P

现在我从剪贴板寄存器中拉出并放入,并且不必关心默认寄存器会发生什么。另一个好处是我可以轻松地从其他应用程序粘贴。我知道,我正在失去一些功能,但无论如何我都无法跟踪多个注册/剪贴板。

答案 5 :(得分:23)

对于您提供的具体示例,如果我理解了这个问题,那么这可能有用:

*Highlight what you want to put somewhere else
*delete (d)
*Highlight the code that you want it to replace
*paste (p)

答案 6 :(得分:21)

默认情况下,所有yank和delete操作都会写入未命名的寄存器。但是,最近的删除和最近的删除始终(单独)存储在编号的寄存器中。注册0拥有最近的一次猛拉。寄存器1-9包含最近的9个删除(1是最新的删除)。

换句话说,删除会覆盖未命名寄存器中最近的一个yank,但它仍然存在于0寄存器中。黑洞注册技巧({其他答案中提到的{1}})因为它可以防止覆盖未命名的寄存器,但它不是必需的。

您使用双引号引用寄存器,因此可以像这样粘贴最近出现的文本:

"_dd

这是一个很好的参考:

答案 7 :(得分:16)

强调EBGreen said

如果您在选择文字时粘贴,则所选文字将替换并带有粘贴的文字。

如果要复制某些文字然后将其粘贴到多个位置,请使用"0p进行粘贴。编号寄存器0包含最近的yank命令中的文本。


此外,您可以列出所有寄存器的内容:

:registers

该命令可以更轻松地在执行dbr's answer之类的操作时找出您想要的寄存器。您还会看到/,%,#个寄存器。 (另见:help registers


最后,请查看cWcW以更改包含但不包括尾随空格的单词。 (使用大写W包括标点符号。)

答案 8 :(得分:10)

对于“替换字词”,请在正常模式下尝试cw

对于“替换段落”,请在正常模式下尝试cap

答案 9 :(得分:10)

如果您正在使用Vim,那么您将拥有可视模式,就像选择一样,但是使用分离模式的东西是vi / vim的基础。

您要做的是使用可视模式选择源,然后猛拉,然后再次使用可视模式选择目标的范围,然后从默认缓冲区粘贴到文本。

示例:

在包含以下内容的文本文件中

1| qwer
2| asdf
3| zxcv
4| poiu

使用以下顺序:ggVjyGVkp您将以:

结束
1| qwer
2| asdf
3| qewr
4| asdf

说明:

  • gg:转到第一行
  • V:以整行开始视觉模式
  • j:向下走一行(在前一行开始选择,这会使选择向下增加一行)
  • y:猛拉到默认缓冲区(两条选定的行,它会自动从可视模式退出)
  • G:转到最后一行
  • V:启动视觉模式(与之前相同)
  • k:向上移动一行(如前所述,启用可视模式后,这会使选择增加一行)
  • p:粘贴(选择最后两行,它将用缓冲区中的任何内容替换这些行 - 在这种情况下为2行)

将最后一个块放在缓冲区上有一点不方便,所以不管怎样都不希望重复粘贴同一个东西,所以你需要将源保存到命名缓冲区,例如{{1} (对于一个名为“a”的缓冲区)并粘贴"ay之类的东西(但是如果你正在编程,你可能不想粘贴几次但是要创建一个函数并调用它,对吧?的 RIGHT ?)。

如果你只是使用vi,那么你必须使用隐形标记而不是视觉模式,"ap更多关于此,我很抱歉,但我对这个看不见的标记不太好,我视觉模式非常污染。

答案 10 :(得分:7)

好吧,先做这个命令:

:h d

然后您将意识到您可以删除特定的寄存器。这样你就不会改变默认寄存器中的内容。

答案 11 :(得分:4)

删除文本时,在插入模式下,不会进入默认寄存器。

答案 12 :(得分:3)

我在正确的语境中使用的两个解决方案是

  • 使用Vims VISUAL模式突出显示要替换的内容,然后粘贴注册表。

我主要是出于习惯而使用这种习惯,因为我后来才发现第二种解决方案,例如

yiw   " yank the whole word
viwp  " replace any word with the default register
  • YankRing。使用此插件,您可以使用键绑定<ctrl>+<p>将您之前编号的寄存器替换为刚刚粘贴的寄存器。

基本上你会像你一样粘贴,但是当你意识到你已经覆盖了默认寄存器而失去了你想要粘贴的东西时,你可以<C-P>找到并替换YankRing历史记录!

其中一个必须有插件......

答案 13 :(得分:3)

我找到了一个非常有用的地图用于您的目的:

xnoremap p "_dP

已删除的文本放入&#34;黑洞注册表&#34;,并且已删除的文本仍然存在。

来源:http://vim.wikia.com/wiki/Replace_a_word_with_yanked_text

答案 14 :(得分:2)

在Windows版本中(也可能在Linux中),你可以使用"*y进入系统的复制/粘贴缓冲区(即在带有双引号和星号的yank命令之前)。

然后,您可以正常删除可替换的行,并使用"*p粘贴复制的文本。

答案 15 :(得分:2)

我经常犯了一个错误,当按照命令'y'ank然后''_d'elete进入一个黑洞然后'p'aste。我更喜欢'y'ank,然后删除然而我喜欢,然后'“ 0寄存器中的0p',这是最后复制的文本被推送到的位置。

答案 16 :(得分:2)

我的情况:在Normal模式下,当我使用x按键删除字符时,这些删除将覆盖我的最新寄存器-使要使用x删除字符的编辑变得复杂将我已有的东西粘贴到最近的寄存器中(例如,将相同的文本粘贴到两个或多个位置)。

我尝试了接受的答案("_d中的建议,但是没有用。

但是,从https://vi.stackexchange.com/questions/122/performing-certain-operations-without-clearing-register接受的答案/评论中,我将其添加到了~/.vimrc,它可以正常工作(您可能必须重新启动Vim):

nnoremap x "_x

也就是说,我现在可以执行常规拉(y),删除(d)和粘贴(p)命令-以及使用{{1 }}不再填充最新的寄存器。

答案 17 :(得分:2)

Vim偶尔会偏向于复杂性而不是实用性,这给用户增加了将寄存器应用于复制/删除操作的负担-通常,人们只是想粘贴复制的内容,而“忘记”删除的内容。

但是,与其使用vim复杂的寄存器,不如让它们更方便:选择一个“默认”寄存器来存储最新的删除内容。例如,将删除发送到d寄存器(为特殊使用保留a-c; d是一个很好的助记符):

nnoremap d "dd           "send latest delete to d register
nnoremap D "dD           "send latest delete to d register 
nnoremap dd "ddd         "send latest delete to d register
nnoremap x "_x           "send char deletes to black hole, not worth saving
nnoremap <leader>p "dp   "paste what was deleted
nnoremap <leader>P "dP   "paste what was deleted

这种方法可以防止删除造成麻烦,但不要放弃注册删除操作-可以粘贴(返回)删除的内容而不是将其丢失在黑洞中(如公认的答案所示)。在上面的示例中,此调用使用两个前导p映射完成。这种方法的好处是,它使您能够选择要粘贴的内容:(a)刚删除的内容,或(b)刚删除的内容。

答案 18 :(得分:1)

对于Dvorak用户来说,一个非常方便的方法就是将不需要的文本删除到“1寄存器而不是”_黑洞寄存器中,只要因为你可以按下“+ 1”,同时按下相同的移位和快速的小指动作因为1是Dvorak中的紧接上方的键(另一方面是PLUS d,这使得整个命令快速下降)。

当然,“1寄存器可以用于其他东西,因为它的方便,但除非你有一个比替换文本更常见的目的,我会说这是一个很好的使用寄存器。

答案 19 :(得分:1)

以下vscode设置应允许例如dd和dw变为“ _dd”和“ _dw”,现在可以与我们的重新映射器一起正常工作。

import pandas as pd
df = [{'id': 1, 'name': 'bob', 'apple': 45, 'grape': 10, 'rate':0},
      {'id': 1, 'name': 'bob', 'apple': 45, 'grape': 20, 'rate':0},
      {'id': 2, 'name': 'smith', 'apple': 5, 'grape': 30, 'rate':0},
      {'id': 2, 'name': 'smith', 'apple': 10, 'grape': 40, 'rate':0}]
df = pd.DataFrame(df)
df=df.groupby(['id','name']).sum().reset_index()
df['rate']=round((df['apple'] / df['grape'])*100,1)
print(df)

答案 20 :(得分:1)

寄存器0到9是您拉动或剪切的最新事物,并且不包括已删除的事物等。因此,如果您拉动/剪切某些事物,则即使在整天之后都说删除的事物,它也位于寄存器0中。 ,寄存器0仍然是您取消/删除的最后一个内容。

yiw#同时进入默认寄存器和寄存器0

它使光标所在的单词变大

已删除的内容等将进入默认寄存器,但不会变为0

在标准模式下:

“ 0p#输入寄存器0的内容

在插入模式下:

ctrl-r 0#输入寄存器0的内容

我还有一个朋友,总是拉扯/切割来注册x哈哈。

答案 21 :(得分:1)

适用于在IdeaVim中使用JetBrans IDE(PhpStorm,WebStorm,IntelliJ IDEA)的用户。您可能遇到像nnoremap d "_d这样的重新映射并使用它来删除行dd的问题。可能的解决方案:nnoremap dd "_dd

youtrack上存在问题,请对它们进行投票: https://developer.apple.com/documentation/security/keychain_services https://youtrack.jetbrains.com/issue/VIM-1189

答案 22 :(得分:1)

对于emacs-evil用户,可以在粘贴后触发功能(evil-paste-pop),并在kill-ring中的先前条目之间循环。假设您将其绑定到<C-p>(Spacemacs中的默认设置),您将击中p,然后按需要插入<C-p>

答案 23 :(得分:1)

对于那些主要感兴趣的人,当您通过虚拟选择和粘贴替换文本时,不会覆盖未命名的寄存器。

您可以使用以下解决方案,这对我来说很简单,最适合我:

xnoremap <expr> p 'pgv"'.v:register.'y'

这里的答案(和评论): How to paste over without overwriting register

首先超过选择,然后再次选择带有新文本的选择(gv)。现在最后一个在可视模式下使用的寄存器(通常是未命名的寄存器,但如果你使用另一个寄存器进行粘贴,也可以免费使用副作用)。然后再次将新值拉到寄存器中。

PS:如果你需要一个更简单的变体,它也适用于intellj idea插件vim-simulation,你可以选择这个(下行:覆盖未命名的寄存器,即使给出了另一个寄存器用于粘贴):

vnoremap p pgvy

答案 24 :(得分:0)

您可以使用以下方法创建一个简单的宏: q"_dwq

现在要删除下一个单词而不覆盖寄存器,可以使用@d

答案 25 :(得分:0)

主要问题是在可视模式下使用p。在可视模式下粘贴某些内容后,以下功能将恢复未命名寄存器的内容。

 function! MyPaste(ex)
  let save_reg = @"
  let reg = v:register
  let l:count = v:count1
  let save_map = maparg('_', 'v', 0, 1)
  exec 'vnoremap _ '.a:ex
  exec 'normal gv"'.reg.l:count.'_'
  call mapset('v', 0, save_map)
  let @" = save_reg
endfunction

vmap p :<c-u>call MyPaste('p')<cr>
vmap P :<c-u>call MyPaste('P')<cr>

用法与以前相同,并且寄存器“”的内容未更改。

答案 26 :(得分:0)

我发现从一开始就更容易进入“p”缓冲区。

复制(又名:猛拉)

# highlight text you want to copy, then:
"py

粘贴

# delete or highlight the text you want to replace, then:
"pp

优点(与删除到特定寄存器相反):

  • "pp 触手可及
  • 不会在删除时意外覆盖粘贴缓冲区。

答案 27 :(得分:0)

noremap mm m

noremap mx "_x

这是我处理它的方式。