如何粘贴而不覆盖寄存器

Sta*_*rne 103 vi vim

有没有人知道粘贴在一个可视选择区域的方法而没有将选择放在默认寄存器中?

我知道我总是可以通过明确的寄存器来解决问题.但是,打字是一种痛苦,"xp而不仅仅是打字p

Jef*_*ake 38

我不喜欢用拷贝删除了所有文本的默认VIM行为d,D,c,或者C到默认寄存器.

我周围得到通过映射d"_d,c"_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
Run Code Online (Sandbox Code Playgroud)

  • 尽管这些映射很有用(我自己也做了类似的事情),但它们并没有回答OP的问题,p仍然会覆盖您粘贴到所选内容上的内容。 (6认同)

Ste*_*ard 38

用于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)

  • 这应该是公认的答案:) (2认同)

Ben*_*oit 30

使用以下内容:

xnoremap p pgvy
Run Code Online (Sandbox Code Playgroud)

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

编辑:为了与"xp你合作,你可以做到:

xnoremap p pgv"@=v:register.'y'<cr>
Run Code Online (Sandbox Code Playgroud)

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

  • @mark``:xnoremap <expr> p'pgv"'.v:register.'y`>'``,我添加```>``恢复光标位置 (5认同)
  • @LondonRob:`g`一无所获.它提供扩展的多键命令,如`z`.例如,`go`转到缓冲区中的第n个字节,`gj`和`gk`转到下一个和前一个显示的行(当行包裹时不同于`jk`),`ga`显示光标下字符的信息, `gJ`连接没有空格的行,这里`gv`恢复了最后的视觉选择.你可以使用`:help gv`. (4认同)
  • 您对"xnoremap p pgv"@ = v:register.'y'<cr>`的建议对我不起作用.但是,这样做:`xnoremap <expr> p'pgv"'.v:register.' y'` (3认同)

Luc*_*tte 29

"{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()
Run Code Online (Sandbox Code Playgroud)

只要您不使用具有非nore vmap的插件,并且需要覆盖寄存器,这应该没问题.

此代码在那里作为脚本提供.Ingo Karkat还定义了一个解决同一问题的插件.

  • 这可能是矫枉过正,但它没有副作用。在 `"xp` 上,与 `pgvy` 不同,这不会用 `@x` 覆盖 `@"` 内容 (2认同)

Jas*_*ney 15

在你的 .vimrc

xnoremap p "_dP
Run Code Online (Sandbox Code Playgroud)

我从类似线程的响应中找到了这个,但最初的来源是http://vim.wikia.com/wiki/Replace_a_word_with_yanked_text.它提到了一些缺点,但它适用于我.

  • 如果您的选择延伸到行尾,则不起作用。 (5认同)
  • 这似乎是最简单的解决方案。 (2认同)

Tai*_*ine 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  
Run Code Online (Sandbox Code Playgroud)


mra*_*rak 6

尝试在您的~/.vimrc

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

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

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

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

的结果"xp将评估为pgv"xyx寄存器在哪里。

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


小智 5

在我进行了更改以支持剪贴板=未命名设置这一事实后,Luc 的功能对我来说效果很好:

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