¿Hay alguna manera de usar query-replace desde los modos de salida grep / ack / ag?

31

Soy consciente de find-grep-diredmarcar los archivos correspondientes y luego presionar Qpara ejecutar dired-do-query-replace-regexplos archivos marcados. Desafortunadamente, eso requiere reiniciar el grep y ya no usar git-grep, ack o ag y cambiar a usar find-grepque tiene una sintaxis diferente para la búsqueda.

También estoy al tanto de multi-occury occur-edit-mode, pero eso requiere reiniciar la búsqueda usando. Finalmente, ag-diredparece coincidir con el nombre del archivo, no con el contenido del archivo.

Mi enfoque actual es generar resultados grep, y luego ejecutar una macro que comienza en el búfer grep, y visita cada partido y lo cambia. Preferiría usar query-replacedirectamente sobre el conjunto de coincidencias encontradas.

Lo que me gustaría hacer es crear rápidamente un búfer directo a partir de la salida grep existente para poder marcar los archivos apropiados y llamar a query-regexp en ellos, o transformar la salida grep en una lista de buffers para multi-occurque pueda usar occur-edit-modepara editarlo en su lugar y ejecutar query-replaceen ese búfer.

¿Existe esta funcionalidad o hay otro flujo de trabajo que resuelva este problema?

dgtized
fuente

Respuestas:

28

@Malabarba mencionó el uso del wgreppaquete para editar resultados grep / ack / ag.

Me gustaría escribir un recorrido detallado de cómo uso el agpaquete y los wgrep-agpaquetes para lograr la edición de resultados 'agregados' usando el multiple-cursorspaquete.

Estos paquetes están disponibles a través de Melpa. También necesita tener agaka the_silver_searcher instalado en su sistema.

Este recorrido se aplica a los casos en los que está buscando una forma de realizar ediciones de una sola línea en todas las ubicaciones seleccionadas ag.

  • Instale agen su sistema y los paquetes de emacs mencionados anteriormente.

  • agadmite la búsqueda de archivos con contenido que coincida con la expresión regular especificada. La forma más sencilla de saber agdónde está la raíz del proyecto es colocar una .gitcarpeta vacía allí. Luego haga la búsqueda usando M-x ag-project-regexp.

  • El búfer de resultados de la búsqueda ag no es editable por defecto. Para hacerlo editable, haga M-x wgrep-change-to-wgrep-modeo use el wgrepenlace predeterminado C-c C-p.

  • Ahora, si necesita cambiar 'abcdef' a 'ghijkl' en todos sus archivos, buscaría 'abcdef' y el búfer de resultados ag mostrará todas las líneas que contienen esa cadena. Luego, hace que el búfer sea editable y cambie esas cadenas manualmente y esos cambios se reflejarán en los búferes de archivo reales al hacer M-x wgrep-finish-edito usar el enlace predeterminado C-c C-e. También puede usar query-replace-regexppara hacer esa búsqueda reemplazar.

  • Prefiero usar multiple-cursorspara una refactorización rápida para poder ver una retroalimentación en tiempo real de dónde están ocurriendo mis ediciones múltiples simultáneamente. Resalte la cadena que desea reemplazar en ese búfer de resultados ag y llame M-x mc/mark-all-like-thisy luego edite con asombro mientras ve que las cosas se editan en varios puntos al mismo tiempo.

  • Una vez que esté satisfecho con las ediciones, como mencioné anteriormente, hágalo C-c C-epara "reflejar" los cambios en los búferes reales. Los buffers aún no se han guardado.

  • Para guardar todos los búferes, generalmente lo hago de una vez, usando el C-x s !enlace predeterminado de emacs .

Aquí hay un ejemplo de caso de uso con capturas de pantalla:

Muestra el proceso de reemplazar todas las instancias de bind-to-modi-mapto bind-to-my-mapen my ~/.emacs.d/.

Cuando busco bind-to-modi-mapen mi carpeta de configuración de emacs, obtengo el siguiente resultado 'ag'ged:resultados ag, sin modificar

Este búfer es de solo lectura.

Después M-x wgrep-change-to-wgrep-mode, resalto, -modi-mapseleccione todas las instancias de esa selección usando M-x mc/mark-all-like-thisy después de editar esas selecciones -my-map, se ve a continuación: resultados ag, modificados con múltiples cursores

