web-dev-qa-db-fra.com

Comment rechercher et remplacer par ack dans vim?

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?

53

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'

Explication

accuser

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

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 à é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/ .

93
Eric Johnson

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
34
rools

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
16
DrAl

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
10
Ilake Chang

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.

9
milkfarm