Функция поиска / замены для замены текста

12

Я часто ловлю себя пытается заменить , например , fooс barи barс fooв буфере.

Я обычно делаю это либо:

  • 3 запроса-Заменяет: aaa -> @@@, bbb -> aaa,@@@ -> bbb
  • отказаться от автоматизации и просто сделать замену вручную

Я предполагаю, что можно заставить что-то работать, используя ,синтаксис, query-replace-regexpчтобы проверить, соответствует ли строка aaaили bbb. Но полученный синтаксис был бы слишком громоздким, поэтому я никогда не пробовал его.

Дело в том, что с учетом того, насколько распространена задача, я думаю, что должен быть лучший, одношаговый, способ сделать это, встроенный или в существующем пакете. Есть?

Т. Веррон
источник
Там может быть один шаг, но ваш первый путь неплох, ИМО. И если вы выберете правильную строку замены, вы можете просто выполнить замену без запроса для второго прохода.
Дрю
@Drew Для регулярных query-replace, я знаю, что это обычно быстрее, M-% str1 str2чем перемещать точку и делать изменения вручную. Это приятно, потому что мне не нужно тратить время на размышления о том, что будет быстрее, даже если есть только один случай str1. В идеале я хотел бы, чтобы инверсия текста была такой же быстрой, чтобы я мог использовать ее, не задумываясь об этом.
Т. Веррон
Кто-то даст простой ответ. Без сомнения, вы можете делать то, что просите, например, используя выражение Lisp для замены, ссылаясь на текст, который нужно заменить. Например, используйте что-то похожее на идиому подкачки (setq a (prog1 b (setq b a))). И может быть даже проще.
Дрю
2
Я не нахожу \,(if \1 "b" "a")особенно уродливым (против регулярного выражения \(a\)\|b), но все же слова нужно вводить дважды, если это вас беспокоит.
политза
2
Почему нет \(aaa\)\|bbb?
политза

Ответы:

8

Вот небольшая команда, которая сделает это:

(defun query-swap-strings (from-string to-string &optional delimited start end)
  "Swap occurrences of FROM-STRING and TO-STRING."
  (interactive
   (let ((common
          (query-replace-read-args
           (concat "Query swap"
                   (if current-prefix-arg
                       (if (eq current-prefix-arg '-) " backward" " word")
                     "")
                   (if (use-region-p) " in region" ""))
           nil)))
     (list (nth 0 common) (nth 1 common) (nth 2 common)
           (if (use-region-p) (region-beginning))
           (if (use-region-p) (region-end)))))
  (perform-replace
   (concat "\\(" (regexp-quote from-string) "\\)\\|" (regexp-quote to-string))
   `(replace-eval-replacement replace-quote (if (match-string 1) ,to-string ,from-string))
   t t delimited nil nil start end))
link0ff
источник
Спасибо, это намного сложнее, чем то, что я написал бы сам! Может быть, вы могли бы рассказать о реализованных функциях? Я вижу, что с префиксным аргументом вы возвращаетесь назад, что он выполняет замену только в регионе, если это необходимо ... Или это просто переписывание query-replaceдля инверсии, чтобы он сохранил все свои особенности? Это не соответствует 100% определению в моем emacs, но я все еще с 24.5 ...
Т. Веррон
@ T.Verron Это просто стандартное тело из query-replaceсемейства функций из последней версии, поэтому он сохраняет все функции. В конце функции я добавил рекомендованный способ замены строк, упомянутый в руководстве по Emacs.
link0ff
Я, вероятно, принял слишком быстро. Функция работает только здесь (emacs 24.3), если я закомментирую backwardи region-noncontiguous-pпри вызове perform-replace. Это общая проблема, или это означает, что интерфейс perform-replaceизменился между версиями?
Т. Веррон
Да, интерфейс изменился с этими 2 аргументами, добавленными в последней версии, поэтому они не существуют в более ранних,
link0ff
2
Это решение также, кажется, хорошо сейчас.
Имя
9

Установить плур

и запустить команду plur-query-replace

и ввод {foo,bar}и его замена{bar,foo}

Нажмите, yчтобы заменить вхождения по желанию.

Существуют также неинтерактивные и похожие на поиск варианты этой команды.

InHarmsWay
источник
Благодарность! Цель Plur - это то, что я иногда искал, я обязательно посмотрю на нее. Мое единственное сомнение связано с комментарием автора пакета выше ...;)
Т. Веррон
1
plurтребует emacs 24.4.
Т. Веррон