Apakah ada cara untuk menggunakan query-replace dari mode keluaran grep / ack / ag?

31

Saya sadar find-grep-dired, menandai file yang sesuai dan kemudian menekan Quntuk menjalankan dired-do-query-replace-regexpfile yang ditandai. Sayangnya itu membutuhkan restart grep dan tidak lagi menggunakan git-grep, ack, atau ag dan beralih menggunakan find-grepyang memiliki sintaks berbeda untuk pencarian.

Saya juga menyadari multi-occurdan occur-edit-mode, tetapi itu membutuhkan restart pencarian menggunakan terjadi. Akhirnya, ag-diredtampaknya cocok dengan nama file, bukan pada isi file.

Pendekatan saya saat ini adalah untuk menghasilkan keluaran grep, dan kemudian menjalankan makro yang dimulai pada buffer grep, dan mengunjungi setiap kecocokan dan mengubahnya. Saya lebih suka menggunakan query-replacelangsung dari set pertandingan yang ditemukan.

Apa yang ingin saya lakukan adalah dengan cepat membangun buffer dired dari output grep yang ada sehingga saya dapat menandai file yang sesuai dan memanggil query-regexp pada mereka, atau mengubah output grep menjadi daftar buffer untuk multi-occursehingga saya dapat menggunakan occur-edit-modeuntuk sunting di tempatnya dan jalankan query-replacedi buffer itu.

Apakah fungsi ini ada, atau apakah ada alur kerja lain yang memecahkan masalah ini?

dgtized
sumber

Jawaban:

28

@Malabarba menyebutkan penggunaan wgreppaket untuk mengedit hasil grep / ack / ag.

Saya ingin menulis walk-through terperinci tentang bagaimana saya menggunakan agpaket dan wgrep-agpaket untuk mencapai pengeditan hasil 'menggunakan multiple-cursorspaket menggunakan .

Paket-paket ini tersedia melalui Melpa. Anda juga harus memasang agalias the_silver_searcher di sistem Anda.

Walk-through ini berlaku untuk kasus-kasus di mana Anda mencari cara untuk melakukan pengeditan satu baris di semua / lokasi terpilih yang agditemukan.

  • Instal agpada sistem Anda dan paket emacs yang disebutkan di atas.

  • agmendukung pencarian file dengan konten yang cocok dengan regex yang Anda tentukan. Cara paling sederhana untuk mengetahui di agmana root proyek adalah meletakkan .gitfolder kosong di sana. Kemudian lakukan pencarian menggunakan M-x ag-project-regexp.

  • Buffer hasil pencarian ag tidak dapat diedit secara default. Untuk membuatnya dapat diedit, lakukan M-x wgrep-change-to-wgrep-modeatau gunakan wgreppengikatan -default C-c C-p.

  • Sekarang jika Anda perlu mengubah 'abcdef' menjadi 'ghijkl' di semua file Anda, Anda akan mencari 'abcdef' dan buffer hasil ag akan menampilkan semua baris yang berisi string itu. Kemudian Anda membuat buffer itu dapat diedit dan mengubah string-string itu secara manual dan perubahan-perubahan itu akan tercermin dalam buffer file aktual untuk melakukan M-x wgrep-finish-editatau menggunakan pengikatan default C-c C-e. Anda juga dapat menggunakan query-replace-regexpuntuk melakukan penggantian pencarian itu.

  • Saya lebih suka menggunakan multiple-cursorsuntuk refactoring cepat sehingga saya bisa melihat umpan balik waktu nyata di mana beberapa pengeditan saya terjadi secara bersamaan. Sorot string yang ingin Anda ganti di buffer hasil dan panggilan ag M-x mc/mark-all-like-thislalu edit dengan kagum saat Anda melihat hal-hal yang diedit di beberapa titik pada saat yang sama.

  • Setelah Anda puas dengan pengeditan, seperti yang saya sebutkan di atas, lakukan C-c C-euntuk "mencerminkan" perubahan dalam buffer yang sebenarnya. Buffer belum disimpan.

  • Untuk menyimpan semua buffer, saya biasanya melakukannya sekaligus, menggunakan C-x s !pengikatan default emacs .

Berikut adalah contoh kasus penggunaan dengan tangkapan layar:

Ini menunjukkan proses mengganti semua contoh bind-to-modi-mapke bind-to-my-mapdalam ~/.emacs.d/.

Ketika saya mencari bind-to-modi-mapdi folder pengaturan emacs saya, saya mendapatkan hasil 'di bawah ini:hasil ag, tidak dimodifikasi

Buffer ini hanya baca.

Setelah M-x wgrep-change-to-wgrep-mode, saya sorot,, -modi-mappilih semua contoh pilihan itu menggunakan M-x mc/mark-all-like-thisdan setelah mengedit pilihan -my-mapitu, terlihat seperti di bawah ini: hasil ag, dimodifikasi menggunakan multi-kursor

