Funkcja wyszukiwania / zamiany do zamiany tekstu

12

I często znajduję się próbując zastąpić np fooz bara barz foow buforze.

Zazwyczaj robię to w następujący sposób:

  • 3 query-Zastępuje: aaa -> @@@, bbb -> aaa,@@@ -> bbb
  • zrezygnuj z automatyzacji i po prostu zrób to ręcznie

Przypuszczam, że możliwe jest uzyskanie działania przy użyciu ,składni w query-replace-regexpcelu sprawdzenia, czy dopasowany ciąg to aaalub bbb. Ale wynikowa składnia byłaby zbyt kłopotliwa, więc tak naprawdę nigdy tego nie próbowałem.

Chodzi o to, biorąc pod uwagę, jak powszechne jest to zadanie, myślę, że musi istnieć lepszy, jednoetapowy sposób, albo wbudowany, albo w istniejącym pakiecie. Jest tu?

T. Verron
źródło
Może być jeden krok, ale twój pierwszy sposób nie jest zły, IMO. A jeśli dobrze wybierzesz ciąg zastępujący, możesz po prostu wykonać zamianę bez zapytania dla drugiego przejścia.
Drew
@Drew Dla zwykłych query-replacewiem, że zazwyczaj szybsze M-% str1 str2jest przesunięcie punktu i wykonanie zmiany ręcznie. To miłe, ponieważ nie muszę tracić czasu na myślenie o tym, co będzie najszybsze, nawet jeśli jest tylko jedno wystąpienie str1. Idealnie byłoby, gdyby inwersja tekstu była tak szybka, żebym mogła z niej korzystać również bez zastanowienia.
T. Verron
Ktoś udzieli prostej odpowiedzi. Bez wątpienia możesz zrobić to, o co prosisz, np. Używając wyrażenia Lisp do zamiany, odwołując się do tekstu, który ma zostać zamieniony. Np. Użyj czegoś podobnego do idiomu wymiany (setq a (prog1 b (setq b a))). I może być nawet prostszy sposób.
Drew
2
Nie uważam za \,(if \1 "b" "a")szczególnie brzydkie (w stosunku do wyrażenia regularnego \(a\)\|b), ale nadal słowa muszą być wpisywane dwukrotnie, jeśli ci to przeszkadza.
politza
2
Dlaczego nie \(aaa\)\|bbb?
politza

Odpowiedzi:

8

Oto małe polecenie, które to zrobi:

(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
źródło
Dziękuję, to jest o wiele bardziej skomplikowane niż coś, co sam bym napisał! Może mógłbyś rozwinąć zaimplementowane funkcje? Widzę, że z argumentem przedrostka przechodzisz do tyłu, że w razie potrzeby wykonuje on zamianę tylko w regionie ... A może to po prostu przepisywanie query-replaceinwersji, aby zachować wszystkie swoje funkcje? Nie pasuje do 100% definicji w moich emacach, ale wciąż mam 24,5 ...
T. Verron
@ T.Verron To tylko standardowe ciało z query-replacerodziny funkcji z najnowszej wersji, więc zachowuje wszystkie funkcje. Na końcu funkcji dodałem zalecany sposób zamiany ciągów wymienionych w podręczniku Emacsa.
link0ff
Prawdopodobnie zaakceptowałem zbyt szybko. Funkcja działa tutaj (emacs 24.3) tylko wtedy, gdy skomentuję backwardi region-noncontiguous-pod połączenia do perform-replace. Czy to ogólny problem, czy oznacza to, że interfejs perform-replacezmieniał się między wersjami?
T. Verron,
Tak, interfejs zmienił się z dodaniem 2 argumentów w najnowszej wersji, więc nie istnieją we wcześniejszych,
link0ff 14.10.16
2
To rozwiązanie wydaje się teraz również w porządku.
Imię
9

Zainstaluj plur

i uruchom polecenie plur-query-replace

oraz dane wejściowe {foo,bar}i ich wymiana{bar,foo}

Naciśnij, yaby zamienić wystąpienia według potrzeb.

Istnieją również nieinteraktywne i podobne do isearch warianty tego polecenia.

InHarmsWay
źródło
Dzięki! Plur jest także czymś, czego czasem szukałem, na pewno się temu przyjrzę. Moje jedyne wahanie wynika z komentarza autora paczki powyżej ...;)
T. Verron,
1
plurwymaga emacs 24.4.
T. Verron,