Чи є спосіб використовувати запит-заміну з вихідних режимів grep / ack / ag?


31

Мені відомо find-grep-dired, позначення відповідних файлів і натискання Qдля запуску dired-do-query-replace-regexpпозначених файлів. На жаль, це вимагає перезавантаження grep і більше не використання git-grep, ack або ag та переключення на використання, find-grepяке має інший синтаксис для пошуку.

Я також в курсі multi-occurі occur-edit-mode, але це вимагає перезапуску пошуку з допомогою відбувається. Нарешті, ag-diredсхоже, відповідає ім'я файлу, а не вміст файлу.

Мій поточний підхід полягає у створенні грепового виводу, а потім запустіть макрос, який запускається у буфері grep, та відвідує кожну відповідність та змінює її. Я вважаю за краще використовувати query-replaceбезпосередньо набір знайдених сірників.

Що я хотів би зробити, це або швидко створити відведений буфер з існуючого виводу grep, щоб я міг позначити відповідні файли і викликати query-regexp на них, або перетворити grep вихід у список буферів, multi-occurщоб я міг використовувати occur-edit-modeдля відредагуйте його на місці та запустіть query-replaceна цьому буфері.

Чи існує ця функціональність чи є інший робочий процес, який вирішує цю проблему?

Відповіді:


28

@Malabarba згадав про використання wgrepпакета для редагування результатів grep / ack / ag.

Я хотів би написати детальну інформацію про те, як я використовую agпакет і wgrep-agпакети, щоб досягти редагування 'побіжних результатів за допомогою multiple-cursorsпакета.

Ці пакети доступні через Melpa. Вам також потрібно мати agака-файл the_silver_searcher у вашій системі.

Цей покроковий опис застосовується до випадків, коли ви шукаєте спосіб зміни редагування одного рядка у всіх / вибраних місцях ag.

  • Встановіть agу вашу систему та вищезгадані пакети emacs.

  • agпідтримує пошук файлів із вмістом, який відповідає вказаному регексу. Найпростіший спосіб сказати, agде корінь проекту - помістити туди порожню .gitпапку. Потім виконайте пошук, використовуючи M-x ag-project-regexp.

  • Буфер результатів пошуку за замовчуванням не можна редагувати. Щоб зробити його редагованим, виконайте M-x wgrep-change-to-wgrep-modeабо використовуйте wgrepприв'язку за замовчуванням C-c C-p.

  • Тепер, якщо вам потрібно було змінити 'abcdef' на 'ghijkl' у всіх своїх файлах, ви шукаєте 'abcdef', а в буфері результатів ag з’являться всі рядки, що містять цей рядок. Тоді ви робите цей буфер редагованим і змінюєте ці рядки вручну, і ці зміни відображатимуться у фактичних буферах файлів при виконанні M-x wgrep-finish-editабо використанні прив'язки за замовчуванням C-c C-e. Ви також можете використовувати query-replace-regexpцю заміну для пошуку.

  • Я вважаю за краще використовувати multiple-cursorsдля швидкого рефакторингу, щоб я міг бачити відгуки в реальному часі про те, де одночасно відбуваються мої зміни. Виділіть рядок, який ви хочете замінити, у цьому буфері результатів ag і зателефонуйте, M-x mc/mark-all-like-thisа потім відредагуйте зі страхом, коли ви бачите, що речі редагуються в декількох точках одночасно.

  • Після того, як ви будете задоволені змінами, як я вже згадував вище, зробіть C-c C-e"відображення" змін у фактичних буферах. Буфери ще не збережені.

  • Щоб зберегти всі буфери, я зазвичай роблю це за один раз, використовуючи C-x s !прив'язку за замовчуванням emacs .

Ось приклад використання випадку із скріншотами:

Це показує процес заміни всіх примірників , bind-to-modi-mapщоб bind-to-my-mapна мою ~/.emacs.d/.

Коли я шукаю bind-to-modi-mapу своїй папці налаштування emacs, я отримую наведений нижче результат ':ag результати, немодифіковані

Цей буфер доступний лише для читання.

