Jak owinąć dany tekst wokół regionu

11

Często mam sytuację, w której muszę zastosować tekst w całym regionie. W przypadku HTML i prostych przypadków istnieją już biblioteki do tego. Ale co z ogólnym przypadkiem? Chciałbym zapytać, co wstawię na początku i na końcu regionu.

nperson325681
źródło
Czy chcesz go używać do jednorazowego wstawiania dowolnych treści lub wielu par? W tym drugim przypadku biblioteki takie jak smartparens mogą okazać się przydatne i można je rozszerzyć o niestandardowe pary. Na przykład możesz dodać parę <?php... ?>, a następnie, po wybraniu regionu i typu <?php(lub skrótu klawiszowego), zawiń go w parę. Ale afaik, nie ma łatwego sposobu korzystania z tych bibliotek, jeśli masz wiele pojedynczych par.
T. Verron
@ T.Verron: Wiem, że one istnieją. Ale w tych momentach, gdy istnieje wyjątkowa potrzeba przejrzenia kodu i oznaczenia rzeczy, jedna ogólna funkcja wielokrotnego użytku najlepiej pasuje
nperson325681,

Odpowiedzi:

6

Przeszukałem go i znalazłem ten post Johna D. Cooka . Demonstruje, jak zbudować prostą funkcję interaktywną, aby łatwo przesuwać tagi HTML / XML wokół regionu. Od tego czasu zmodyfikowałem funkcję, by pytać dwukrotnie.

(defun tag-word-or-region (text-begin text-end)
  "Surround current word or region with given text."
  (interactive "sStart tag: \nsEnd tag: ")
  (let (pos1 pos2 bds)
    (if (and transient-mark-mode mark-active)
        (progn
          (goto-char (region-end))
          (insert text-end)
          (goto-char (region-beginning))
          (insert text-begin))
      (progn
        (setq bds (bounds-of-thing-at-point 'symbol))
        (goto-char (cdr bds))
        (insert text-end)
        (goto-char (car bds))
        (insert text-begin)))))

Co ważniejsze, ta funkcja może być również używana jako narzędzie pomocnicze, na przykład, gdy chcesz powiązać klawisze, aby zmapować określone fragmenty tekstu.

(defun tag-php ()
  (interactive)
  (tag-word-or-region "<?php " "?>"))
nperson325681
źródło
Przy okazji sposób, w jaki obsługuje niektóre przypadki graniczne, nie jest optymalny; wyszukiwanie początku może czasami zawieść i pozostawić oba znaczniki na końcu. Możliwe evil, że użyję tego, że to przeszkadza. Być może funkcja typu interactive "r" działała solidniej?
nperson325681
4

Sugerowałbym inne podejście. Gdy istnieje region, z definicji pointmusi znajdować się na początku (lub końcu) regionu i markbędzie na końcu (lub początku). Co oznacza, że ​​możesz wpisać tekst, który chcesz w punkcie, a następnie użyć exchange-point-and-mark, tj. C-x C-xPrzeskoczyć na drugi koniec regionu. Wprowadź drugą połowę opakowania i gotowe.

Nie pojawia się wyraźne pytanie o tekst do wstawienia, ale nie wyobrażam sobie, aby byłby sposób na osiągnięcie tego samego przy mniejszym wysiłku.

Tyler
źródło
Jeśli tekst początkowy i końcowy jest taki sam, zastanawiam się, czy coś takiego multiple-cursorsmożna by ulepszyć, aby wstawiać tekst jednocześnie na początku i na końcu aktywnego regionu.
glucas
To brzmi jak ręczny sposób, w jaki użytkownicy mniejszych redaktorów są zmuszeni to zrobić. W każdym razie czytam użycie makr jako podtekstu z twojej odpowiedzi, muszę powiedzieć. Podoba mi się twój styl
nperson325681,
1
@progo - Dzięki :) Brzmi to bardziej manualnie, ale w rzeczywistości używa mniejszej liczby naciśnięć klawiszy niż alternatywa. Przy takim podejściu, innym niż zawijanie tekstu, potrzebujesz tylko C-x C-x. Po otrzymaniu odpowiedzi musisz wywołać swoją funkcję ( C-c something), a także nacisnąć returnpo każdym wpisie. Bez względu na to, co robisz, masz jeszcze dwa naciśnięcia klawiszy. To powiedziawszy, to nie pomaga, jeśli chcesz zadzwonić z elisp.
Tyler
3

Ze względu na różnorodność:

Innym sposobem na zrobienie tego z dowolnym tekstem początkowym i końcowym byłoby użycie replace-regexpw regionie: dopasuj .+i zamień na before \& afterlub dowolny tekst, którego chcesz użyć dla beforei after.

Możesz napisać polecenie do tego, ale myślę o przypadku, w którym w danym pliku chcesz zastosować ten sam tekst początkowy / końcowy w wielu miejscach. Możesz nagrać makro lub po prostu użyć historii minibufora, aby powtórzyć w innym regionie.

Oczywiście, jeśli tekst, który chcesz zawinąć, może być wyrażony jako wyrażenie regularne, nie musisz nawet wybierać regionu i możesz zrobić to query-replace-regexpw buforze, ale prawdopodobnie tekst, który chcesz zawinąć, nie jest tak spójny.

glucas
źródło