Existe-t-il un moyen d'utiliser le remplacement de requête à partir des modes de sortie grep / ack / ag?

31

Je suis au courant find-grep-dired, marquant les fichiers correspondants, puis appuyant sur Qpour exécuter dired-do-query-replace-regexples fichiers marqués. Malheureusement, cela nécessite de redémarrer le grep et de ne plus utiliser git-grep, ack ou ag et de passer à l'utilisation find-grepqui a une syntaxe différente pour la recherche.

Je suis également au courant de multi-occuret occur-edit-mode, mais cela nécessite de redémarrer la recherche à l'aide de se produire. Enfin, ag-diredsemble correspondre sur le nom de fichier, pas sur le contenu du fichier.

Mon approche actuelle consiste à générer une sortie grep, puis à exécuter une macro qui démarre dans le tampon grep, visite chaque correspondance et la modifie. Je préférerais utiliser query-replacedirectement sur l'ensemble des correspondances trouvées.

Ce que je voudrais faire, c'est de créer rapidement un tampon dired à partir de la sortie grep existante afin de pouvoir marquer les fichiers appropriés et d'appeler query-regexp dessus, ou de transformer la sortie grep en une liste de tampons pour multi-occurque je puisse l'utiliser occur-edit-modepour éditez-le sur place et exécutez-le query-replacesur ce tampon.

Cette fonctionnalité existe-t-elle ou existe-t-il un autre flux de travail qui résout ce problème?

dgtized
la source

Réponses:

28

@Malabarba a mentionné l'utilisation du wgreppaquet pour éditer les résultats grep / ack / ag.

Je voudrais écrire une présentation détaillée de la façon dont j'utilise le agpackage et les wgrep-agpackages pour réaliser l'édition des résultats «ag» à l'aide du multiple-cursorspackage.

Ces packages sont disponibles via Melpa. Vous devez également avoir agaka the_silver_searcher installé sur votre système.

Cette procédure pas à pas s'applique aux cas où vous recherchez un moyen d'effectuer des modifications sur une seule ligne à tous les emplacements sélectionnés sélectionnés ag.

  • Installez agsur votre système et les packages emacs mentionnés ci-dessus.

  • agprend en charge la recherche de fichiers dont le contenu correspond à l'expression régulière spécifiée. La façon la plus simple de savoir agoù se trouve la racine du projet est d'y placer un .gitdossier vide . Effectuez ensuite la recherche à l'aide de M-x ag-project-regexp.

  • Le tampon de résultats de la recherche ag n'est pas modifiable par défaut. Pour le rendre modifiable, utilisez M-x wgrep-change-to-wgrep-modeou utilisez la wgrepliaison -default C-c C-p.

  • Maintenant, si vous deviez changer 'abcdef' en 'ghijkl' dans tous vos fichiers, vous rechercheriez 'abcdef' et le tampon de résultats ag affichera toutes les lignes contenant cette chaîne. Ensuite, vous modifiez ce tampon et modifiez ces chaînes manuellement et ces modifications se refléteront dans les tampons de fichier réels lors de l'exécution M-x wgrep-finish-editou de l'utilisation de la liaison par défaut C-c C-e. Vous pouvez également utiliser query-replace-regexppour effectuer cette recherche remplacer.

  • Je préfère utiliser multiple-cursorspour une refactorisation rapide afin que je puisse voir un retour en temps réel de l'endroit où mes multiples modifications se produisent simultanément. Mettez en surbrillance la chaîne que vous souhaitez remplacer dans ce tampon de résultats ag et appelez M-x mc/mark-all-like-this, puis modifiez-la avec admiration lorsque vous voyez des éléments modifiés en plusieurs points en même temps.

  • Une fois que vous êtes satisfait des modifications, comme je l'ai mentionné ci-dessus, faites C-c C-epour "refléter" les changements dans les tampons réels. Les tampons ne sont pas encore enregistrés.

  • Pour enregistrer tous les tampons, je le fais généralement en une seule fois, en utilisant la C-x s !liaison par défaut emacs .

Voici un exemple d'utilisation avec des captures d'écran:

Il montre le processus de remplacement de toutes les instances de bind-to-modi-mapto bind-to-my-mapdans my ~/.emacs.d/.

Lorsque je recherche bind-to-modi-mapdans mon dossier de configuration emacs, j'obtiens le résultat ci-dessous 'ag':résultats ag, non modifiés

Ce tampon est en lecture seule.

Après M-x wgrep-change-to-wgrep-mode, je souligne, -modi-mapsélectionnez toutes les instances de cette sélection en utilisant M-x mc/mark-all-like-thiset après avoir édité ces sélections -my-map, cela ressemble à ci-dessous: résultats ag, modifiés à l'aide de curseurs multiples

