Je cherche le meilleur moyen de rechercher et remplacer (avec confirmation) dans tous les fichiers de projet dans Vim. Par «fichiers de projet», j'entends les fichiers du répertoire courant, dont certains n'ont pas besoin d'être ouverts.
Une façon de faire pourrait être d'ouvrir simplement tous les fichiers du répertoire courant:
:args ./**
puis effectuez la recherche et le remplacement sur tous les fichiers ouverts:
:argdo %s/Search/Replace/gce
Cependant, lorsque je fais cela, l'utilisation de la mémoire de Vim passe de quelques dizaines de Mo à plus de 2 Go, ce qui ne fonctionne pas pour moi.
J'ai également installé le plugin EasyGrep , mais il ne fonctionne presque jamais - soit il ne trouve pas toutes les occurrences, soit il se bloque jusqu'à ce que j'appuie sur CtrlC. Jusqu'à présent, ma manière préférée d'accomplir cette tâche est d' ack-grep pour le terme de recherche, en utilisant sa fenêtre de correction rapide, ouvrez tout fichier contenant le terme et qui n'a pas été ouvert auparavant, et enfin :bufdo %s/Search/Replace/gce
.
Je recherche soit un bon plugin fonctionnel qui puisse être utilisé pour cela, soit une commande / séquence de commandes qui serait plus facile que celle que j'utilise actuellement.
Réponses:
Greplace fonctionne bien pour moi.
Il existe également une version prête pour les agents pathogènes sur github.
la source
:Gsearch
et:Gbuffersearch
existent, mais quand je tape:Greplace
je reçoisNot an editor command: Greplace
.:Gsearch [<grep-option(s)>] [[<pattern>] [<filename(s)>]]
vous pouvez donc faire une recherche récursive en utilisant, par exemple::Gsearch -r pattern dir/
L'autre grande option ici est simplement de ne pas utiliser vim:
ou si vous avez un moyen de générer une liste de fichiers, peut-être quelque chose comme ceci:
etc!
la source
sed
des expressions régulières, qui sont essentiellement des expressions régulières de base POSIX.2, mais pas exactement (c'est dans la page de manuel) - elles permettent de faire\n
correspondre les nouvelles lignes, et d'autres choses similaires. Ils sont donc à peu près les mêmes quegrep
les expressions régulières.find . -type f | LANG=C xargs sed -i '' 's/SEARCH/REPLACE/g'
EDIT: utilisez la
cfdo
commande au lieu decdo
pour réduire considérablement le nombre de commandes qui seront exécutées pour accomplir cela (carcdo
exécute des commandes sur chaque élément tout encfdo
exécutant des commandes sur chaque fichier)Grâce à la
cdo
commande récemment ajoutée , vous pouvez maintenant le faire en deux commandes simples en utilisant n'importe quelgrep
outil que vous avez installé. Aucun plug-in supplémentaire requis !:(
cdo
exécute la commande donnée pour chaque terme de la liste de correctifs rapides, que votregrep
commande remplit.)(Supprimez le
c
à la fin de la 2ème commande si vous souhaitez remplacer chaque terme de recherche sans confirmer à chaque fois)la source
:cdo update
pour enregistrer les modifications dans tous les fichiers.c
à la fin de la deuxième commande (utilisez simplementg
) pour le faire rechercher et remplacer sans demander de confirmationupdate
, je devais:cdo %s/<search term>/<replace term>/g | update
J'ai décidé d'utiliser ack et Perl pour résoudre ce problème afin de tirer parti des expressions régulières Perl complètes plus puissantes plutôt que du sous-ensemble GNU.
Explication
accuser
ack est un outil impressionnant de ligne de commande qui est un mélange de
grep
,find
et plein d' expressions régulières Perl (pas seulement le sous - ensemble GNU). Il est écrit en pur Perl, rapide, il a la coloration syntaxique, fonctionne sous Windows et est plus convivial pour les programmeurs que les outils de ligne de commande traditionnels. Installez-le sur Ubuntu avecsudo apt-get install ack-grep
.xargs
Xargs est un ancien outil de ligne de commande unix. Il lit les éléments de l'entrée standard et exécute la commande spécifiée suivie des éléments lus pour l'entrée standard. Donc, fondamentalement, la liste des fichiers générés par ack est ajoutée à la fin de la
perl -pi -E 's/pattern/replacemnt/g'
commande.perl -pi
Perl est un langage de programmation. L'option -p amène Perl à créer une boucle autour de votre programme qui itère sur les arguments de nom de fichier. L'option -i oblige Perl à éditer le fichier sur place. Vous pouvez le modifier pour créer des sauvegardes. L'option -E oblige Perl à exécuter la ligne de code spécifiée comme programme. Dans notre cas, le programme est juste une substitution de regex Perl. Pour plus d'informations sur les options de ligne de commande Perl
perldoc perlrun
. Pour plus d'informations sur Perl, consultez http://www.perl.org/ .la source
peut-être faire ceci:
Explication:
:noautocmd vim /Search/ **/*
⇒ rechercher (vim
est une abréviation pourvimgrep
) motif dans tous les fichiers de tous les sous-répertoires du cwd sans déclencher autocmds (:noautocmd
), pour des raisons de vitesse.:set hidden
⇒ permettre d'avoir des tampons modifiés non affichés dans une fenêtre (pourrait être dans votre vimrc):cfirst
⇒ passer au premier résultat de rechercheqa
⇒ commencer l'enregistrement d'une macro dans le registre a:%s//Replace/gce
⇒ remplacer toutes les occurrences du dernier modèle de recherche (toujours/Search/
à ce moment-là) parReplace
:g
drapeau)c
drapeau)e
drapeau):cnf
⇒ passer au fichier suivant dans la liste créée par lavim
commandeq
⇒ arrêter l'enregistrement de la macro1000@a
⇒ jouer la macro stockée dans le registre 1000 fois:wa
⇒ enregistrer tous les tampons modifiés* EDIT * Voie Vim 8:
À partir de Vim 8, il existe une meilleure façon de le faire, car il se
:cfdo
répète sur tous les fichiers de la liste des correctifs rapides:la source
vim
m'a convaincu pour beaucoup de choses, je pense que je vais m'en tenir à PowerGrep avec cela.Remplir à
:args
partir d'une commande shellIl est possible (sur certains systèmes d'exploitation 1 )) de fournir les fichiers
:args
via une commande shell.Par exemple, si vous avez installé ack 2 ,
demandera à ack de retourner une liste de fichiers contenant 'pattern' et de les mettre dans la liste d'arguments.
Ou avec un vieux grep ordinaire, je suppose que ce serait:
Vous pouvez alors simplement utiliser
:argdo
comme décrit par l'OP:Remplir à
:args
partir de la liste des correctifs rapidesConsultez également la réponse de nelstrom à une question connexe décrivant une commande simple définie par l'utilisateur qui remplit l'arglist à partir de la liste de correctifs rapides actuelle. Cela fonctionne très bien avec de nombreuses commandes et plugins dont la sortie se termine dans la liste des correctifs rapides (
:vimgrep
,:Ack
3 ,:Ggrep
4 ).La séquence pour effectuer une recherche à l'échelle du projet pourrait alors être effectuée avec:
où
:Qargs
est l'appel à la commande définie par l'utilisateur qui remplit l'arglist à partir de la liste de correctifs rapides.Vous trouverez également des liens dans la discussion qui suit vers des plugins simples qui réduisent ce flux de travail à 2 ou 3 commandes.
Liens
la source
Une autre option en 2016, le plugin far.vim :
la source
Si cela ne vous dérange pas d'introduire une dépendance externe, j'ai préparé un plugin ctrlsf.vim (dépend de ack ou ag ) pour faire le travail.
Il peut formater et afficher les résultats de la recherche depuis ack / ag, et synchroniser vos modifications dans le tampon de résultats avec les fichiers réels sur le disque.
Peut-être que la démo suivante explique plus
la source
L'étape 1 remplit la liste des correctifs rapides avec les éléments souhaités. Dans ce cas, il est propagé avec les termes de recherche que vous souhaitez modifier via
grep
.cfdo
exécute la commande suivante sur chaque fichier de la liste des correctifs rapides. Tapez:help cfdo
pour plus de détails.s/<search term>/<replace term>/g
remplace chaque terme./g
signifie remplacer chaque occurrence du fichier.| update
enregistre le fichier après chaque remplacement.J'ai reconstitué cela sur la base de cette réponse et de ses commentaires, mais j'ai estimé qu'il méritait sa propre réponse car tout est au même endroit.
la source
2. :cfdo %s/<search term>/<replace term>/g | update
Sans le%
, seule la première occurrence du motif est remplacée.%s
fonctionne également sur vim régulier.Fondamentalement, je voulais le remplacement en une seule commande et surtout dans vim lui-même
Sur la base de la réponse de @Jefromi, j'ai créé un raccourci clavier, que j'avais défini dans mon fichier .vimrc comme ceci
maintenant à partir du vim, sur un coup de leader + r je reçois la commande chargée dans vim, que j'édite comme ci-dessous,
Par conséquent, je fais le remplacement avec une seule commande et, plus important encore, dans vim lui-même
la source