Sorotan biru menunjukkan garis mana yang akan dimodifikasi ketika saya menekan C-c C-e.

Saat memukul C-c C-e, Anda dapat melihat perubahan yang tercermin dalam file aktual di tangkapan layar ini: hasil ag, setelah menyelesaikan pengeditan

Saya kemudian akan menyimpan semua file yang dimodifikasi menggunakan C-x s !.

Kaushal Modi
sumber
Ini benar-benar cara terbaik untuk mengganti string. Berisi proyek, tidak termasuk ag, mengecek mudah, masih dapat memverifikasi Anda mengganti hal yang benar.
PascalVKooten
13

Apa yang ingin saya lakukan adalah dengan cepat membangun buffer dired dari output grep yang ada [...], atau mengubah output grep menjadi daftar buffer untuk multi-terjadi [...].

Anda tidak perlu mengubah buffer hasil grep menjadi apa pun, sudah ada mode khusus untuk mengedit output grep (dan tentu saja mencerminkan perubahan pada file).

  1. Instal wgrep paket dari Melpa.
  2. (require 'wgrep) dalam file init Anda.
  3. Setelah melakukan pencarian grep, tekan C-c C-pdan edit pergi!
  4. Simpan hasil edit Anda dengan C-c C-e

Ia bahkan bekerja dengan ACK dan AG juga.

Malabarba
sumber
2
Itulah yang saya lakukan (dengan ag.el). Bersama-sama dengan magnet multicursor, mengedit refactoring sederhana sangat mudah.
Tom Regner
4

Fungsi ini ada dalam proyektil ( projectile-replace). Ini akan menggunakan ag / ack / git grep / grep jika tersedia (dalam urutan itu) untuk menemukan kejadian, dan tags-query-replaceuntuk menjalankan query-replace.

shosti
sumber
Itu menderita masalah yang sama seperti find-grep-dired. Itu tidak menggunakan output grep yang ada. Ada masalah serupa dengan proyektil-multi-terjadi. Saya lebih suka memulai kueri ganti setelah melihat daftar kecocokan dan tidak mengubah metode pencarian yang mendasarinya. Ini adalah alur kerja alternatif.
dgtized
Apa yang Anda gambarkan terdengar seperti itu dapat dengan mudah dicapai dengan membuat makro yang sangat cepat untuk mengganti teks dan berulang kali memanggil M-g n C-x e(yaitu, gunakan next-erroruntuk menelusuri kejadian-kejadian).
shosti
1

Berikut adalah pendekatan lain, menggunakan Icicles .

Di *grep*buffer output Emacs Anda , tekan Cc `(itu backquote Cc), yang dalam mode Icicle terikat dalam buffer *grep*to command icicle-compilation-search. Ini memungkinkan Anda dengan cepat menavigasi di antara setiap pencarian pencarian ( grephits) yang Anda pilih, dalam urutan apa pun.

Input yang Anda ketik di minibuffer secara dinamis menyaring (mempersempit) himpunan hasil pencarian, dan Anda dapat menggunakan pelengkapan progresif untuk mempersempit dengan mencocokkan beberapa pola secara berurutan (mis. Substring, regexps).

Saat menavigasi di antara pencarian hit Anda dapat menggantinya dengan permintaan - baik seluruh hit (baris) atau hanya bagian yang cocok dengan input minibuffer Anda saat ini.

Lihat Pencarian Icicles - Kompilasi atau Grep . Intro untuk pencarian Icicles ada di sini , dan info tentang mengganti kecocokan selama pencarian Icicles ada di sini .

Drew
sumber
0

Saya menggunakan util ini saya menulis xah_find.el

Saya menulisnya karena:

  • Elisp murni. Tidak ada lagi kekhawatiran tentang grep pada Windows atau transmisi Unicode antara emacs ke Sistem Operasi. masalah emacs grep
  • Jika Anda pengguna unicode berat, alat unix memiliki beberapa semi-bug. masalah linux uniq
  • Saya menemukan / mengganti setiap minggu di file 5k. Saya menggunakan dired-do-query-replace-regexp selama bertahun-tahun. Saya menemukan sifat interaktif benar-benar menyita waktu saya, namun saya perlu memeriksa hasil dari perubahan. Jadi, solusi saya sekarang adalah menjalankan batch tetapi memiliki laporan bagus yang dapat saya pindai sama sekali menemukan / mengganti hasil, dengan opsi untuk menulis ke file.

Utilitas elisp ini mungkin 5 hingga 10 kali lebih lambat daripada memanggil unix grep di emacs, tetapi bekerja dengan baik untuk saya.

Xah Lee
sumber