【问题标题】:How to paste over without overwriting register如何粘贴而不覆盖寄存器
【发布时间】:2010-09-22 08:56:19
【问题描述】:

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

我知道我可以通过始终从显式寄存器粘贴来解决问题。但是输入 "xp 而不仅仅是 p

会让人头疼

【问题讨论】:

    标签: vim vi


    【解决方案1】:

    试试-

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

    【讨论】:

    • 控制是否将选定文本添加到窗口系统的剪贴板(例如,X11 或 Win32),而不是添加到 Vim 的内部复制寄存器。
    【解决方案2】:

    "{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 具有非 nore vmap 并且期望寄存器被覆盖的插件,这应该没问题。

    此代码以脚本there 的形式提供。 Ingo Karkat 还定义了一个 plugin 来解决同样的问题。

    【讨论】:

    • 实际上,我虽然有一种巧妙的方法来获取使用的寄存器,但不记得如何了。因此函数的复杂性。
    • 我认为这太过分了,不会记得regtype(按行吗?)并且将p重新映射到pgvy就足够了。
    • 可能有点矫枉过正,但没有副作用。在"xp 上,这不会用@x 覆盖@" 内容,这与pgvy 不同
    • 那么:xnoremap p pgv@=v:register.'y'&lt;cr&gt; 呢?
    • 它对我不起作用。我也试过下载脚本。这是我执行的命令列表:首先按 v,然后按 e 选择到单词的末尾,然后按 y 拉动它。在那之后,我去了一个我想替换的不同的词。我按 v,e,然后按 p 替换那个。然后我再做一次,但这次下一个单词被我之前替换的那个替换了。
    【解决方案3】:

    我不喜欢将使用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
    

    【讨论】:

    • 尽管这些映射很有用(我自己也做过类似的事情),但它们不会回答 OP 的问题,p 仍会覆盖您在选定内容上粘贴的内容。
    【解决方案4】:

    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()\”。
    • 首选silent! vunmap而不是vnoremap &lt;silent&gt; &lt;expr&gt; p p
    【解决方案5】:

    在我进行更改以支持我设置了 clipboard=unnamed 的事实后,Luc 的功能对我来说效果很好:

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

    【讨论】:

    • 供参考:使用clipboard=unnamedplus 这必须是@+ 而不是@*
    【解决方案6】:

    使用以下内容:

    xnoremap p pgvy
    

    这将重新选择并重新拉出以可视模式粘贴的任何文本。

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

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

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

    【讨论】:

    • "xp 上,此方法用@x 覆盖@"
    • 您对xnoremap p pgv"@=v:register.'y'&lt;cr&gt; 的建议对我不起作用。但是,这样做:xnoremap &lt;expr&gt; p 'pgv"'.v:register.'y'
    • 这看起来很有趣。你能补充一句关于g 的作用吗?我以前没见过。
    • @LondonRob: g 一个人什么都不做。它提供扩展的多键命令,例如z。例如,go 转到缓冲区中的第 n 个字节,gjgk 转到下一行和上一行显示(与换行时的 jk 不同),ga 显示光标下字符的信息, gJ 加入没有空格的行,这里gv 恢复最后的视觉选择。您可以使用:help gv
    • @mark :xnoremap &lt;expr&gt; p 'pgv"'.v:register.'y`&gt;' ,我加了```>``恢复光标位置
    【解决方案7】:

    Luc Hermitte 的解决方案非常有效。我使用它大约一个星期左右。然后我从Steve Losh's .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  
    

    【讨论】:

      【解决方案8】:

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

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

      • &lt;expr&gt; 表示xnoremap {lhs} {rhs} 设置的{rhs} 被评估为表达式。

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

      • v:register 被评估为在完成映射期间使用的寄存器。

      "xp 的结果将计算为pgv"xy,其中x 是寄存器。

      这个 stackoverflow 问题的答案帮助了我:Vim - mapping with an optional register prefix 结合Benoit的回答on this page

      【讨论】:

        【解决方案9】:

        在你的.vimrc

        xnoremap p "_dP
        

        我从一个类似线程的回复中找到了这个,但原始来源是http://vim.wikia.com/wiki/Replace_a_word_with_yanked_text。它提到了一些缺点,但对我来说效果很好。

        【讨论】:

        • 这似乎是最简单的解决方案。
        • 为我工作。这个答案很明确。 .vimrc.local 也可以。
        • 如果您的选择延伸到行尾,则不起作用。
        • 这会给我带来一些视觉上的闪烁(vim 在命令之间重绘)。 xnoremap &lt;silent&gt; p p:let @+=@0&lt;CR&gt;:let @"=@0&lt;CR&gt; 没有这个问题
        【解决方案10】:

        胶带编程,但对我有用:

        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<
        

        【讨论】:

          猜你喜欢
          • 2011-01-19
          • 2017-05-31
          • 2011-04-13
          • 2023-02-02
          • 1970-01-01
          • 2011-12-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多