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

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 lá . Ingo Karkat também definiu um plugin para resolver o mesmo problema.


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

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.


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.


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  

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


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

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>

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<

-4

experimentar -

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

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.