So wickeln Sie einen bestimmten Text um die Region

11

Ich habe oft eine Situation, in der ich Text in einer Region anwenden muss. Für HTML und einfache Fälle gibt es dafür bereits Bibliotheken. Aber was ist mit dem allgemeinen Fall? Ich möchte gefragt werden, was ich Anfang und Ende der Region einfügen werde.

nperson325681
quelle
Möchten Sie damit beliebige Inhalte einmal oder eine Handvoll Paare mehrmals einfügen? Im letzteren Fall könnten sich Bibliotheken wie Smartparens als nützlich erweisen und sie können mit benutzerdefinierten Paaren erweitert werden. Sie können beispielsweise ein Paar hinzufügen <?php... ?>und dann, wenn Sie eine Region und einen Typ <?php(oder eine Tastenkombination) auswählen , diese in das Paar einschließen. Aber afaik gibt es keine einfache Möglichkeit, diese Bibliotheken zu verwenden, wenn Sie viele One-Shot-Paare haben.
T. Verron
@ T.Verron: Ich weiß, dass diese existieren. Aber für jene Momente, in denen es eine einzigartige Notwendigkeit gibt, Code
durchzugehen und Dinge zu

Antworten:

6

Ich habe gegoogelt und diesen Beitrag von John D. Cook gefunden . Er zeigt, wie man eine einfache interaktive Funktion erstellt, um HTML / XML-Tags einfach in der Region abzurufen. Daraus habe ich die Funktion geändert, um zweimal zu fragen.

(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)))))

Noch wichtiger ist, dass diese Funktion auch als Hilfswerkzeug verwendet werden kann, beispielsweise wenn Sie Schlüssel binden möchten, um bestimmte Textteile zuzuordnen.

(defun tag-php ()
  (interactive)
  (tag-word-or-region "<?php " "?>"))
nperson325681
quelle
Übrigens ist die Art und Weise, wie dies mit einigen Grenzfällen umgeht, nicht optimal. Die Suche nach dem Anfang kann manchmal fehlschlagen und beide Tags am Ende belassen. Es könnte sein, evildass ich das hier störe. Vielleicht hat eine Funktion des Typs interactive "r" robuster funktioniert ?
nperson325681
4

Ich würde einen anderen Ansatz vorschlagen. Wenn es eine Region gibt, pointmuss sie sich per Definition am Anfang (oder Ende) der Region befinden und markbefindet sich am Ende (oder am Anfang). Das heißt, Sie können den gewünschten Text an einer bestimmten Stelle eingeben und dann mit exchange-point-and-mark, dh C-x C-xzum anderen Ende der Region springen. Geben Sie die zweite Hälfte Ihres Wrappers ein und Sie sind fertig.

Sie werden nicht explizit nach dem Einfügetext gefragt, aber ich kann mir nicht vorstellen, dass es eine Möglichkeit gibt, dasselbe mit weniger Aufwand zu erreichen.

Tyler
quelle
Wenn der Start- und Endtext gleich sind, frage ich mich, ob so etwas multiple-cursorsoptimiert werden könnte, um Text am Anfang und Ende des aktiven Bereichs gleichzeitig einzufügen.
Glucas
Das klingt nach der manuellen Methode, zu der Benutzer kleinerer Editoren ohnehin gezwungen sind. Wie auch immer, ich habe die Verwendung von Makros als Untertext aus Ihrer Antwort gelesen, muss ich sagen. Ich mag deinen Stil
nperson325681
1
@progo - Danke :) Es klingt nach einem manuelleren Ansatz, verwendet aber tatsächlich weniger Tastenanschläge als Ihre Alternative. Bei diesem Ansatz benötigen Sie außer dem umschließenden Text nur C-x C-x. Mit Ihrer Antwort müssen Sie Ihre Funktion ( C-c something) aufrufen und returnnach jedem Eintrag drücken. Egal was Sie tun, Sie haben zwei weitere Tastenanschläge. Das heißt, es hilft nicht, wenn Sie etwas von elisp anrufen möchten.
Tyler
3

Nur aus Gründen der Abwechslung:

Eine andere Möglichkeit, dies mit einem beliebigen Start- und Endtext zu tun, besteht darin, ihn replace-regexpfür die Region zu verwenden: Abgleichen .+und Ersetzen durch before \& afteroder den Text, den Sie für beforeund verwenden möchten after.

Sie könnten einen Befehl dazu schreiben, aber ich denke an einen Fall, in dem Sie in einer bestimmten Datei denselben Start- / Endtext an mehreren Stellen anwenden möchten. Sie können ein Makro aufzeichnen oder einfach den Minibuffer-Verlauf verwenden, um ihn in einer anderen Region zu wiederholen.

Wenn der Text, den Sie umbrechen möchten, als regulärer Ausdruck ausgedrückt werden kann, müssen Sie natürlich nicht einmal eine Region auswählen und können einen query-replace-regexpPuffer erstellen , aber vermutlich ist der Text, den Sie umbrechen möchten, nicht so konsistent.

Glucas
quelle