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

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

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

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

  • 有没有办法删除文本而不将其放入注册表?
  • 有没有办法说,例如 “替换下一个单词”或“替换为下一个段落”
  • 或者是以某种方式使用多寄存器功能的最佳方式?
Edward Tanguay asked 2019-01-04T11:56:13Z
20个解决方案
398 votes

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

"_d

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

Christian Berg answered 2019-01-04T11:56:31Z
100 votes

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

我开始......

line1
line2
line3
line4

old1
old2
old3
old4

我移动+ v选择line1,第2,3和4行,然后用d命令删除它们

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

然后做

"2p

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

所以我最终得到了

line1
line2
line3
line4

参考:编号寄存器上的Vim文档

dbr answered 2019-01-04T11:58:00Z
66 votes

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

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

alex2k8 answered 2019-01-04T11:58:35Z
52 votes

有一个简单的映射可以让你用缓冲区替换当前的选择。

例如,当你把它放在.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
João Portela answered 2019-01-04T11:59:16Z
33 votes

我把以下内容放在我的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

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

Magnus answered 2019-01-04T11:59:54Z
23 votes

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

*Highlight what you want to put somewhere else
*delete (d)
*Highlight the code that you want it to replace
*paste (p)
EBGreen answered 2019-01-04T12:00:18Z
17 votes

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

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

您使用双引号引用寄存器,因此粘贴最近被拉动的文本可以这样做:

"0p

这是一个很好的参考:

  • [http://blog.sanctum.geek.nz/advanced-vim-registers/]
Wayne Burkett answered 2019-01-04T12:01:30Z
15 votes

要强调EBGreen说的话:

如果在选择文本时粘贴,则所选文本将替换为粘贴文本。

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


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

:registers

这个命令可以让你在做dbr的答案时更容易找出你想要的寄存器。 你还会看到/,%,#寄存器。 (另见cW


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

idbrii answered 2019-01-04T12:02:37Z
10 votes

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

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

例:

在一个文本文件中:

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

按以下顺序:ggVjyGVkp您将以:

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

解释:

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

这有点不方便将最后一个块放在缓冲区上,所以它不太需要重复粘贴相同的东西,所以你需要将源保存到命名缓冲区,例如:he mark(到一个名为“的缓冲区”) 一个“)并粘贴像"ap(但如果你正在编程,你可能不想粘贴几次,但要创建一个函数并调用它,对吗?对吗?)。

如果你只是使用vi,那么你必须使用隐形标记而不是视觉模式,:he mark了解更多信息,对不起,我对这个隐形标记的事情不是很好,我很鄙视视觉模式。

maeghith answered 2019-01-04T12:04:58Z
10 votes

对于'替换字',请在正常模式下尝试cap

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

Swaroop C H answered 2019-01-04T12:05:30Z
8 votes

针对懒人的微创解决方案:

注册:help timeoutlen总是包含最后一个猛拉(如Rafael,alex2k8和idbrii已经提到过)。 不幸的是,一直选择寄存器\d可能会非常烦人,所以如果\D默认使用p会很不错。 这可以通过将以下行放入您的P来实现:

noremap p "0p
noremap P "0P
for s:i in ['"','*','+','-','.',':','%','/','=','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
    execute 'noremap "'.s:i.'p "'.s:i.'p'
    execute 'noremap "'.s:i.'P "'.s:i.'P'
endfor

第一行将每个:help timeoutlen笔划映射到\d.但是,这可以防止\D访问任何其他寄存器。 因此,具有显式选择的寄存器的所有p笔划都映射到for循环中的等效命令行表达式。 对于P也是如此。

这种方式保留了标准行为,但隐式:help timeoutlen\d笔划除外,默认情况下使用寄存器\D

提示1:剪切命令现在是:help timeoutlen而不仅仅是\d.但是因为我很懒,这对我来说太长了;)因此我使用以下映射:

noremap <LEADER>d "0d
noremap <LEADER>D "0D

领导键默认为:help timeoutlen,因此您可以通过键入\d\D轻松剪切文本。

提示2:多键映射的默认超时非常短。 您可能希望增加它以便在选择寄存器时有更多时间。 有关详细信息,请参阅:help timeoutlen,我正在使用:

set timeout timeoutlen=3000 ttimeoutlen=100
Torben answered 2019-01-04T12:06:41Z
7 votes

好吧,先做这个命令:

:h d

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

EBGreen answered 2019-01-04T12:07:13Z
4 votes

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

answered 2019-01-04T12:07:37Z
3 votes

我在正确的背景下使用的两个解决方案是:

  • 使用Vims <C-P>模式突出显示要替换的内容然后粘贴寄存器。

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

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

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

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

expelledboy answered 2019-01-04T12:08:40Z
3 votes

我为您的目的找到了一个非常有用的映射:

xnoremap p "_dP

删除的文本放在“黑洞寄存器”中,并且拉出的文本仍然存在。

资料来源:[http://vim.wikia.com/wiki/Replace_a_word_with_yanked_text]

Hieu M. Nguyen answered 2019-01-04T12:09:25Z
2 votes

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

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

JayG answered 2019-01-04T12:09:55Z
2 votes

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

Clueless answered 2019-01-04T12:10:19Z
1 votes

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

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

Vic Goldfeld answered 2019-01-04T12:10:50Z
1 votes

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

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

vnoremap p pgvy

这是来自这里的答案(和评论):如何粘贴而不覆盖寄存器

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

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

vnoremap p pgvy

snap answered 2019-01-04T12:12:09Z
1 votes

对于emacs-evil用户,可以在粘贴后触发函数(evil-paste-pop),并循环遍历kill-ring中的先前条目。 假设你将它绑定到<C-p>(Spacemacs中的默认值),你可以根据需要点击p,然后点击<C-p>

explaw answered 2019-01-04T12:12:33Z
translate from https://stackoverflow.com:/questions/54255/in-vim-is-there-a-way-to-delete-without-putting-text-in-the-register