VIM Remplacer le mot par le contenu du tampon de collage?

110

J'ai besoin de faire un tas de remplacements de mots dans un fichier et je veux le faire avec une commande vi, pas une commande EX telle que :%s///g. Je sais que c'est la manière typique de remplacer le mot à la position actuelle du curseur: cw<text><esc>mais y a-t-il un moyen de le faire avec le contenu du registre sans nom comme texte de remplacement et sans écraser le registre?

plong
la source
8
RÉSOLUTION: Pour mon besoin immédiat, j'avais l'habitude 12ylde tirer 12 caractères et "_cw^r0de remplacer un mot. J'ai ensuite pu utiliser la .commande pour répéter le remplacement dans tout le fichier.
plong

Réponses:

127

Je pense que par "coller" vous entendez le registre sans nom (yank / put / change / delete / substitute), non? (Puisque c'est celui qui serait écrasé par la commande de changement.)

Les registres sont généralement spécifiés en tapant "ensuite le nom (caractère unique) du registre, comme "ayensuite "appour yanker dans le registre a, puis mettre le contenu du registre a. Il en va de même pour une commande de changement. Dans ce cas, si vous ne voulez pas le texte que vous supprimez la commande de changement pour aller n'importe où, vous pouvez utiliser le registre de trou noir "_: "_cw. Puis une fois en mode insertion, vous pouvez appuyer sur ctrl-R suivi du registre que vous voulez (probablement ") mettre dans le contenu de ce registre.

  • "* - registre de sélection (pâte du bouton central)
  • "+ - registre du presse-papiers (probablement également accessible avec ctrl-shift-v via le terminal)
  • "" - registre par défaut (sans nom) de vim yank / put / change / delete / substitute.

Réponse courte: "_cw^R"

Edit: comme d'autres le suggèrent, vous pouvez bien sûr utiliser un registre différent pour le yank (ou autre) qui a mis votre texte dans le registre par défaut. Cependant, vous ne pensez pas toujours à cela en premier, il est donc agréable de faire une seule commande de changement sans l'effacer. Bien que ce ne soit pas totalement époustouflé. Il y a les registres numérotés à "0travers "9:

Vim remplit ces registres avec le texte des commandes yank et delete.

