如何在不覆盖寄存器的情况下粘贴

是否有人知道一种方法来粘贴在一个视觉选择的区域没有把选择放在默认的寄存器?

我知道我可以通过从显式寄存器粘贴来解决这个问题。但是,输入 "xp而不仅仅是 p是一件令人头疼的事情

26552 次浏览

试试

:set guioptions-=a
:set guioptions-=A

"{register}p不会像你描述的那样起作用。它将用寄存器的内容替换所选内容。你将不得不做一些事情,比如:

" I haven't found how to hide this function (yet)
function! RestoreRegister()
let @" = s:restore_reg
return ''
endfunction


function! s:Repl()
let s:restore_reg = @"
return "p@=RestoreRegister()\<cr>"
endfunction


" NB: this supports "rp that replaces the selection by the contents of @r
vnoremap <silent> <expr> p <sid>Repl()

只要你不使用一个有一个非 nore vmap 到 p 的插件,并且这个插件期望一个寄存器被覆盖,那么就没问题。

这段代码可以作为一个脚本 那里使用。 IngoKarkat 也定义了一个 插件来解决同样的问题。

我不喜欢将 dDcC删除的所有文本复制到默认寄存器的缺省 vim 行为。

我已经通过将 d映射到 "_dc映射到 "_c等方式解决了这个问题。

来自我的 vimrc:

"These are to cancel the default behavior of d, D, c, C
"  to put the text they delete in the default register.
"  Note that this means e.g. "ad won't copy the text into
"  register a anymore.  You have to explicitly yank it.
nnoremap d "_d
vnoremap d "_d
nnoremap D "_D
vnoremap D "_D
nnoremap c "_c
vnoremap c "_c
nnoremap C "_C
vnoremap C "_C

Luc Hermitte 的表演成功了!非常好。下面是他在 toggle 函数中提供的解决方案,这样您就可以在正常行为和无替换寄存器 put 之间进行切换。

命令,u 触发行为

let s:putSwap = 1
function TogglePutSwap()
if s:putSwap
vnoremap <silent> <expr> p <sid>Repl()
let s:putSwap = 0
echo 'noreplace put'
else
vnoremap <silent> <expr> p p
let s:putSwap = 1
echo 'replace put'
endif
return
endfunction
noremap ,p :call TogglePutSwap()<cr>

Luc 的函数对我来说工作得很好,因为我做了一个更改,以支持我拥有 clipboard = 未命名集的事实:

function! RestoreRegister()
let @" = s:restore_reg
if &clipboard == "unnamed"
let @* = s:restore_reg
endif
return ''
endfunction

使用以下方法:

xnoremap p pgvy

这将重新选择和重新链接粘贴在可视模式下的任何文本。

编辑: 为了与 "xp一起工作,你可以这样做:

xnoremap p pgv"@=v:register.'y'<cr>

v:register扩展到普通模式命令中使用的最后一个寄存器名称。

Luc Hermitte 的解决方案非常有效。我用了一个星期左右。然后我发现了一个来自 Steve Losh 的 Vimrc的解决方案,如果 YankRing 是你的插件/捆绑包阵容的一部分,那么它可以很好地工作:

function! YRRunAfterMaps()
" From Steve Losh, Preserve the yank post selection/put.
vnoremap p :<c-u>YRPaste 'p', 'v'<cr>gv:YRYankRange 'v'<cr>
endfunction

在你的 ~/.vimrc中试试这个:

xnoremap <expr> p 'pgv"'.v:register.'y'
  • xnoremap意味着这只适用于 Visual模式,而不适用于 Visual + Select模式。

  • <expr>意味着 xnoremap {lhs} {rhs}设置的 {rhs}作为表达式计算。

  • 在这种情况下,我们的 'pgv"'.v:register.'y'表达式使用 .进行连接。

  • v:register计算为在实现映射过程中使用的寄存器。

"xp的结果将被评估为 pgv"xy,其中 x是寄存器。

这个堆栈溢出问题的答案对我有所帮助: 带有可选寄存器前缀的 Vim 映射 结合 伯努瓦的答案 在这一页

在你的 .vimrc

xnoremap p "_dP

我在一个类似的帖子上找到了这个,但最初的来源是 http://vim.wikia.com/wiki/Replace_a_word_with_yanked_text。它提到了一些缺点,不过对我来说还不错。

胶带编程,但对我有用:

nmap viwp viwpyiw
nmap vi'p vi'pyi'
nmap vi"p vi"pyi"
nmap vi(p vi(pyi(
nmap vi[p vi[pyi[
nmap vi<p vi<pyi<

选择文本并按 P(大写)粘贴。

例如:

viwP

有关更多信息,请参见 h: v_P

这就是我的解决办法。

vnoremap p p:let @+=@0<CR>


vnoremap P P:let @+=@0<CR>

我发现粘贴后,旧的内容仍然保存在“0寄存器”中。 只需将其恢复到当前剪贴板

:let @+=@0