使用Vim我经常想用我刚刚拉出的块替换代码块。
但是当我删除要替换的代码块时,该块本身会进入寄存器,该寄存器会擦除我刚刚移动的块。 所以我习惯了yanking,然后插入,然后删除我不想要的东西,但是对于大块的代码,这会变得混乱,试图保持插入的块和块分开删除。
那么在Vim中替换文本的最简单,最快捷的方法是什么?
- 有没有办法删除文本而不将其放入注册表?
- 有没有办法说例如“替换下一个单词”或“替换为下一个段落”
- 或者是以某种方式使用多寄存器功能的最佳方式?
#1楼
我把以下内容放在我的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
现在我从剪贴板寄存器中抽出并放入,并且不必关心默认寄存器会发生什么。 另一个好处是我可以轻松地从其他应用程序粘贴。 我知道,我正在失去一些功能,但我无论如何都无法跟踪多个注册/剪贴板。
#2楼
我经常犯了一个错误,当按照命令'y'ank然后''_d'elete进入黑洞然后'p'aste。我更喜欢'y'ank,然后删除然而我喜欢,然后''0p'来自0寄存器,这是最后复制的文本被推送到的位置。
#3楼
要强调EBGreen说的话 :
如果在选择文本时粘贴,则所选文本将替换为粘贴文本。
如果要复制一些文本然后将其粘贴到多个位置,请使用"0p
粘贴。编号寄存器0包含最近的yank命令中的文本。
此外,您可以列出所有寄存器的内容:
:registers
这个命令可以让你在做dbr的答案时更容易找出你想要的寄存器。 您还会看到/,%,#个寄存器。 (另见:help registers
)
最后,检查cW
和cW
以更改包含但不包括尾随空格的单词。 (使用大写字母W
包括标点符号。)
#4楼
我为您的目的找到了一个非常有用的映射:
xnoremap p "_dP
删除的文本被放入“黑洞注册”中,并且被删除的文本保留。
资料来源: http : //vim.wikia.com/wiki/Replace_a_word_with_yanked_text
#5楼
针对懒人的微创解决方案:
注册0
总是包含最后一个(如Rafael , alex2k8和idbrii已经提到过)。 不幸的是,一直选择寄存器0
会非常烦人,所以如果p
默认使用"0
会很好。这可以通过将以.vimrc
放入.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
第一行将每个p
笔划映射到"0p
。但是,这可以防止p
访问任何其他寄存器。因此,具有明确选择的寄存器的所有p
笔划都映射到for循环中的等效命令行表达式。对P
进行相同的操作。 。
这样就保留了标准行为,除了隐式的p
和P
笔划,默认情况下现在使用寄存器0
。
提示1: cut命令现在是"0d
而不是d
。但是因为我很懒,这对我来说太长了;”因此我使用以下映射:
noremap <LEADER>d "0d
noremap <LEADER>D "0D
领导键默认为\\
,因此您可以通过键入\\d
或\\D
轻松剪切文本。
提示2:多键映射的默认超时非常短。 您可能希望增加它以便在选择寄存器时有更多时间。 请参阅:help timeoutlen
了解详细信息,我正在使用:
set timeout timeoutlen=3000 ttimeoutlen=100
#6楼
默认情况下,所有yank和delete操作都会写入未命名的寄存器。 但是,最近的删除和最近的删除始终(单独)存储在编号的寄存器中。 寄存器0
保持最近的猛拉。 寄存器1-9
保存最近的9个删除( 1
是最近的删除)。
换句话说, 删除会覆盖未命名寄存器中最近的一个yank,但它仍然存在于0
寄存器中。 其他答案中提到的黑洞注册技巧( "_dd
)有效,因为它可以防止覆盖未命名的寄存器,但这不是必需的。
您使用双引号引用寄存器,因此粘贴最近被拉出的文本可以这样做:
"0p
这是一个很好的参考:
#7楼
对于那些主要感兴趣的人,当您通过虚拟选择和粘贴替换文本时,不会覆盖未命名的寄存器。
您可以使用以下解决方案,这对我来说最简单,最有效:
xnoremap <expr> p 'pgv"'.v:register.'y'
这是来自这里的答案(和评论): 如何粘贴而不覆盖寄存器
它首先超过选择,然后再次选择新文本的选择(gv)。 现在最后一个在可视模式下使用的寄存器(通常是未命名的寄存器,但如果你使用另一个寄存器进行粘贴,也可以免费使用副作用)。 然后再次将新值拉到寄存器中。
PS:如果你需要一个更简单的变体,它也适用于intellj idea插件vim-simulation,你可以选择这个(下行:覆盖未命名的寄存器,即使给出了另一个寄存器用于粘贴):
vnoremap p pgvy
#8楼
VIM docs: 编号寄存器0包含来自最近的yank命令的文本,除非命令指定了另一个带有[“x]的寄存器。
例如,我们猛拉“foo”并删除“bar” - 注册表0仍然包含“foo”! 因此可以使用"0p
”粘贴“foo”
#9楼
对于emacs-evil用户,可以在粘贴后触发函数(evil-paste-pop)
,并循环遍历kill-ring中的先前条目。 假设你将它绑定到<Cp>
(Spacemacs中的默认值),你可以根据需要点击p
后跟多个<Cp>
。
#10楼
我在正确的背景下使用的两个解决方案是;
- 使用Vims
VISUAL
模式突出显示要替换的内容,然后粘贴寄存器。
我主要是出于习惯而使用这种习惯,因为我之后才发现第二种解决方案,例如
yiw " yank the whole word
viwp " replace any word with the default register
- YankRing 。 使用此插件,您可以使用键绑定
<ctrl>+<p>
将先前编号的寄存器替换为刚粘贴的寄存器。
基本上你就像你一样粘贴,但是当你意识到你已经覆盖了默认寄存器而失去了你想要粘贴的东西时,你可以<CP>
找到并替换YankRing历史!
其中一个必须有插件......
#11楼
我的情况:在Normal
模式下,当我使用x
按键删除字符时,这些删除会覆盖我最新的寄存器 - 复杂的编辑,我想用x
删除字符并粘贴我最近的寄存器中的内容(例如粘贴相同的文本)两个或两个以上的地方)。
我在接受的答案( "_d
)中尝试了这个建议,但它没有用。
但是,从https://vi.stackexchange.com/questions/122/performing-certain-operations-without-clearing-register上接受的答案/评论中,我将此添加到我的~/.vimrc
,这有效(你可以必须重启Vim):
nnoremap x "_x
也就是说,我现在可以执行正常的yank( y
),delete( d
)和paste( p
)命令 - 我使用x
删除的字符不再填充最新的寄存器。
#12楼
好吧,先做这个命令:
:h d
然后你会意识到你可以删除到特定的寄存器。 这样您就不会改变默认寄存器中的内容。
#13楼
对于您提供的具体示例,如果我理解了问题,那么这可能会起作用:
*Highlight what you want to put somewhere else
*delete (d)
*Highlight the code that you want it to replace
*paste (p)
#14楼
如果您正在使用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
(但当时如果你编程,你可能不想贴几次,但创建一个函数并调用它,对吧? 对吧 ?)。
如果你只使用vi,那么你必须使用隐形标记而不是视觉模式, :he mark
在此:he mark
更多,我很抱歉,但我对这个看不见的标记不是很好,我很受污染视觉模式。
#15楼
要删除某些内容而不将其保存在寄存器中,可以使用“黑洞寄存器”:
"_d
当然,您也可以使用任何其他不包含您感兴趣的寄存器。
#16楼
在插入模式下,文本被删除不会进入默认寄存器。
#17楼
对于'替换单词',请在正常模式下尝试cw
。
对于“替换段落”,请尝试在正常模式下设置cap
。
#18楼
是的。 它比首先删除“旧”文本稍微复杂一点,但是:
我开始......
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文档
#19楼
在Windows版本中(也可能在Linux中),您可以使用"*y
(即在带有双引号和星号的yank命令之前)进入系统的复制/粘贴缓冲区。
然后,您可以正常删除可替换行,并使用"*p
粘贴复制的文本。
#20楼
对于Dvorak用户来说,一个非常方便的方法就是将不需要的文本删除到“1寄存器而不是”_黑洞寄存器中,如果只是因为你可以按下“+ 1”,相同的移位按下和快速的小指运动,因为1是紧接在Dvorak上方的钥匙(另一方面是PLUS d,这使得整个命令快速下降)。
当然,“1寄存器可以用于其他东西,因为它的方便,但除非你有一个比替换文本更常见的目的,我会说这是一个很好的使用寄存器。
#21楼
使用简单的映射很方便,可以用缓冲区替换当前选择。
例如,当你把它放在.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