如何粘贴而不覆盖寄存器


112

有谁知道一种将选择粘贴到视觉选择区域而不将其放置在默认寄存器中的方法吗?

我知道我可以通过始终从显式寄存器粘贴来解决问题。但是打字"xp而不是仅仅在脖子上很痛苦p

Answers:


33

"{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()

只要您不使用对p具有非虚拟vmap且希望寄存器被覆盖的插件,那应该没问题。

此代码在那里可以作为脚本使用。Ingo Karkat还定义了解决相同问题的插件


实际上,尽管我有一种整齐的方法来获取所使用的寄存器,但是却不记得如何。因此功能的复杂性。
卢克·赫米特

1
我认为这太过分了,不会记得regtype(逐行显示吗?),并且将p重新映射pgvy就足够了。
Benoit

2
这可能是过大的杀伤力,但没有副作用。对"xp,这不会覆盖@"内容与@x不同pgvy
吕克Hermitte

1
那又如何:xnoremap p pgv@=v:register.'y'<cr>呢?
Benoit

1
它对我不起作用。我也尝试下载脚本。这是我要执行的命令的列表:首先我按v,然后按e来选择单词的末尾,然后按y来对其进行拉动。在那之后,我转到另一个我想替换的词。我按v,e,然后按p替换那个。然后我再做一次,但是这次下一个单词被我之前替换的单词替换了。
埃迪

41

我不喜欢用删除复制所有文本的默认VIM行为dDc,或者C到默认寄存器。

我周围得到通过映射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

尽管这些映射非常有用(我自己也做类似的事情),但它们并不能回答OP的问题,p仍会覆盖您希望粘贴到所选内容上的内容。
Magnus,

32

使用以下内容:

xnoremap p pgvy

这将重新选择并重新粘贴以可视模式粘贴的所有文本。

编辑:为了与"xp您一起工作,您可以执行以下操作:

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

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


"xp,这种做法覆盖@"@x
Luc Hermitte 2011年

3
您的建议xnoremap p pgv"@=v:register.'y'<cr>对我没有用。但是,这样做是:xnoremap <expr> p 'pgv"'.v:register.'y'
mrak

这看起来很有趣。您能添加一行关于什么的内容g吗?我以前没看过
LondonRob

4
@LondonRob:g一个人什么都不做。它提供了扩展的多键命令,例如z。例如,go转到缓冲区的第n个字节,gj然后gk转到下一个和上一个显示的行(与换行时不同jk),ga在光标下方显示有关字符的信息,gJ连接没有空格的行,并在此处gv恢复最后的视觉选择。您可以使用:help gv
Benoit

6
@马克 :xnoremap <expr> p 'pgv"'.v:register.'y`>' ,我添加```>``要恢复光标位置
ROX


6

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  

6

尝试在您的~/.vimrc

xnoremap <expr> p 'pgv"'.v:register.'y'
  • xnoremap表示这仅适用于Visual模式,不适用于Visual + Select模式。

  • <expr>表示{rhs}xnoremap {lhs} {rhs}设置的值作为表达式求值。

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

  • v:register 对映射完成期间正在使用的寄存器求值。

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

我被一个答案帮助这个计算器的问题:Vim的-有一个可选的寄存器前缀映射 结合贝努瓦的回答这个网页上


4

在进行更改以支持我设置了剪贴板=未命名的事实之后,Luc的功能对我来说运作良好:

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

1
供参考:使用clipboard=unnamedplus这个必须是@+代替@*
塞巴斯蒂安·布拉斯克

2

卢克·赫米特(Luc Hermitte)做到了!真的很好 这是他在切换功能中提供的解决方案,因此您可以在正常行为和无替换寄存器放置之间进行切换。

命令,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>

您还可以根据s:putSwap值将s:Repl更改为返回“ p”,而不是“ p @ = RestoreRegister()\ <cr>”。
卢克·赫米特

1
更喜欢silent! vunmap而不是vnoremap <silent> <expr> p p
Luc Hermitte 2011年

0

胶带编程,但对我有用:

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<

-4

尝试-

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

3
这些控件控制是否将选定的文本添加到窗口系统的剪贴板(例如X11或Win32),而不添加到Vim的内部复制寄存器。
罗伯·肯尼迪
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.