J'utilise le plugin Ack dans Vim, qui m'aide à rechercher rapidement des chaînes dans mon projet. Cependant, je souhaite parfois remplacer tout ou partie des occurrences des chaînes trouvées. Vous pouvez faire une sorte de recherche globale et de remplacer en utilisant l'arglist Vim comme ceci ( source ):
:args app/views/*/*
:argdo %s/, :expire.*)/)/ge | update
Mais au lieu d'utiliser args
, je préférerais faire une recherche via Ack et ensuite faire le remplacement dans tous les fichiers qui ont été trouvés. Existe-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 les 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'
ack est un outil de ligne de commande génial qui est un mélange de grep
, find
et d'expressions régulières Perl complètes (pas seulement le sous-ensemble GNU ). Il est écrit en pur Perl, il est rapide, il met en évidence les 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 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 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 à é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/ .
Maintenant, Vim a cette nouvelle commande cdo
qui exécutera la commande donnée sur chaque ligne de la liste de correctifs rapides.
Ainsi, vous pouvez utiliser
:Ack pattern
:cdo s/pattern/newpattern/g
Je ne pense pas qu'il y ait une manière intégrée de faire cela, mais cela devrait être facile à faire.
Ce que vous devez faire est de 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 des correctifs rapides et exe
pour faire le sale boulot. Faites attention à ce que vous passez pour un argument!
" Define a command to make it easier to use
command! -nargs=+ QFDo call QFDo(<q-args>)
" 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 entries)
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 utilisez ag
:args `ag -l User app/`
:argdo %s/, :expire.*)/)/gec | w
J'utilise MacVim (activé avec mvim
dans un Shell). Je dirige les résultats de ack
vers mvim
:
mvim -f $(ack -l $@)
Puis dans MacVim, je recherche/remplace en utilisant bufdo
:
:bufdo %s/SEARCH/REPLACE/gce | update
Omettez l'option c
si la confirmation n'est pas nécessaire.