Como colar sem sobrescrever o registro

112

Alguém conhece uma maneira de colar sobre uma área selecionada visualmente sem ter a seleção colocada no registro padrão?

Eu sei que posso resolver o problema sempre colando de um registro explícito. Mas é uma dor de cabeça digitar em "xpvez de apenasp

Starr Horne
fonte

Respostas:

33

"{register}pnão funcionará como você descreve. Substituirá a seleção pelo conteúdo do cadastro. Em vez disso, você terá que fazer algo como:

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

O que deve funcionar, contanto que você não use um plugin que tenha um vmap não nore para p, e que espere que um registro seja sobrescrito.

Este código está disponível como um script . Ingo Karkat também definiu um plugin para resolver o mesmo problema.

Luc Hermitte
fonte
Na verdade, achei que houvesse uma maneira legal de buscar o registrador usado, mas não conseguia lembrar como. Daí a complexidade da função.
Luc Hermitte
1
Acho que isso é um exagero, não vou lembrar do regtype(linewise?) E que remapear p to pgvyé suficiente.
Benoit
2
Pode ser um exagero, mas não tem efeito colateral. Em a "xp, isso não substitui o @"conteúdo com @xdiferente depgvy
Luc Hermitte
1
então o que acontece :xnoremap p pgv@=v:register.'y'<cr>?
Benoit
1
Não funciona para mim. Também tentei baixar o script. Aqui está a lista de comandos que faço: primeiro, pressiono v, depois e para selecionar até o final da palavra e, em seguida, y para puxá-la. Depois disso, vou para uma palavra diferente que desejo substituir. Eu pressiono v, e, em seguida, p para substituir aquele. Então eu faço de novo, mas desta vez a próxima palavra é substituída pela que substituí anteriormente.
Eddy
41

Eu não gosto do comportamento vim padrão de copiar todo o texto eliminado com d, D, cou Cpara o registro padrão.

Eu resolvi isso mapeando dpara "_d, cpara "_ce assim por diante.

Do meu .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
Jeff Lake
fonte
Por mais úteis que esses mapeamentos sejam (eu mesmo faço algo semelhante), eles não respondem à pergunta de OP, p ainda sobrescreverá o que você arrancou colando o conteúdo selecionado.
Magnus
32

Use o seguinte:

xnoremap p pgvy

isso selecionará novamente e puxará novamente qualquer texto colado no modo visual.

Editar: para que isso funcione, "xpvocê pode fazer:

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

v:register expande para o último nome de registro usado em um comando de modo normal.

Benoit
fonte
Em a "xp, essa abordagem sobrescreve @"com @x.
Luc Hermitte
3
Sua sugestão de xnoremap p pgv"@=v:register.'y'<cr>não funcionou para mim. Isso, no entanto, faz:xnoremap <expr> p 'pgv"'.v:register.'y'
mrak
Isso parece interessante. Você poderia adicionar uma linha sobre o que gfaz? Eu não vi isso antes.
LondonRob
4
@LondonRob: gsozinho não faz nada. Ele fornece comandos estendidos de várias teclas, como z. Por exemplo, govai para o enésimo byte no buffer gje gkvai para a próxima linha exibida e a anterior (diferente de jkquando as linhas são quebradas), gaexibe informações sobre o caractere sob o cursor, gJjunta linhas sem espaço e aqui gvrestaura a última seleção visual. Você pode usar :help gv.
Benoit
6
@mark :xnoremap <expr> p 'pgv"'.v:register.'y`>' , adicionei `` `>` `Para restaurar a posição do cursor
rox
19

Na tua .vimrc

xnoremap p "_dP

Eu encontrei isso em uma resposta em um tópico semelhante, mas a fonte original era http://vim.wikia.com/wiki/Replace_a_word_with_yanked_text . Ele menciona algumas desvantagens, mas funciona bem para mim.

Jason Denney
fonte
2
Esta parece ser a solução mais simples.
Rudolph9
1
Funcionou para mim. E essa resposta é clara. .vimrc.localestá bem também.
BaiJiFeiLong
3
Não funciona se sua seleção se estender até o final da linha.
John Freeman
6

A solução de Luc Hermitte funciona perfeitamente. Eu estava usando por cerca de uma semana ou assim. Então descobri uma solução do .vimrc de Steve Losh que funciona muito bem se o YankRing fizer parte da sua linha de plug-in / pacote:

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

Experimente isso em seu ~/.vimrc:

xnoremap <expr> p 'pgv"'.v:register.'y'
  • xnoremapsignifica que isso é apenas para Visualmodo, não Visual + Selectmodos.

  • <expr>significa que {rhs}a xnoremap {lhs} {rhs}configuração é avaliada como uma expressão.

  • Nesse caso, nossa expressão de 'pgv"'.v:register.'y'está usando .para concatenação.

  • v:register é avaliado para o registro que está sendo usado durante o cumprimento do mapeamento.

O resultado de "xpavaliaria para pgv"xy, onde xestá o registro.

Fui ajudado por uma resposta a esta questão stackoverflow: Vim - mapeamento com um prefixo de registro opcional em conjunto com a resposta de Benoit nesta página

mrak
fonte
4

A função de Luc funcionou bem para mim depois que fiz uma alteração para suportar o fato de que tenho a área de transferência = conjunto sem nome:

function! RestoreRegister()
    let @" = s:restore_reg
    if &clipboard == "unnamed"
        let @* = s:restore_reg
    endif
    return ''
endfunction
danprice
fonte
1
Para referência: usando clipboard=unnamedplusisso tem que ser em @+vez de @*.
Sebastian Blask
2

Luc Hermitte fez o truque! Muito bom. Aqui está sua solução colocada em uma função de alternância, para que você possa alternar entre o comportamento normal e a colocação sem substituição de registro.

o comando, você alterna o comportamento

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>
Joernsn
fonte
Você também pode alterar s: Repl para retornar "p" em vez de "p @ = RestoreRegister () \ <cr>" dependendo do valor s: putSwap.
Luc Hermitte,
1
prefira em silent! vunmapvez devnoremap <silent> <expr> p p
Luc Hermitte
0

programação de fita adesiva, mas funciona para mim:

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<
steven_noble
fonte
-4

experimentar -

:set guioptions-=a
:set guioptions-=A
Gowri
fonte
3
Eles controlam se o texto selecionado é adicionado à área de transferência do sistema de janelas (por exemplo, X11 ou Win32), não aos registros de cópia internos do Vim.
Rob Kennedy de