Comment puis-je coller (écraser) avec vim?

31

Dans vimj'utilise yyet ptout le temps pour tirer et coller des lignes. Cependant, si je veux remplacer une ligne à plusieurs endroits dans le fichier, je ne peux pas l'utiliser yy p dd pcar le dd supprime la ligne dans le presse-papiers / registre. Bien que je devrais probablement savoir comment mieux utiliser les registres, je pense qu'il existe probablement un moyen de premplacer la ligne actuelle.

cwd
la source

Réponses:

27

Par défaut, les commandes de collage utilisent le "registre («sans nom») . En effet, toute commande qui écrit dans un registre écrit également dans le registre sans nom, donc les tirages, les suppressions et les modifications l'affectent tous. C'est pourquoi votre séquence yank-delete-paste colle le texte supprimé au lieu du texte yanked.

Le 0registre peut aider ici. Toutes les commandes yank qui ne spécifient pas de registre mettent le texte yanked dans le registre 0(en plus de "). Il n'est pas affecté par les opérations de suppression ou de modification, vous pouvez donc l'utiliser pour coller plusieurs fois une ligne tirée, même si vous effectuez des suppressions ou des modifications intermédiaires.

  1. yy: Les registres 0et les "deux ont maintenant la ligne tirée.
  2. Déplacer vers une ligne à remplacer.
  3. dd: Le registre a "maintenant la ligne supprimée, mais le registre a 0toujours la ligne tirée.
    "0P: Collez la ligne initialement tirée du registre 0.
  4. Passez à la ligne suivante pour remplacer.
  5. dd"0P (comme ci-dessus)

(En raison de la façon dont le positionnement du curseur fonctionne lors du remplacement de la dernière ligne d'un tampon, vous souhaiterez utiliser à la "0pplace de "0P.)

Ceci est très proche de la réponse de Bruce Ediger , sauf que vous n'avez pas besoin de spécifier un registre lors du tirage initial. L'utilisation d'un ou plusieurs registres nommés peut être très pratique si vous devez (par exemple) remplacer certaines lignes par AAA, mais d'autres lignes par BBB(mettre AAAdans le registre aet BBBdans le registre b(ou laisser l'une d'entre elles dans le registre 0), puis collez-les en conséquence ).

Vous pouvez également coller à partir 0en mode visuel ligne par ligne ( V) pour enregistrer une séquence de touches: V"0p.

Si vous n'aimez pas avoir à taper "0, vous pouvez trouver un mappage plus pratique:

noremap <Leader>p "0p
noremap <Leader>P "0P
vnoremap <Leader>p "0p

Une autre approche consiste à supprimer le _registre («trou noir») . Lorsque vous le supprimez, le "registre n'est pas affecté, donc votre séquence yank-delete-paste peut toujours coller le texte retiré du registre sans nom.

  1. yy: Inscrivez-vous 0et les "deux ont maintenant la ligne tirée.
  2. "_dd: Pas de changement dans les registres.
    P: Collez le texte originellement retiré du registre ".

Encore une fois, vous pourriez trouver un mappage plus pratique:

noremap <Leader>d "_d
Chris Johnsen
la source
2
Ou, tl; dr, utilisez simplement yy(déplacer vers la ligne à remplacer) S<C-r>0<Esc>. A l'avantage d'être reproductible avec la .commande.
Wildcard
11

On dirait que Kevin a une assez bonne réponse, mais si vous voulez jeter un œil sur chaque ligne que vous supprimez, puis remplacez, une solution légèrement différente existe.

1. Find line to copy in some select number of places.
2. Put cursor on it.
3. "ayy copies that line into register 'a'.
4. Find line to replace. Put cursor on it.
5. dd deletes that line. "aP inserts the copied line above where the cursor now lies.
6. Repeat steps 4 and 5.

Ce type de recette vous permet d'utiliser la correspondance de motifs pour trouver des lignes à supprimer et à remplacer, et vous pouvez revenir au début du fichier (1G) et effectuer une recherche vers l'avant aussi souvent que vous le souhaitez. Si j'ai 2 lignes ou plus à rassembler et à placer à plusieurs reprises, j'utilise "ayypour la première ligne, "byypour la seconde, "cyypour la troisième, etc. J'ai pris l'habitude (ce qui réduit la généralité de la recette) de diminuer la charge mentale sur moi.

Bruce Ediger
la source
Très agréable. Donc, si j'utilise "ayyet ensuite dd, ddne remplacera pas ce qui est dedans a, mais si je tape, pil collera ce qui vient d'être supprimé à l'aide dd. Et si je voulais remplacer ce qui se trouve "ayypar ce que je supprime, alors j'utiliserais "add- est-ce vrai?
cwd
"ayy copie une ligne dans le registre 'a'." dd "coupe une ligne dans un registre par défaut, pas 'a'. 'p' colle le registre par défaut, correct. Et oui," add coupe une ligne dans le registre 'a' , qui remplacerait le contenu de la "commande ayy.
Bruce Ediger
5

Il existe plusieurs façons de le faire :s, selon la quantité de frappe que vous souhaitez effectuer. Le moyen le plus simple est une simple recherche et remplacement:

:%s/find this line/replace with this/

La %recherche dans tout le fichier et remplace toutes les occurrences.

Si c'est trop de frappe pour vous, vous pouvez extraire la chaîne de destination ( yy) et utiliser le "registre (par défaut), en l'insérant avec Ctrl+r ":

:%s/<ctrl+r><">/replacement/

Ou, si vous avez une copie de la chaîne de remplacement, vous pouvez séparer les deux dans des registres séparés avec "ayyet "byypour extraire respectivement dans les registres aet b(vous pouvez utiliser n'importe quelle lettre pour vos registres). Utilisez ensuite Ctrl+r aet Ctrl+r bpour les coller dans les champs de recherche et de remplacement.

Pas pour Bruce, mais si vous voulez vérifier les lignes avant de les remplacer, ajoutez simplement l' coption:

:%s/find this line/replace with this/c
Kevin
la source
2

Vous pouvez utiliser Vpour mettre en surbrillance la ligne que vous souhaitez remplacer en mode visuel, puis appuyer sur pppour coller sur cette ligne.

Cela n'ajoute qu'une touche, cela semble donc être une assez bonne solution.

mouche
la source
Cela ne fonctionne pas: après le collage, le presse-papiers contient le texte qui a été marqué parV
daniel kullmann
Un seul p.
Aaron Thoma
2

J'utilise la commande c"change" assez souvent pour ce genre de chose, combinée à une recherche régulière. Vous pouvez rechercher dans le fichier chaque ligne / morceau de texte qui vous intéresse, puis utiliser des n.commandes consécutives ( npour ensuite, puis .pour répéter la dernière modification.)

/^hello- trouver la ligne commençant par bonjour;
c$goodbye- changer la ligne en au revoir;
n.- répéter la recherche, répéter le changement

Si vous souhaitez modifier la ligne en une déjà dans le fichier, vous pouvez simplement la copier dans votre tampon d'entrée (en supposant que votre interface graphique le permet), puis la coller pour obtenir le contenu de la première commande de modification.

Comme pour tout ce qui est vi, c'est une bonne idée d'avoir beaucoup d'options dans votre poche, selon le type de modification que vous souhaitez effectuer.

rghome
la source