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 . 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.