Comment faire pour chercher et remplacer avec ack in vim?

J’utilise le plugin Ack dans Vim, ce qui m’aide à rechercher rapidement des chaînes dans mon projet. Cependant, je souhaite parfois remplacer toutes ou certaines occurrences des chaînes trouvées. Vous pouvez faire une sorte de recherche globale et remplacer en utilisant l’architecte Vim comme ceci ( source ):

:args app/views/*/* :argdo %s/, :expire.*)/)/ge | update 

Mais au lieu d’utiliser des args , je préférerais faire une recherche via Ack, puis effectuer le remplacement dans tous les fichiers trouvés. Y a-t-il un moyen de le faire similaire à la commande argdo ?

J’ai décidé d’utiliser ack et Perl pour résoudre ce problème en dehors de Vim afin de pouvoir utiliser les expressions régulières Perl plus puissantes au lieu du sous-ensemble GNU. Vous pouvez mapper ceci à un coup de clé dans votre vimrc.

 ack -l 'pattern' | xargs perl -pi -E 's/pattern/replacement/g' 

Explication

ack

ack est un outil de ligne de commande impressionnant qui combine des expressions régulières grep , find et Perl complètes (pas seulement le sous-ensemble GNU). Il est écrit en Perl pur, il est rapide, il a la mise en évidence des correspondances, fonctionne sous Windows et il est plus convivial pour les programmeurs que les outils de ligne de commande traditionnels. Installez-le sur Ubuntu avec sudo 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 commande perl -pi -E 's/pattern/replacemnt/g' .

perl -pi

Perl est un langage de programmation. L’option -p oblige Perl à créer une boucle autour de votre programme qui itère sur les arguments de nom de fichier. L’option -i oblige Perl à modifier le fichier en place. Vous pouvez modifier cela pour créer des sauvegardes. L’option -E oblige Perl à exécuter la ligne de code spécifiée en tant que 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, voir http://www.perl.org/ .

Maintenant, Vim a cette nouvelle commande cdo qui exécutera la commande donnée à chaque ligne de la liste de correctifs.

Donc, vous pouvez utiliser

 :Ack pattern :cdo s/pattern/newpattern/g 

Je ne crois pas qu’il y ait une manière de faire, mais cela devrait être facile.

Vous devez créer une commande qui appelle une fonction personnalisée. La fonction doit alors utiliser la fonction getqflist() pour obtenir toutes les entrées de la liste de correctifs et exe pour faire le sale boulot. Faites attention à ce que vous passez en argument!

 " Define a command to make it easier to use command! -nargs=+ QFDo call QFDo() " Function that does the work function! QFDo(command) " Create a dictionary so that we can " get the list of buffers rather than the " list of lines in buffers (easy way " to get unique ensortinges) let buffer_numbers = {} " For each entry, use the buffer number as " a dictionary key (won't get repeats) for fixlist_entry in getqflist() let buffer_numbers[fixlist_entry['bufnr']] = 1 endfor " Make it into a list as it seems cleaner let buffer_number_list = keys(buffer_numbers) " For each buffer for num in buffer_number_list " Select the buffer exe 'buffer' num " Run the command that's passed as an argument exe a:command " Save if necessary update endfor endfunction 

Vous pouvez utiliser ack de cette façon

 :args `ack -l User app/` :argdo %s/, :expire.*)/)/ge | update 

Ou utiliser ag

 :args `ag -l User app/` :argdo %s/, :expire.*)/)/gec | w 

J’utilise MacVim (activé avec mvim dans un shell). Je mets les résultats de l’ ack en mvim :

 mvim -f $(ack -l $@) 

Ensuite, dans MacVim, je recherche / remplace par bufdo :

 :bufdo %s/SEARCH/REPLACE/gce | update 

Omettez l’option c si la confirmation n’est pas nécessaire.