在使用Vim时,我经常想用我刚拉出的代码块替换代码块。

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

那么,在Vim中替换文本的最灵活、最快的方法是什么呢?

是否有一种方法可以删除文本而不将其放入寄存器? 有一种说法吗?“替换下一个单词”或“替换到下一段” 还是使用多寄存器特性的最佳方式?


当前回答

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

当然,1寄存器也可以用于其他事情,因为它很方便,但除非你有一个比替换文本更常见的目的,否则我认为它是一个很好的使用寄存器的方法。

其他回答

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

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

xnoremap p "_dP

删除的文本被放入“黑洞寄存器”,而被拉拽的文本仍然存在。

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

如果你用的是Vim,你会有视觉模式,就像选择,但有分离模式,这是vi/ Vim的基础。

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

例子:

在文本文件中使用:

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

使用以下序列:ggVjyGVkp,你将以:

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

解释道:

gg: go to first line V: start visual mode with whole lines j: go down one line (with the selection started on the previous lines this grows the selection one line down) y: yank to the default buffer (the two selected lines, and it automatically exits you from visual mode) G: go to the last line V: start visual mode (same as before) k: go up one line (as before, with the visual mode enabled, this grows the selection one line up) p: paste (with the selection on the two last lines, it will replace those lines with whatever there is in the buffer -- the 2 first lines in this case)

这有一点不方便,把最后一个块放在缓冲区,所以它不需要重复粘贴相同的东西,所以你会想要保存源代码到一个命名缓冲区,如“ay”(缓冲区称为“a”)和粘贴,如“ap”(但如果你在编程,你可能不想多次粘贴而是创建一个函数并调用它,对吗?对吧?)。

如果你只使用vi,那么你必须使用不可见的标记,而不是视觉模式,他标记更多关于这个,我很抱歉,但我不太擅长这种不可见标记的东西,我很受视觉模式的污染。

懒人的微创解决方案:

寄存器0总是包含最后一个yank (Rafael, alex2k8和idbrii已经提到过)。不幸的是,一直选择寄存器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

第一行将每个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

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

"_d

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