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

Edw*_*uay 461 vim replace vim-registers

使用Vim我经常想用我刚刚拉出的块替换代码块.

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

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

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

Chr*_*erg 421

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

"_d
Run Code Online (Sandbox Code Playgroud)

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

  • 这是标准文本编辑器获胜的一个领域.您只需按删除键即可. (53认同)
  • 你也可以用"yy"或"3yy"(或者其他)来抽取一些东西,它将它放在未命名的寄存器中,但也可以在0中.你可以继续用"0p"粘贴它,尽管之后使用过`d`那. (19认同)
  • 要删除一个字符,请尝试:````_x``` (5认同)
  • 起初我以为这个命令工作不正常.然后我意识到我正在使用美国键盘的"死键"版本.使用这种键盘布局,我必须输入"<space> _d`.实际输入"需要空格. (4认同)
  • 有选择地只在空行上做这个的想法吗?(如果我在空行上"dd"它会进入黑洞,否则它会像正常一样). (4认同)
  • @VincePanuccio No.您可以在vim中按x删除一个键,就像在标准文本编辑器中一样,但这里的问题是如何删除键而不将删除的字符移动到缓冲区中,这样您仍然可以粘贴在删除之前缓冲区中有什么内容.祝你在记事本中好运. (3认同)
  • 将«Yank / Cut / Paste»映射到一个寄存器,将其删除映射到另一个寄存器会更加有用-这样,我仍然可以删除自己的内容,而不会惹恼我的yank。我在Emacs中做了这样的事情,有没有办法在VIM中做到这一点? (2认同)
  • @VincePanuccio @Alex 我只是在我的 .vimrc 中放入了 `noremap x "_x` 和 `noremap X "_X` 行,它们分别提供了正常模式下的前向删除和退格功能。防止在寄存器中保存单个字符。 (2认同)

dbr*_*dbr 102

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

我开始......

line1
line2
line3
line4

old1
old2
old3
old4
Run Code Online (Sandbox Code Playgroud)

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

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

然后做

"2p
Run Code Online (Sandbox Code Playgroud)

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

所以我最终得到了

line1
line2
line3
line4
Run Code Online (Sandbox Code Playgroud)

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

  • 1到9适用于删除.要粘贴最后的东西真的被猛拉(使用'y')你必须使用"0p.这在你第一次想要替换其他东西的情况下很有用,但是其他东西会覆盖默认的粘贴寄存器. (30认同)

ale*_*2k8 72

VIM docs:编号寄存器0包含最近的yank命令中的文本,除非该命令指定了另一个带有["x]的寄存器.

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


小智 52

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

例如,当你把它放在.vimrc中时

vmap r "_dP       // it's a capital 'p' on the end
Run Code Online (Sandbox Code Playgroud)

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

说明:

vmap - mapping for visual mode
"_d - delete current selection into "black hole register"
P - paste
Run Code Online (Sandbox Code Playgroud)

  • 您可以放置​​文本而不删除选择.例如,`Vp`立即用被拉出的线替换你当前的线. (7认同)

Mag*_*nus 35

我把以下内容放在我的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
Run Code Online (Sandbox Code Playgroud)

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

  • 除了所有那些重映射之外,你还可以设置clipboard = unnamed`或`set clipboard = unnamedplus`,它们分别将默认剪贴板更改为`*`或`+`. (5认同)
  • @Steve如果你这样做,那么d也会覆盖最后一次猛拉到剪贴板寄存器,这就是问题试图避免的问题. (5认同)
  • @tba用nnoremap(两个n)替换noremap,它应该可以正常工作. (2认同)

EBG*_*een 24

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

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

  • 这种方法很有效,除非您要粘贴多个选择. (6认同)

Way*_*ett 22

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

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

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

"0p
Run Code Online (Sandbox Code Playgroud)

这是一个很好的参考:


idb*_*rii 16

要强调EBGreen说的话:

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

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


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

:registers
Run Code Online (Sandbox Code Playgroud)

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


最后,检查cWcW更改包含但不包括尾随空格的单词.(使用资本W包括标点符号.)


小智 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行)

这有点不方便将最后一个块放在缓冲区上,所以不管怎样都不希望重复粘贴同一个东西,所以你需要将源保存到一个命名缓冲区,例如"ay(到一个叫做"a"的缓冲区) "),并且用类似粘贴"ap(但当时如果你编程,你可能不想贴几次,但创建一个函数并调用它,对吗?RIGHT?).

如果你只是使用vi,那么你必须使用隐形标记而不是视觉模式,:he mark对于更多这方面,我很抱歉,但我对这个隐形标记的东西不是很好,我很鄙视视觉模式.


Swa*_*C H 10

对于"替换单词",请尝试cw正常模式.

对于"替换段落",请尝试cap正常模式.

  • @WiSaGaN"ap"代表"段落":https://vimhelp.appspot.com/motion.txt.html#object-select (2认同)

Tor*_*ben 8

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

注册0总是包含最后一个猛拉(如Rafael,alex2k8idbrii已经提到过).不幸的是,一直选择寄存器0可能非常烦人,所以如果默认p使用它会很好"0.这可以通过将以下行放入您的.vimrc:

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
Run Code Online (Sandbox Code Playgroud)

第一行将每个p笔划映射到"0p.但是,这会阻止p访问任何其他寄存器.因此p,具有显式选择的寄存器的所有笔划都映射到for循环中的等效命令行表达式.这样做也是如此P.

这种方式保留了标准行为,但隐式pP笔划除外,它们现在0默认使用register .

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

noremap <LEADER>d "0d
noremap <LEADER>D "0D
Run Code Online (Sandbox Code Playgroud)

\默认情况下,领导键是您可以通过键入\d或轻松剪切文本\D.

提示2:多键映射的默认超时非常短.您可能希望增加它以便在选择寄存器时有更多时间.查看:help timeoutlen详情,我正在使用:

set timeout timeoutlen=3000 ttimeoutlen=100
Run Code Online (Sandbox Code Playgroud)


EBG*_*een 7

好吧,先做这个命令:

:h d
Run Code Online (Sandbox Code Playgroud)

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


Vic*_*art 6

我的情况:在Normal模式下,当我使用x按键删除字符时,这些删除会覆盖我最新的寄存器——使编辑变得复杂,我想使用删除字符x并粘贴我在最近寄存器中的内容(例如,在两个或多个位置粘贴相同的文本)更多地方)。

我尝试了已接受答案 ( "_d) 中的建议,但没有奏效。

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

nnoremap x "_x
Run Code Online (Sandbox Code Playgroud)

也就是说,我现在可以执行正常的 yank ( y)、delete ( d) 和 paste ( p) 命令——我删除的字符x不再填充最近的寄存器。


gre*_*ory 6

Vim 偶尔偏爱复杂性而不是实用性,这给用户应用寄存器来复制/删除操作带来了负担——而通常情况下,人们只想粘贴复制的内容并“忘记”删除的内容。

然而,与其与 vim 复杂的寄存器作斗争,不如让它们变得更方便:选择一个“默认”寄存器来存储您最新的删除。例如,将删除发送到 d 寄存器(使 ac 保持打开状态以供临时使用;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
Run Code Online (Sandbox Code Playgroud)

这种方法可以防止删除被猛拉,但不会放弃注册删除——人们可以粘贴(回)删除的内容,而不是将其丢失在黑洞中(如已接受的答案中所示)。在上面的示例中,此召回是通过两个领导者 p 映射完成的。这种方法的一个好处是,它使您能够选择要粘贴的内容:(a) 刚刚拉出的内容,或 (b) 刚刚删除的内容。