Wie ersetze ich passende Klammern?

10

Ich schreibe (und schreibe) viele mathematische Formeln in LaTeX mit Emacs. Ich stoße häufig auf Situationen, in denen ich zwei übereinstimmende Klammern ändern möchte, um die Lesbarkeit zu verbessern. Mein Emacs ist so freundlich, mir das passende Trennzeichen zu zeigen, aber wie ändere ich es programmgesteuert?

Ändern Sie beispielsweise die äußeren Begrenzer auf einmal:

( (\sqrt{a} + b)^{-1} + c^{-1} )

zu

[ (\sqrt{a} + b)^{-1} + c^{-1} ]
Mankka
quelle
2
Beachten Sie, dass es auch interessant wäre, wenn sich ein solcher Code beispielsweise \bigl(...\bigr)in \Bigl(...\Bigr)usw. ändern könnte .
Andrew Swann
1
Hier habe ich ein Beispiel für eine vereinfachte LaTeX-Grammatik mit PEG gegeben: emacs.stackexchange.com/questions/36541/… Dies wäre eine Möglichkeit, dieses Problem anzugehen .
wvxvw
@wvxvw Ich habe mir Ihren Ansatz angesehen, als ich diese Frage geschrieben habe, und tatsächlich sieht er interessant aus! Ich hoffe auch, dass es da draußen etwas gibt, das vielleicht einfacher ist. Emacs kennt das passende Trennzeichen bereits, da es hervorgehoben ist. Vielleicht könnte dies genutzt werden?
Mankka
Emacs kann das übereinstimmende Trennzeichen hervorheben, da entweder der Modus implementiert wird forward-sexp-function(was vermutlich der TeX-Modus tut) oder er verwendet wird scan-sexps, um die mögliche Übereinstimmung zu finden. Im späteren Fall ist die Übereinstimmung nicht immer korrekt. Wenn Sie also nur übereinstimmende Trennzeichen suchen müssen, können Sie die Syntax des Zeichens unter Punkt überprüfen. Wenn $ja, muss es eine Übereinstimmung haben, und Sie können verwenden forwad-sexp, um zu seiner Übereinstimmung zu gelangen.
wvxvw

Antworten:

5

Ich benutze den Code unten und binde yf/replace-or-delete-pairan M-D.

Anwendungsbeispiel: Mit Punkt auf (drücke ich M-D [und das ()Paar wird zu einem []Paar. Wenn Sie M-D RETstattdessen drücken, wird das Paar entfernt.

Dieser Code verwendet die Syntaxtabelle. Dies bedeutet, dass Sie für einige Paare den schließenden Paren selbst angeben müssen. zB im HTML-Modus, ()kann <>durch Schlagen ersetzt werden M-D <. In vielen Modi <>wird jedoch kein Paar erkannt und es M-D <wird "Weiß nicht, wie man <schließt" angezeigt. Sie können dann einfach tippen >.

(defun yf/replace-or-delete-pair (open)
  "Replace pair at point by OPEN and its corresponding closing character.
The closing character is lookup in the syntax table or asked to
the user if not found."
  (interactive
   (list
    (read-char
     (format "Replacing pair %c%c by (or hit RET to delete pair):"
             (char-after)
             (save-excursion
               (forward-sexp 1)
               (char-before))))))
  (if (memq open '(?\n ?\r))
      (delete-pair)
    (let ((close (cdr (aref (syntax-table) open))))
      (when (not close)
        (setq close
              (read-char
               (format "Don't know how to close character %s (#%d) ; please provide a closing character: "
                       (single-key-description open 'no-angles)
                       open))))
      (yf/replace-pair open close))))

(defun yf/replace-pair (open close)
  "Replace pair at point by respective chars OPEN and CLOSE.
If CLOSE is nil, lookup the syntax table. If that fails, signal
an error."
  (let ((close (or close
                   (cdr-safe (aref (syntax-table) open))
                   (error "No matching closing char for character %s (#%d)"
                          (single-key-description open t)
                          open)))
        (parens-require-spaces))
    (insert-pair 1 open close))
  (delete-pair)
  (backward-char 1))
Junger Frosch
quelle
7

Für diejenigen, die das Böse benutzen, können Sie das Böse-Surround verwenden, das Ihnen die c sBewegung gibt (Veränderung, Surround).

Für Ihr Beispiel tun Sie es einfach c s ( [(Bewegung, vom Parentyp zum Parentyp)

Anntoin Wilkinson
quelle
Genau das, was ich brauchte!!! Vielen Dank!
Hilman
2

ar-parentized2bracketed-atpt würde die Aufgabe erledigen.

Es kommt zusammen mit ar-braced2parentized-atptund im Grunde allen jeweiligen Kombinationen.

Holen Sie es sich von thingatpt-transform-delimited.el von

URL: https://github.com/andreas-roehler/thing-at-point-utils

Eine abstrahierte Befehlsklasse transformiert alle abgegrenzten Formen, zum Beispiel:

ar-delimited2bracketed-atpt

Diese Befehle werden im selben Repo von geliefert

thingatpt-transform-generic-delimited.el

Andreas Röhler
quelle
0

Übereinstimmende Klammern werden mit angezeigt show-paren-mode. Der logische Ansatz besteht darin, die Funktion zum Ändern der Parens auf dieselbe zugrunde liegende Logik und Funktion zu stützen. Wenn übereinstimmende Parens hervorgehoben sind, können Sie die toggle-parensunten definierte Funktion aufrufen :

(defun toggle-parens ()
  "Toggle parens () <> [] at cursor.

Turn on `show-paren-mode' to see matching pairs of parentheses
and other characters in buffers. This function then uses the same
function `show-paren-data-function' to find and replace them with
the other pair of brackets.

This function can be easily modified and expanded to replace
other brackets. Currently, mismatch information is ignored and
mismatched parens are changed based on the left one."
  (interactive)
  (let* ((parens (funcall show-paren-data-function))
         (start (if (< (nth 0 parens) (nth 2 parens))
                    (nth 0 parens) (nth 2 parens)))
         (end (if (< (nth 0 parens) (nth 2 parens))
                  (nth 2 parens) (nth 0 parens)))
         (startchar (buffer-substring-no-properties start (1+ start)))
         (mismatch (nth 4 parens)))
    (when parens
      (pcase startchar
        ("(" (toggle-parens--replace "[]" start end))
        ("[" (toggle-parens--replace "()" start end))))))

(defun toggle-parens--replace (pair start end)
  "Replace parens with a new PAIR at START and END in current buffer.

A helper function for `toggle-parens'."
  (goto-char start)
  (delete-char 1)
  (insert (substring pair 0 1))
  (goto-char end)
  (delete-char 1)
  (insert (substring pair 1 2)))
Heikki
quelle