Le registre numéroté 0 contient le texte de la commande yank la plus récente, sauf si la commande spécifie un autre registre avec ["x].

Le registre numéroté 1 contient le texte supprimé par la commande de suppression ou de modification la plus récente, sauf si la commande spécifie un autre registre ou si le texte est inférieur à une ligne (le petit registre de suppression est alors utilisé). Une exception est faite pour l'opérateur de suppression avec ces commandes de mouvement: %, (, ), `, /, ?, n, N, {et }. Le registre "1 est toujours utilisé alors (il est compatible Vi). Le registre" - est également utilisé si la suppression est dans une ligne.

A chaque suppression ou changement successif, Vim décale le contenu précédent du registre 1 dans le registre 2, 2 dans 3, et ainsi de suite, perdant le contenu précédent du registre 9.

Cascabel
la source
1
Très bien, vous pensez avoir copié suffisamment de documents sur les registres dans ma réponse? Tout est là-dessous :help registers.
Cascabel
48

En utilisant les informations de cet article, j'ai formé cette cartographie utile. J'ai choisi «cp» car cela signifie «modifier la pâte»

nmap <silent> cp "_cw<C-R>"<Esc>

ÉDITER:

J'ai également poussé cela plus loin et soutenu toute motion.

Pour obtenir l'équivalent de la commande ci-dessus, ce serait cpwpour "modifier le mot coller"

"This allows for change paste motion cp{motion}
nmap <silent> cp :set opfunc=ChangePaste<CR>g@
function! ChangePaste(type, ...)
    silent exe "normal! `[v`]\"_c"
    silent exe "normal! p"
endfunction
ostler.c
la source
Le <silent> fait que cela ne fonctionne pas pour moi ... une idée de pourquoi cela serait? Je suis un n00b dans les mappages et les fonctions.
Hollister
Le seul problème avec cela est que vous ne pouvez pas choisir un registre avec lequel coller ... mais dans ce cas, je suppose que vous pouvez simplement cw et utiliser CTRL + R
Steve Vermeulen
2
Il y a peut-être un meilleur moyen d'ajouter un nom de registre, mais ce qui suit fonctionne pour moi: nmap <silent> cp :let g:currentRegister=v:register<cr>:set opfunc=ChangePaste<CR>g@ function! ChangePaste(type, ...) silent exe "normal! `[v`]\"_c".getreg(g:currentRegister) endfunction
Steve Vermeulen
@eventualEntropy cela fonctionne bien pour remplacer les lignes, comment puis-je faire fonctionner cela pour des mots au lieu de lignes, j'apprends toujours vim. Merci pour l'aide.
Xavitoj Cheema
@XavitojCheema Je ne me souviens même pas d'avoir fait ce commentaire, haha. Mais il s'avère que j'ai en fait depuis écrit un plugin pour fournir cette fonctionnalité ( github.com/svermeulen/vim-easyclip )
Steve Vermeulen
27

Vous pouvez utiliser le mode visuel de vim pour cela. par exemple, copiez un mot: yepuis écrasez-en un autre avec le mot copié:vep

Ste
la source
9
Cela fonctionne, mais il convient également de noter que la pâte visuelle écrase le tampon de suppression du texte nouvellement supprimé.
ostler.c
24

Si votre curseur est sur le mot que vous souhaitez remplacer par le contenu du registre sans nom, vous pouvez utiliser viwp. vpasse en mode visuel, iwsélectionne le mot interne et premet le contenu du registre à sa place.

En pratique, lorsque j'ai besoin de remplacer un mot (nom de fonction, etc.) par un autre, je passe à celui à utiliser en remplacement, yiwpour extraire le mot interne du registre sans nom, puis passer au mot I ' m le remplacer et viwple remplacer. Moyen assez rapide de remplacer un mot par un autre. Si vous avez recherché ( /) le mot que vous remplacez pour y accéder, vous pouvez simplement appuyer sur npour accéder à l'occurrence suivante que vous devez remplacer. Évidemment, pas de substitut à l'utilisation :%s/find/replace/g, mais pour quelques substitutions rapides, cela peut être pratique, surtout si vous avez déjà le nouveau mot dans un registre.

Travis Northcutt
la source
4
Je suis surpris que ce ne soit pas la solution acceptée: tout ce qui précède, bien que plus flexible dans certains cas marginaux, est beaucoup plus verbeux pour simplement `` échanger le registre sans nom actuel contre une sélection quelque part '', ce qui est la situation d'origine Le demandeur est venu ici pour.
ELLIOTTCABLE
1
Ceci est très utile et intuitif.
lacostenycoder
6

Si vous utilisez un registre nommé (c.-à-d. Utilisez "ayou "ad, etc., pour remplir votre registre de collage), vous pouvez faire quelque chose comme

cw<CTRL-R>a<esc>

Ce qui remplacera le mot par le contenu du registre a. Pour autant que je sache, vous ne pouvez pas utiliser le registre par défaut, car cwil sera rempli avec le mot coupé par cette commande.

Daniel Vandersluis
la source
Vous pouvez utiliser le registre par défaut! Regardez ma réponse.
Cascabel
2

Voulez-vous dire le tampon de collage système ou le registre vi?

Si vous souhaitez utiliser le tampon de collage système, vous êtes bien et pouvez le faire dw"+P- "choisit un registre et "+est le tampon de collage système.

Sinon, copiez dans le registre non par défaut avec dire "aypour copier dans le registre a, puis pour remplacer quelque chose fairedw"aP

Hamish Downer
la source
Merci, Hamish. J'ai essayé cela, mais dwsupprime les espaces de fin après ce que je considérerais comme le «mot», alors que cwne change que le mot. Pour cette raison, dwne fonctionnera pas pour moi.
plong
Dans ce cas, cela dedevrait fonctionner pour vous - il supprimera à la fin de ce mot, tandis que dwsupprimera au début du mot suivant.
Hamish Downer
1

Vous pouvez utiliser ywpour extraire le mot, puis vous pouvez changer le mot avec le mot tiré par vipwpour extraire le mot et coller le mot précédemment retiré.

YevgenyYork
la source
0

Vous pouvez utiliser des registres pour cela:

texte de remplacement de la première place dans le registre <mark some text>"ay

aest le nom du registre

alors vous pouvez utiliser ce registre en remplacement

ve"ap

lollinus
la source
Malheureusement, je ne pouvais pas simplement répéter la dernière opération de collage via ., ce qui est une autre chose que je voulais faire. Merci quand même. Très appréciée.
plong
0

Ou vous pouvez faire Shift+ v- p(sélectionnez la ligne entière et collez à sa place)

Elimirks
la source
1
ou pdw ... N'aimez-vous pas vim? : P
elimirks