Comment coller sans écraser le registre

112

Quelqu'un connaît-il un moyen de coller sur une zone sélectionnée visuellement sans placer la sélection dans le registre par défaut?

Je sais que je peux résoudre le problème en collant toujours à partir d'un registre explicite. Mais c'est une douleur dans le cou de taper "xpau lieu de justep

Starr Horne
la source

Réponses:

33

"{register}pne fonctionnera pas comme vous le décrivez. Il remplacera la sélection par le contenu du registre. Vous devrez à la place faire quelque chose comme:

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

Ce qui devrait être bien tant que vous n'utilisez pas un plugin qui a un vmap non-nore vers p, et qui s'attend à ce qu'un registre soit écrasé.

Ce code est disponible en tant que script il . Ingo Karkat a également défini un plugin résolvant le même problème.

Luc Hermitte
la source
En fait, je pensais qu'il y avait une bonne façon de récupérer le registre utilisé, mais je ne me souvenais pas comment. D'où la complexité de la fonction.
Luc Hermitte
1
Je pense que c'est exagéré, je ne me souviendrai pas du regtype(linewise?) Et que le remappage de p à pgvyest suffisant.
Benoit
2
C'est peut-être exagéré, mais cela n'a aucun effet secondaire. Sur un "xp, cela n'écrase pas le @"contenu avec @xcontrairementpgvy
Luc Hermitte
1
alors qu'en est-il :xnoremap p pgv@=v:register.'y'<cr>?
Benoit
1
Ça ne marche pas pour moi. J'ai également essayé de télécharger le script. Voici la liste des commandes que je fais: J'appuie d'abord sur v, puis sur e pour sélectionner jusqu'à la fin du mot, puis sur y pour le retirer. Après cela, je passe à un mot différent que je veux remplacer. J'appuie sur v, e puis p pour remplacer celui-là. Ensuite, je recommence, mais cette fois, le mot suivant est remplacé par celui que j'ai remplacé plus tôt.
Eddy
41

Je ne aime pas le comportement de vim par défaut de copier tout le texte supprimé avec d, D, cou Cdans le registre par défaut.

Je l'ai contourné en mappant dvers "_d, cvers "_c, etc.

Depuis mon .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
la source
Aussi utiles que soient ces mappages (je fais quelque chose de similaire moi-même), ils ne répondent pas à la question de OP, p écrasera toujours ce que vous avez copié en collant le contenu sélectionné.
Magnus
32

Utilisez le suivant:

xnoremap p pgvy

cela resélectionnera et re-yank tout texte collé en mode visuel.

Edit: pour que cela fonctionne avec, "xpvous pouvez faire:

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

v:register se développe jusqu'au dernier nom de registre utilisé dans une commande en mode normal.

Benoit
la source
Sur a "xp, cette approche remplace @"par @x.
Luc Hermitte
3
Votre suggestion de xnoremap p pgv"@=v:register.'y'<cr>n'a pas fonctionné pour moi. Ceci, cependant, fait:xnoremap <expr> p 'pgv"'.v:register.'y'
mrak
Cela semble intéressant. Pourriez-vous ajouter une ligne sur ce que gfait? Je ne l'ai jamais vu.
LondonRob
4
@LondonRob: gseul ne fait rien. Il fournit des commandes étendues à plusieurs touches, comme z. Par exemple, gova au nième octet dans la mémoire tampon, gjet gkva à la ligne suivante et précédente affichée (diffère de jkquand les lignes sont enveloppées),ga affiche des informations sur le caractère sous le curseur, gJjoint les lignes sans espace et gvrestaure ici la dernière sélection visuelle. Vous pouvez utiliser :help gv.
Benoit
6
@mark :xnoremap <expr> p 'pgv"'.v:register.'y`>' , j'ai ajouté ``> `` Pour restaurer la position du curseur
rox
19

Dans votre .vimrc

xnoremap p "_dP

J'ai trouvé cela à partir d'une réponse sur un fil similaire, mais la source d'origine était http://vim.wikia.com/wiki/Replace_a_word_with_yanked_text . Il mentionne certains inconvénients, mais cela fonctionne très bien pour moi.

Jason Denney
la source
2
Cela semble être la solution la plus simple.
rudolph9
1
A travaillé pour moi. Et cette réponse est claire. .vimrc.localest OK aussi.
BaiJiFeiLong
3
Ne fonctionne pas si votre sélection s'étend jusqu'à la fin de la ligne.
John Freeman
6

La solution de Luc Hermitte fonctionne comme un charme. Je l'ai utilisé pendant environ une semaine. Puis j'ai découvert une solution de .vimrc Steve Losh qui fonctionne bien si YankRing fait partie de votre gamme de plugins / bundles:

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
la source
6

Essayez ceci dans votre ~/.vimrc:

xnoremap <expr> p 'pgv"'.v:register.'y'
  • xnoremapsignifie que ce n'est que pour le Visualmode, pas pour les Visual + Selectmodes.

  • <expr>signifie que {rhs}le xnoremap {lhs} {rhs}paramètre est évalué comme une expression.

  • Dans ce cas, notre expression de 'pgv"'.v:register.'y'utilise .pour la concaténation.

  • v:register est évalué par rapport au registre utilisé lors de l'exécution du mappage.

Le résultat de "xpserait évalué à pgv"xy, où xest le registre.

J'ai été aidé par une réponse à cette question de stackoverflow: Vim - mapping avec un préfixe de registre optionnel en conjonction avec la réponse de Benoit sur cette page

mrak
la source
4

La fonction de Luc a bien fonctionné pour moi après avoir apporté une modification pour prendre en charge le fait que j'ai clipboard = ensemble sans nom:

function! RestoreRegister()
    let @" = s:restore_reg
    if &clipboard == "unnamed"
        let @* = s:restore_reg
    endif
    return ''
endfunction
danprice
la source
1
Pour référence: utiliser clipboard=unnamedplusceci doit être @+au lieu de @*.
Sebastian Blask
2

Luc Hermitte a fait l'affaire! Très bien. Voici sa solution mise dans une fonction de bascule, vous pouvez donc basculer entre le comportement normal et la mise sans remplacement du registre.

la commande, u bascule le comportement

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
la source
Vous pouvez également modifier s: Repl pour renvoyer "p" au lieu de "p @ = RestoreRegister () \ <cr>" en fonction de la valeur de s: putSwap.
Luc Hermitte
1
préférez silent! vunmapau lieu devnoremap <silent> <expr> p p
Luc Hermitte
0

programmation de ruban adhésif, mais fonctionne pour moi:

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
la source
-4

essayez -

:set guioptions-=a
:set guioptions-=A
Gowri
la source
3
Ceux-ci contrôlent si le texte sélectionné est ajouté au presse-papiers du système de fenêtrage (par exemple, X11 ou Win32), pas aux registres de copie internes de Vim.
Rob Kennedy