La surbrillance bleue indique les lignes qui seront modifiées lorsque j'appuie sur C-c C-e.

En frappant C-c C-e, vous pouvez voir le changement reflété dans le fichier réel dans cette capture d'écran: résultats ag, après avoir terminé les modifications

Je voudrais ensuite enregistrer tous les fichiers modifiés en utilisant C-x s !.

Kaushal Modi
la source
C'est vraiment la meilleure façon de remplacer une chaîne. Contenue dans un projet, en tenant compte de l'ag-exclude, facile à faire par lots, tout en étant en mesure de vérifier que vous remplacez la bonne chose.
PascalVKooten
13

Ce que je voudrais faire est soit de créer rapidement un tampon dired à partir de la sortie grep existante, [...] soit de transformer la sortie grep en une liste de tampons pour les événements multiples [...].

Vous n'avez pas besoin de convertir le tampon de résultats grep en quoi que ce soit, il existe déjà un mode spécifiquement pour éditer la sortie grep (et refléter les changements sur les fichiers, bien sûr).

  1. Installez le paquet wgrep de Melpa.
  2. (require 'wgrep) dans votre fichier init.
  3. Après avoir fait une recherche grep, appuyez C-c C-pet modifiez!
  4. Enregistrez vos modifications avec C-c C-e

Il fonctionne même avec ack et ag également.

Malabarba
la source
2
C'est ce que je fais (avec ag.el). Avec l'édition multicurseur de magnars, des refactorings simples sont vraiment faciles.
Tom Regner du
4

Cette fonctionnalité existe dans projectile ( projectile-replace). Il utilisera ag / ack / git grep / grep si disponible (dans cet ordre) pour trouver des occurrences et tags-query-replacepour exécuter le remplacement de requête.

shosti
la source
Cela souffre des mêmes problèmes que find-grep-dired. Il n'utilise pas la sortie grep existante. Il y a des problèmes similaires avec projectile-multi-occurrence. Je préférerais démarrer la requête de remplacement après avoir regardé la liste des correspondances et ne pas changer la méthode de la recherche sous-jacente. Il s'agit cependant d'un flux de travail alternatif.
daté du
Ce que vous décrivez semble être facilement réalisable en créant une macro très rapide pour remplacer le texte et en appelant à plusieurs reprises M-g n C-x e(c'est-à-dire, utilisez next-errorpour faire défiler les occurrences).
shosti
1

Voici une autre approche, en utilisant Icicles .

Dans votre *grep*tampon de sortie Emacs , appuyez sur Cc `(c'est-à-dire Cc backquote), qui en mode Icicle est lié dans le tampon *grep*à la commande icicle-compilation-search. Cela vous permet de naviguer rapidement parmi les résultats de recherche (les greprésultats) que vous choisissez, dans n'importe quel ordre.

L'entrée que vous saisissez dans le mini-tampon filtre dynamiquement (rétrécit) l'ensemble des résultats de recherche, et vous pouvez utiliser l'achèvement progressif pour affiner en faisant correspondre successivement plusieurs modèles (par exemple, sous-chaînes, expressions rationnelles).

Lorsque vous naviguez parmi les résultats de recherche, vous pouvez remplacer n'importe lequel d'entre eux à la demande - soit le résultat complet (ligne) ou uniquement la partie correspondant à votre entrée de mini-tampon actuelle.

Voir Icicles Search - Compile ou Grep . Une introduction à la recherche Icicles est ici , et des informations sur le remplacement des correspondances pendant la recherche Icicles sont ici .

A dessiné
la source
0

J'utilise cet util que j'ai écrit xah_find.el

Je l'ai écrit parce que:

  • Elisp pur. Plus de souci de grep sur Windows ou de transmission Unicode entre emacs et le système d'exploitation. emacs grep problem
  • Si vous êtes un utilisateur intensif d'Unicode, les outils Unix ont des semi-bugs. problème linux uniq
  • Je trouve / remplace chaque semaine des fichiers 5k. J'utilisais dired-do-query-replace-regexp depuis des années. Je trouve que la nature interactive a vraiment gâché mon temps, mais je dois vérifier les résultats des changements. Donc, ma solution est maintenant exécutée par lots, mais j'ai un bon rapport que je peux analyser tous les résultats de recherche / remplacement, avec possibilité d'écrire dans un fichier.

Cet util elisp est peut-être 5 à 10 fois plus lent que d'appeler unix grep dans emacs, mais il a bien fonctionné pour moi.

Xah Lee
la source