Після того M-x wgrep-change-to-wgrep-mode, як я виділяю, -modi-mapвибираю всі екземпляри цього вибору за допомогою M-x mc/mark-all-like-thisта після редагування цих виділень -my-map, це виглядає як нижче: ag результати, модифіковані за допомогою декількох курсорів

Синя підсвітка показує, які лінії будуть змінені, коли я натискаю C-c C-e.

Під час натискання C-c C-eви можете побачити зміни, відображені у фактичному файлі на цьому знімку екрана: ag результати, після закінчення редагування

Тоді я б зберігав усі модифіковані файли за допомогою C-x s !.


Це дійсно найкращий спосіб замінити рядок. Міститься в проекті, маючи на увазі ag-виключення, просту партію, яка все ще може перевірити, що ви замінюєте правильну річ.
PascalVKooten

13

Що я хотів би зробити, це або швидко створити відведений буфер з існуючого виводу grep [...], або перетворити grep вихід у список буферів для багатопоточних [...].

Вам не потрібно перетворювати буфер результатів grep в що-небудь, вже існує режим, призначений спеціально для редагування виводу grep (і, звичайно, відображення змін у файлах).

  1. Встановіть пакет wgrep від Melpa.
  2. (require 'wgrep) у вашому файлі init.
  3. Після глибокого пошуку, натисніть C-c C-pі відредагуйте!
  4. Збережіть правки за допомогою C-c C-e

Він навіть працює з ack і ag.


2
Це я роблю (з аг.ел). Спільно з мультикурсором редагувати прості рефактори дуже просто.
Том Регнер

4

Ця функціональність існує в межах снаряда ( projectile-replace). Він використовуватиме ag / ack / git grep / grep, якщо вони доступні (у цьому порядку) для пошуку подій та tags-query-replaceвиконання запиту-заміни.


Це страждає від тих же питань, що і пошук. Він не використовує наявний вихід греп. Існують подібні проблеми зі снарядом-багаторазовими. Я вважаю за краще запустити заміну замість запиту після перегляду списку збігів, а не змінити метод основного пошуку. Однак це альтернативний робочий процес.
занотувано

Те, що ви описуєте, звучить так, як це легко зробити, зробивши дуже швидкий макрос для заміни тексту та багаторазового дзвінка M-g n C-x e(тобто використовуйте next-errorдля прокрутки подій).
shosti

1

Ось ще один підхід із використанням Icicles .

У своєму *grep*вихідному буфері Emacs натисніть Cc `(це зворотне запитання Cc), яке в режимі Icicle пов'язане в буфері *grep*для команди icicle-compilation-search. Це дозволяє швидко переходити між будь-яким із обраних вами пошукових запитів (будь-яких grepзвернень) у будь-якому порядку.

Введіть текст, який ви вводите в мінібуфер, динамічно фільтрує (звужує) набір пошукових запитів, і ви можете використовувати прогресивне завершення для звуження шляхом послідовного узгодження декількох шаблонів (наприклад, підрядків, регулярних виразів).

Під час навігації серед пошукових запитів ви можете замінити будь-який з них на вимогу - або весь хіт (рядок), або просто деталь, що відповідає вашому поточному входу мінібуфера.

Див бурульок Пошук - Compile або Grep . Вступ до пошуку Icicles знаходиться тут , а інформація про заміну матчів під час пошуку в Icicles знаходиться тут .


0

Я використовую цю утиліту, яку я написав xah_find.el

Я написав це тому, що:

  • Чистий елісп. Більше не турбуйтеся про grep для передачі Windows або Unicode між emacs до операційної системи. проблема grep у emacs
  • Якщо ви є великим користувачем Unicode, в інструментах unix є кілька напівсправ. Проблема linux uniq
  • Щотижня я знаходжу / замінюю файли на 5k. Я використовував dired-do-query-substitu-regexp роками. Я вважаю, що інтерактивна природа дійсно затримала свій час, але мені потрібно перевірити результати змін. Отже, моє рішення тепер запускається пакетно, але є хороший звіт, який я можу просканувати всі результати пошуку / заміни результатів, з можливістю написати у файл.

Цей утиліт Elisp, можливо, у 5–10 разів повільніше, ніж викликати unix grep в emacs, але для мене справно.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.