J'aimerais optimiser mon flux de travail "trouver et remplacer" dans Vim. C'est quelque chose que je fais souvent, comme la plupart d'entre vous, j'en suis sûr. Généralement, quelque chose comme: copie un bloc et change le nom d'une variable à quelques endroits. Je sais, je sais, cela déclenche probablement votre réflexe "pourquoi copiez-vous et collez-vous du code", mais n'allons pas dans cette voie ... Il existe de nombreux cas d'utilisation valables :)
Je connais bien les commandes de recherche et de remplacement: :s
ou, :%s
mais je ne les aime pas. Cela me force à taper à la fois le nom complet de la variable que je recherche et son changement. Peut-être y a-t-il une meilleure façon de régler le nombre de dactylographies :%s
? J'utilise souvent des noms de variable descriptifs longs, ce qui est donc vraiment un facteur décisif pour moi. Je n'aime pas non plus que le fait de taper un nom de variable à partir de zéro soit sujet aux fautes de frappe et puisse consommer du temps et de la cervelle à la recherche de fautes de frappe. Je préfère de loin taper une fois, puis copier-coller pour éviter cela, si possible.
Mon flux de travail actuel utilise une combinaison de mouvement / tirer / sélectionner / rechercher / mettre pour déplacer le fichier et le remplacer un par un. Ce n'est pas génial, mais a l'avantage d'éviter de taper des noms de variables complets. Je pourrais juste avoir besoin de taper les premières lettres avec /
ou d'utiliser une autre commande de mouvement (par exemple fx
) en fonction de ce qui est autour, puis appuyez sur ve
pour sélectionner le mot entier. Cela ne me dérange pas aussi de devoir répéter chaque fois. Je ne fais jamais un remplacement complet sans confirmer chaque changement. Mais il serait bien préférable que je répète l’action de remplacement avec une seule frappe (ce que je ne peux pas faire avec cette méthode). chaque remplacement est généralement quelque chose comme n
alors ve
alors p
(ou pire encore "0p
)
Y at-il un moyen plus rapide?
la source
.
répète le dernier "bloc de commande" (pas sûr du terme exact. Par exemple: move + action + text. par exemple:cwtoto<Esc>
(changement du curseur à la fin du mot avec "toto"),c/foo<enter>bar<Esc>
(changement du curseur juste avant " foo ", et remplacez par" bar "). vous pouvez alors vous déplacer (avec le curseur, hjkl ou un nombre + hjkl (le fait n fois), G (aller à la fin du fichier), / quelque chose (aller juste avant" quelque chose "), etc) puis appuyez sur.
pour refaire le même" bloc de commande "n
ve
"0p
. Ce qui malheureusement ne peut pas être reproduit avec juste un.
n ce ctrl-r 0 <esc> n.n.n.n.n.n.
Réponses:
J'ai en fait un flux de travail assez similaire au vôtre (copier et coller des blocs similaires, puis utiliser
:s
pour modifier les noms de variables), en particulier lorsque j'écris beaucoup de lignes similaires, à l'exception de la variable qu'elles utilisent. Mais il y a quelques choses que je fais qui pourraient vous être utiles.Choses vim général
La première chose qui vous aidera à comprendre est de
:s//foo/g
remplir le dernier terme de recherche que vous avez utilisé et de le remplacer par foo . Cela seul peut économiser beaucoup de temps, mais lorsque vous le combinez avec la commande astérisque (recherche du mot sous le curseur actuel), vous gagnez un temps précieux. Par exemple, pour tout changerfoo
enspam
, au lieu de faireCe qui vous oblige à taper foo et spam (qui peuvent être de longues variables), vous pouvez simplement naviguer vers foo et faire:
De cette façon, vous pouvez obtenir rapidement le nom de la variable que vous modifiez en la recherchant, sans avoir à la saisir. Cela fonctionnera également bien avec votre flux de travail actuel de
n
beaucoup d’utilisation . C'est également utilehlsearch
, car vous pouvez ainsi visualiser où se trouvent les variables que vous remplacez.(Note: La commande astérisque ajoutera les limites de mots, qui est
\<
et\>
autour du mot sous le curseur Si vous ne voulez pas cela, utilisez. à lag*
place.)Vous pouvez utiliser
@:
pour refaire la dernière commande de substitution. C'est bien si vous voulez faire une:s
commande sur beaucoup de lignes, mais toutes:%s
ne fonctionneront donc pas. Une autre option est le drapeau de confirmation, à savoir:%s///gc
. Cela vous permettra de tapery
oun
à chaque occurrence de décider si vous souhaitez la remplacer ou non.Comme Desty l’a souligné , vous pouvez également &exécuter de nouveau la dernière commande de substitution, mais notez que cela ne conservera pas vos indicateurs (tels que
global
ouconfirm
). Que cela soit bon ou mauvais dépend de votre opinion personnelle. Si vous souhaitez utiliser ceci mais que vous le gardiez aussi, vous pouvez le faire.Si vous souhaitez modifier toutes les occurrences d'un bloc, mais pas toutes les correspondances du fichier, vous pouvez toujours utiliser une sélection visuelle du bloc, qui sera remplie.
à votre remplaçant, ce qui le limite aux lignes que vous avez sélectionnées. Combiné à l'approche astérisque, je trouve cela extrêmement utile. En outre, si vous effectuez plusieurs commandes de substitution sur le même bloc de lignes, vous pouvez utiliser gvpour resélectionner les mêmes lignes afin d'effectuer une autre commande. (que ce
:substitute
soit une commande ou une commande normale)Si vous faites une autre commande de substitution, vous n'avez pas besoin de resélectionner les mêmes lignes, car
:'<,'>
elles fonctionneront toujours sur les mêmes lignes. Cependant, il est plus pratique de taperplutôt que
Plugins / Mappings J'aime
J'ai le mappage suivant dans mon
.vimrc
qui étend l' approche astérisque de sorte que je n'ai qu'à taper le nouveau nom souhaité:Pour l'utiliser, placez simplement votre curseur sur le mot que vous souhaitez modifier, puis tapez
<leader>rNewVarName<cr>
et le tour est joué. Notez que cela remplacera toutes les correspondances sans vous donner l'option de les confirmer, vous pourriez donc ne pas l'aimer autant. Bien sûr, vous pouvez simplement le changer enPour permettre l'option de confirmation.
edit : Suite à la fois à la réponse de la messe et au commentaire de rcorre , vous pouvez aussi écrire ceci comme
Ce qui a l’avantage de garder le même registre que votre nom non nommé.
Si vous renommez des groupes de variables similaires en même temps, par exemple, changez
à
il peut être difficile de les remplacer individuellement. C’est là que tpope / vim-abolish est utile. Vous pouvez remplacer tous ces éléments en une seule commande par:
et il s’occupe de la capitalisation pour vous.
Celles-ci devraient vous aider beaucoup, mais laissez-moi savoir s'il vous manque quelque chose à propos de ces approches. Je suis heureux de parler de plus d'approches. :)
Lecture recommandée:
:h s_c
:h *
:h g*
:h @:
:h /\<
:h &
la source
<leader>rc
(oucr
) d’ajouter cela/c
à la fin. De plus, je suisset gdefault
partant, car je ne veux presque jamais remplacer un seul résultat, alors ce serait justeyiw:%s/\<<C-r>"\>//<left><left>
ctrl+r-ctrl+w
le mappage (comme suggéré par @Mass), il devrait fonctionner de la même manière, mais ne gênera pas votre registre de yank (ce qui peut être souhaitable ou non).
d'effectuer d'autres substitutions.La
c_CTRL-R
famille de cartes peut considérablement améliorer votre flux de travail:Vous n’avez pas besoin de taper de nom de variable lors de l’utilisation
:s/
, vous n'avezCTRL-R
CTRL-W
qu’à insérer le mot sous le curseur dans la ligne de commande (attention: cela n’échappe pas aux caractères spéciaux, comme le*
fait le cas).Après avoir effectué une petite modification en utilisant
ce
, vous pouvez rechercher l'ancien mot en utilisant/
CTRL-R
-
. Puis utilisez.
pour répéter le changement.Si vous devez modifier le modèle de recherche,
CTRL-R
/
la recherche existante sera placée dans la ligne de commande.Enfin, vous pouvez mettre le contenu de tout registre en utilisant
CTRL-R
{register}
la source
Ctrl-R
/
? J'utilise cela assez souvent dans les:s
commandes si je veux utiliser un terme de recherche qui est presque mais pas tout à fait le même que le précédent.Il y a encore quelques méthodes qui (à ma grande surprise!) N'ont pas encore été mentionnées.
Utiliser la
gn
commandegnfonctionne comme la ncommande, sauf qu’en plus de sauter au match, il entre en mode visuel, avec tout le match sélectionné.
Donc, pour changer un mot (ou tout ce que vous pouvez faire correspondre à une expression régulière!), Commencez par chercher 1 , puis appuyez sur cgnsuivi du texte avec lequel vous souhaitez remplacer la correspondance et Escpour revenir au mode normal.
(Vous indiquez que le texte de remplacement que vous souhaitez utiliser est parfois stocké dans le
"0
registre yank. Notez que vous pouvez le saisir rapidement sans avoir à le ressaisir en appuyant sur Ctrl+R0en mode insertion.)Vous pouvez ensuite passer au match suivant et répéter le changement en .appuyant simplement sur une touche!
S'il y a des endroits où vous ne voulez pas faire le remplacement, appuyez simplement sur unpour annuler la modification et passer au match suivant.
1: Rapidement, en utilisant les autres suggestions de cette page, telles que *, Ctrl+RCtrl+Wetc. Voir aussi le commentaire de Peter Rincker pour plus de suggestions sur la manière de remplir initialement votre recherche.
Utiliser le mode de sélection
(Je l' ai appris de romainl de post sur le subreddit vim . Je ne sais pas s'il a inventé lui - même ou était juste de le transmettre.)
Le mode de sélection est un peu comme le mode visuel, sauf si vous commencez à taper le texte sélectionné est immédiatement remplacé par ce que vous tapez (comme le mode de sélection dans la plupart des autres éditeurs).
Vous pouvez donc utiliser ce trio de mappages pour effectuer une recherche / remplacement très rapide, que vous pourrez modifier si nécessaire:
Mappage en mode normal : entre le mode de sélection avec le mot le plus proche du curseur sélectionné.
Vous pouvez ensuite taper votre remplacement pour le mot sélectionné et ( sans appuyer Esc) utiliser le:
Mappage en mode insertion : passe à la correspondance suivante et passe en mode sélection.
Vous pouvez ensuite taper un nouveau remplacement ou appuyer sur .pour utiliser le:
Mappage de mode de sélection : Rentre le dernier texte inséré - essentiellement, répète la dernière insertion.
la source
gn
méthode à la fin de ma réponse vi.stackexchange.com/a/13696/488 hier pour ce que ça vaut! Votre réponse a cependant une mise en forme beaucoup plus agréable.gn
qu'une seule fois) et que c'est la méthode spécifique (plutôt que lagn
commande) qui m'a surpris, n'avait pas encore été mentionnée.gn
. Vous donne plus d'options de recherche. Pauvre homme est la cartographie visuelle étoiles:xnoremap * :<c-u>let @/=@"<cr>gvy:let [@/,@"]=[@",@/]<cr>/\V<c-r>=substitute(escape(@/,'/\'),'\n','\\n','g')<cr><cr>
. Épisode de Vimcasts lié: Opération sur les correspondances de recherche en utilisant gnLe plugin https://github.com/terryma/vim-multiple-cursors s’occupe en grande partie de ce problème.
Mon flux de travail est généralement comme suit:
ctrl-n
jusqu'à ce que tout soit sélectionné.c
et commencez à taper le remplacement.La chose pratique ici est que vous pouvez également faire des opérations plus compliquées que la simple recherche-remplacement, bien que je trouve que si vous allez trop loin, le plug-in commence à montrer quelques problèmes.
la source
Une autre façon de faire des choses qui n’ont pas encore été mentionnées: vous pouvez utiliser la fenêtre de ligne de commande (ouverte avec
q:
en mode normal -:help q:
pour plus d’informations), dans laquelle vous avez un accès complet aux fonctions de complétion automatique de Vim (i_CTRL-N
/i_CTRL-P
et aux différentesi_CTRL-X
séquences être parmi eux).Dans la fenêtre de ligne de commande, vous pouvez également utiliser des commandes en mode normal pour modifier la ligne de commande, ce qui signifie par exemple que vous pouvez extraire et coller des parties de commandes précédentes de votre historique de ligne de commande.
Notez que votre curseur sera déplacé vers la fenêtre de ligne de commande lors de son utilisation, ce qui signifie que
CTRL-R CTRL-W
les méthodes similaires qui impliquent l'insertion de texte sous le curseur ne fonctionneront pas là, contrairement à la ligne de commande normale.la source
:substitute
commande en appuyant sur<ctrl-f>
La solution à cela est un peu entre les autres réponses pour moi:
Supposons que vous ayez 6 lignes identiques et que vous souhaitiez remplacer «pomme» par deux au centre:
Ce que je fais c'est:
v
pour entrer en mode visuel2j
:s/<C-R><C-W>/
qui utilise la sélection visuelle comme plage pour:s
, puis insère le mot sous le curseur<C-F>
ce qui vous met dans un mode où vous pouvez éditer votre commande comme s'il s'agissait d'un tampon. Ainsi, vous pouvez utiliser la complétion ou les plugins pour lesquels vous souhaitez choisir le mot de remplacement, et vous avez terminé.Tout en une ligne, le flux pour ce serait
/apples<CR>2nv/apples<CR>nn:s/<C-R><C-W/oranges<CR>
mais cela semble pire que ce qu'il est.Dans votre cas, vous pouvez ajouter la
/c
à la:s
commande pour ignorer ceux que vous ne voulez pas, si votre gamme contient quelques - unes que vous voulez sauter::s/<C-R><C-W/orange/c
.Sinon (et peut - être plus simplement), vous pouvez rechercher le mot entier que vous voulez remplacer,
c
Hänge, puisgn
et.
de répéter la recherche et appliquer le même changement à nouveau. Cela ressemblerait/\<apple\><CR>viwcorange<ESC>gn.gn.gn..ngn.
à le répéter trois fois, puis à ignorer une instance, puis à le répéter une dernière fois.la source
vim -Nu NONE
). Il émet un bip lorsque j'appuie sur le premier.
. Une idée pourquoi c'est? Dans tous les cas, il serait plus simple d'utiliserciw
au lieu deviw
etn
au lieu d'gn
apporter des modifications de cette manière.Ceci n’est pas entièrement lié à la question, mais devrait néanmoins aider à sélectionner le mot à remplacer.
La recherche incrémentale (
set incsearch
) vous permet de taper le préfixe du mot à rechercher et vim passera automatiquement à la première occurrence du préfixe au fur et à mesure de la frappe. La recherche sera confirmée si vous appuyez sur Entrée et est rejetée sur Échap (dans ce dernier cas, le curseur reviendra à l'endroit où il se trouvait avant le début de la recherche).Cependant, la recherche incrémentielle offre une fonctionnalité supplémentaire utile. Lorsque vous avez déjà saisi le préfixe d'un mot et que le curseur est à la bonne position, appuyez sur
<C-L>
pour ajouter des caractères du mot sous le curseur à la chaîne de recherche. Cela vous permet de saisir la chaîne remplacée presque sans appuyer sur une touche.Donc, si je veux remplacer
someOddVariableName
parevenOdderVariableName
, je/someOddV
et arriver à l'apparition desomeOddVariableName
;<C-L>
jusqu'à ce quesomeOddVariableName
apparaisse complètement dans la ligne de recherche;:%s//evenOdderVariableName/g
ou selon la commande de remplacement dont vous avez besoin; vous voudrez peut-être suivre d'autres réponses ici.la source
Vous pouvez commencer par mettre le nom de la variable dans le tampon (
yw
pour copier un mot), puis le copier-coller:%s
en appuyant sur<C-r>"
.la source
Si vous souhaitez remplacer une variable dans le nouveau bloc (collé), j'ai deux suggestions:
Remplacement automatisé
Allez à la première ligne du nouveau bloc, appuyez sur
ma
. Ceci marque un emplacement et le nommea
.Allez à la dernière ligne du nouveau bloc, appuyez sur
mb
. Vous avez maintenant deux emplacements nommés.Maintenant , remplacer entre les deux lignes, comme suit:
:'a,'bs/oldVarName/newVarName/g
.C'est-à-dire que la portée du remplacement est comprise entre vos deux marques.
La manière manuelle
Aller à la première ligne du nouveau bloc.
Utilisez
/oldVarName
pour trouver la première instance deoldVarName
.Changez-le comme suit:,
cwnewVarName<Esc>
ce qui changera de motnewVarName
et vous échapperez.Utilisez
n
pour aller à la prochaine instance deoldVarName
.Utilisez
.
pour répéter le dernier changement (c'est-à-dire le répétercw
).la source
Beaucoup des autres réponses ici couvrent déjà les moyens intégrés pour améliorer le flux de travail de recherche et remplacement, mais je voulais mentionner abolish.vim , un plugin de Tim Pope. Il effectue des remplacements lorsque vous souhaitez couvrir un plus grand nombre de cas, généralement dus à des variations de cas ou parce que vous devez traiter à la fois les formes au singulier et au pluriel.
:S/child{,ren}/adult{,s}/g
convertit correctementchild
versadult
,Children
versAdults
etCHILD
versADULT
.Si vous avez affaire à des mots traités à la chamelle, vous devez inclure les majuscules où vous en avez besoin dans les mots d'origine et de remplacement.
%:S/wordWrap/textBreak/g
gère correctement les deuxwordWrap
etwordwrap
.la source
Comme d'autres l'ont déjà souligné, si vous avez le curseur placé au-dessus de votre mot, vous pouvez utiliser la famille de commandes Ctrl + r. Ctrl + r Ctrl + w est probablement la plus appropriée.
Cette méthode, cependant, ne fonctionne que pour insérer un mot (celui juste en dessous du curseur), mais que se passe-t-il si il y a plusieurs portions de texte dans la mémoire tampon que nous voulons utiliser? Comme vous ne pouvez pas déplacer votre curseur en ligne de commande. Pour ce faire, le meilleur moyen est de copier des portions de texte dont vous aurez besoin dans différents registres, ce que vous pouvez faire en ajoutant le préfixe "{reg_letter}" à l'opérateur de copie. insérer différents mots dans la ligne de commande plus tard avec Ctrl + r {reg_letter} Ceci est un peu gênant mais fonctionne.
Mais revenons à l’idée précédente, ce serait bien de déplacer la position du curseur sur le tampon lors de l’écriture d’un motif. De cette façon, nous pourrions "sélectionner" du texte à partir de différentes positions avec Ctrl + r Ctrl + w, j'ai donc créé un plugin qui remplit ce but: EXtend.vim Le plugin dispose également de nombreuses autres fonctionnalités permettant d'effectuer des opérations de substitution.
la source