El resaltado azul muestra qué líneas se modificarán cuando presione C-c C-e.

Al golpear C-c C-e, puede ver el cambio reflejado en el archivo real en esta captura de pantalla: resultados ag, después de terminar las ediciones

Luego guardaría todos los archivos modificados usando C-x s !.

Kaushal Modi
fuente
Esta es realmente la mejor forma de reemplazar cadenas. Contenido en un proyecto, pensando en ag-exclude, lote fácil de hacer, aún pudiendo verificar que está reemplazando lo correcto.
PascalVKooten
13

Lo que me gustaría hacer es crear rápidamente un búfer directo a partir de la salida grep existente [...] o transformar la salida grep en una lista de búferes para múltiples [...].

No necesita convertir el búfer de resultados grep en nada, ya existe un modo específicamente para editar la salida grep (y reflejar los cambios en los archivos, por supuesto).

  1. Instale el paquete wgrep de Melpa.
  2. (require 'wgrep) en su archivo de inicio.
  3. Después de hacer una búsqueda grep, ¡presiona C-c C-py edita!
  4. Guarda tus ediciones con C-c C-e

Incluso funciona con ack y ag también.

Malabarba
fuente
2
Eso es lo que hago (con ag.el). Junto con la edición multicursor magnars, las refactorizaciones simples son realmente fáciles.
Tom Regner
4

Esta funcionalidad existe dentro de proyectil ( projectile-replace). Utilizará ag / ack / git grep / grep si está disponible (en ese orden) para encontrar ocurrencias y tags-query-replaceejecutar la consulta de reemplazo.

shosti
fuente
Eso sufre los mismos problemas que find-grep-dired. No está utilizando la salida grep existente. Hay problemas similares con el proyectil múltiple. Preferiría comenzar el reemplazo de la consulta después de mirar la lista de coincidencias y no cambiar el método de búsqueda subyacente. Sin embargo, es un flujo de trabajo alternativo.
Dgtized
Lo que está describiendo parece que puede lograrse fácilmente al hacer una macro muy rápida para reemplazar el texto y llamar repetidamente M-g n C-x e(es decir, usar next-errorpara desplazarse por las ocurrencias).
shosti
1

Aquí hay otro enfoque, usando Icicles .

En su *grep*búfer de salida de Emacs , presione Cc `(eso es una comilla inversa de Cc), que en el modo Icicle está enlazado en el búfer *grep*al comando icicle-compilation-search. Esto le permite navegar rápidamente entre cualquiera de los resultados de búsqueda (los grepresultados) que elija, en cualquier orden.

La entrada que escriba en el minibúfer filtra dinámicamente (reduce) el conjunto de resultados de búsqueda, y puede usar la finalización progresiva para reducir mediante la coincidencia sucesiva de múltiples patrones (por ejemplo, subcadenas, expresiones regulares).

Al navegar entre los resultados de búsqueda, puede reemplazar cualquiera de ellos a pedido, ya sea el resultado completo (línea) o solo la parte que coincide con su entrada de minibúfer actual.

Ver Icicles Search - Compilar o Grep . Una introducción a la búsqueda de Icicles está aquí , y la información sobre el reemplazo de coincidencias durante la búsqueda de Icicles está aquí .

Dibujó
fuente
0

Yo uso esta utilidad escribí xah_find.el

Lo escribí porque:

  • Pura elisp. No se preocupe más por grep en Windows o transmisión Unicode entre emacs al sistema operativo. problema grema de emacs
  • Si es un gran usuario de Unicode, las herramientas de Unix tienen algunos semi-errores. problema de Linux uniq
  • Encuentro / reemplazo cada semana en archivos de 5k. Estuve usando dired-do-query-replace-regexp durante años. Me parece que la naturaleza interactiva realmente me quitó el tiempo, pero necesito verificar los resultados de los cambios. Entonces, mi solución ahora se ejecuta por lotes, pero tengo un buen informe que puedo escanear en todos los resultados de búsqueda / reemplazo, con la opción de escribir en el archivo.

Esta utilidad elisp es quizás 5 a 10 veces más lenta que llamar a unix grep en emacs, pero funcionó bien para mí.

Xah Lee
fuente