如何在 vim 中替换粘贴猛拉文本而不猛拉已删除的行?

bit*_*ask 63 vim copy-paste

所以我通常会发现自己将文本从一个点复制到另一个点,同时覆盖粘贴新文本的旧文本:

blah1
newtext
blah2
wrong1
blah3
wrong2
blah4
Run Code Online (Sandbox Code Playgroud)

假设我对它进行了视觉标记newtextyank。现在我选择wrong1(可以是任何东西,不一定只是一个词)并p品尝newtext. 但是,如果我现在wrong2对它做同样的事情,它将被替换wrong1newtext

那么如何防止缓冲区中的文本与我当前正在覆盖的文本交换?

编辑 1

尽管我非常喜欢 reigister 建议(我想我将开始更多地使用寄存器,现在我发现了该:dis命令),但我将修改jinfield的答案,因为我不使用交换模式。

vnoremap p "0p
vnoremap P "0P
vnoremap y "0y
vnoremap d "0d
Run Code Online (Sandbox Code Playgroud)

完美地做到了这一点。

编辑 2

我太快了;romainl的解决方案正是我正在寻找的,没有Edit 1 中的黑客。
其实,vnoremap p "_dP够了!
所以,改变接受的答案。

rom*_*inl 37

我的 .vimrc 中有这些映射:

" delete without yanking
nnoremap <leader>d "_d
vnoremap <leader>d "_d

" replace currently selected text with default register
" without yanking it
vnoremap <leader>p "_dP
Run Code Online (Sandbox Code Playgroud)

"_是“黑洞登记册”,根据:help "_

“写入该寄存器时,什么也没有发生。这可用于删除文本而不影响正常寄存器。从该寄存器读取时,不返回任何内容。{Vi 无此功能}”

  • 我已经使用了 `vnoremap p "_dP map` 并注意到它不适用于一行中的最后一个单词/字符。我已经回到了 `vnoremap p "0p`,`vnoremap P "0P ` 和 `set clipboard=unnamed`(对于 OSX) (2认同)

Tra*_*sud 17

除了标准缓冲区之外,您还可以将文本拉入命名缓冲区,然后从这些命名缓冲区中放入。您最多可以使用 26 个命名缓冲区(每个字母一个)。使用双引号和一个字母来访问命名缓冲区。例子:

"dyy - 将当前行拖入缓冲区 d。
"a7yy- 将接下来的七行拖入缓冲区 a。
"dP- 将缓冲区 d 的内容放在光标之前。
"ap- 将缓冲区 a 的内容放在光标之后

另一个很酷的事情是,如果您使用大写字母而不是小写字母,即"Dyy当前行将被附加到缓冲区 d 而不是替换它。O`Reilly 书中的更多细节:http ://docstore.mik.ua/orelly/unix/vi/ch04_03.htm

  • 很酷的东西。我知道缓冲区,但没有将它们与这个问题联系起来。''a'一切仍然很麻烦,但没关系。 (3认同)
  • 我认为你的意思是“寄存器”而不是“缓冲区” (2认同)

小智 12

用于P粘贴而不猛拉已删除的文本。

:帮助v_P

使用 P 时,未命名寄存器不会更改(选择或剪贴板也不会更改),您可以重复相同的更改。

此行为在v8.2.4242 (2022-01-28)中引入,并在v8.2.4881 (2022-05-06) 中改进。

或者如果你的肌肉记忆太强:

xnoremap p P
Run Code Online (Sandbox Code Playgroud)

  • 迟到30年总比不到好!这应该是公认的答案。 (2认同)

小智 9

put在可视模式下使用时,您要替换的文本wrong1, 会被 'unamed' 寄存器的内容覆盖。

这实际上是通过在选择后“放置”寄存器然后删除选择来实现的。问题是这个删除现在存储在unnamed寄存器中,并将用于下一个put操作。

根据 ,解决方案:h v_p是拉入一个命名寄存器,例如"0y,然后"0p根据需要使用尽可能多的时间进行粘贴。如果您经常这样做,映射<leader>y<leader>p使用命名寄存器可能会有所帮助。

:map <leader>y "0y
:map <leader>p "0p
Run Code Online (Sandbox Code Playgroud)

如需更多帮助,请参阅:

:help v_p
:help map
Run Code Online (Sandbox Code Playgroud)


gar*_*ohn 5

当您将文本拉入未命名寄存器*时,也会将副本放入寄存器 0。每次替换所选文本时,您只需从 0 寄存器粘贴即可。看

:help registers
Run Code Online (Sandbox Code Playgroud)

此外,如果您要用同一个单词替换多个单词,您可以移动到要替换的单词的开头并键入.。这将重复上次编辑操作。看

:help single-repeat
Run Code Online (Sandbox Code Playgroud)

* 您拉入和放出的存储位置称为寄存器。缓冲区是您编辑的内容,通常是磁盘中文件的副本。


Jer*_*rph 5

"0寄存器粘贴很重要,但您通常想要多次替换。如果您使它成为可重复的操作,则可以使用.运算符,正如 garyjohn 所暗示的那样。它在 vim wiki 上有解释:

yiw     yank inner word (copy word under cursor, say "first". Same as above).
...     Move the cursor to another word (say "second").
ciw<C-r>0   select "second", then replace it with "first" If you are at the start of the word then cw<C-r>0 is sufficient.
...     Move the cursor to another word (say "third").
.   select "third", then replace it with "first". 
Run Code Online (Sandbox Code Playgroud)