Есть ли эквивалент для подстановочных команд в стиле sed из vim?

14

Одна из вещей, которые я пропускаю в vim - это возможность ввести команду подстановки, которая будет работать в несколько строк, например:

:/begin/,/end/s/foo/bar/g

Приведенная выше команда заменяет «foo» на «bar», начиная с первой строки, содержащей «begin», и заканчивая следующей строкой после той, что содержит «end».

Есть ли способ сделать что-то подобное в Emacs?

Ларри Коулман
источник

Ответы:

7

evilпредоставляет урезанную версию ex, так что, вероятно, лучше предположить, что это не точное раскрытие. Тем не менее, приведенный вами пример работает «из коробки», при условии, что точка находится перед первой строкой (т. Е. beginСтрокой в ​​вашем примере).

Дэн
источник
В vim поиск также начнется в какой-то момент, так что это будет похоже на то, что я искал. Благодарность!
Ларри Коулман,
8

Вот один из способов сделать это, который использует только встроенную функциональность:

  1. С точкой в ​​строке, которая содержит первое вхождение begin, нажмите C-SPC.

  2. Перейти к следующему появлению end:

    C-s end RET

  3. Заменить fooна bar:

    M-% foo RET bar RET !

Это использует тот факт, что query-replaceбудет работать с активной областью вместо целого буфера, если таковой имеется.


Конечно, вы также можете определить пользовательскую команду:

(defun replace-from-to (beg end str repl)
  (interactive "sBegin: \nsEnd: \nsString: \nsReplacement: ")
  (save-excursion
    (goto-char (point-min))
    (let ((start-pos (search-forward beg))
          (end-pos (search-forward end)))
      (replace-string str repl nil start-pos end-pos))))

Эта команда всегда будет искать с начала буфера, поэтому точка может быть после begin/ foo/, endкогда вы ее вызываете.

Установите для него привязку ключа:

(global-set-key (kbd "C-c r") 'replace-from-to)
itsjeyd
источник
5

В общем, это то, что вы бы использовали narrow-to-region.

Вы перемещаете курсор (например, с помощью поиска) в начало региона и нажимаете C-SPC, затем перемещаетесь в конец региона и вводите M-x narrow-to-region. Теперь вы можете выполнять любые команды поиска и замены, которые вы хотите, и они будут применяться только к суженной части буфера. Как только вы закончите, введите, M-x widenчтобы восстановить содержимое буфера.

Элиас Мортенсон
источник
4
Если begin/ endявляются разделителями на языке программирования, вы можете использовать команду C-M-Spacerun mark-sexpдля выбора региона в одной команде.
dgtized
1
Привязки по умолчанию: C-x n n( narrow-to-region) и C-x n w( widen).
itjeyd