¿Cómo reemplazar los paréntesis coincidentes?

10

Escribo (y reescribo) muchas fórmulas matemáticas en LaTeX con Emacs. Con frecuencia me encuentro con situaciones en las que quiero cambiar un par de paréntesis coincidentes, para mejorar la legibilidad. Mi Emacs tiene la amabilidad de mostrarme el delimitador coincidente, pero ¿cómo lo cambio programáticamente?

Por ejemplo, cambie los delimitadores externos de una vez:

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

a

[ (\sqrt{a} + b)^{-1} + c^{-1} ]
Mankka
fuente
2
Tenga en cuenta que también sería interesante si dicho código pudiera cambiar, por ejemplo, \bigl(...\bigr)a \Bigl(...\Bigr)etc.
Andrew Swann
1
Aquí di un ejemplo de una gramática simplificada de LaTeX usando PEG: emacs.stackexchange.com/questions/36541/... esta sería una forma de abordar este problema.
wvxvw
@wvxvw Observé tu enfoque cuando escribí esta pregunta, ¡y de hecho parece interesante! También espero que haya algo, quizás más simple, por ahí. Emacs ya conoce el delimitador correspondiente ya que está resaltado. Tal vez esto podría ser aprovechado?
Mankka
2
Hilo de desbordamiento de pila relacionado: ¿Cómo puede modificar dos delimitadores coincidentes a la vez con Emacs?
Dan
Emacs sabe resaltar el delimitador coincidente porque el modo se implementa forward-sexp-function(lo cual, supongo que lo hace el modo TeX), o lo usará scan-sexpspara encontrar la posible coincidencia. En el último caso, la coincidencia no siempre será correcta. Entonces, si todo lo que necesita es hacer coincidir los delimitadores coincidentes, puede verificar la sintaxis del carácter debajo del punto. Si es así $, tiene que tener una coincidencia, y podría usar forwad-sexppara llegar a su coincidencia.
wvxvw

Respuestas:

5

Yo uso el siguiente código y me uno yf/replace-or-delete-paira M-D.

Ejemplo de uso: con el punto activado (, golpeo M-D [y el ()par se convierte en un []par. Si golpeas M-D RET, el par será eliminado.

Este código usa la tabla de sintaxis, lo que significa que para algunos pares tendrá que especificar el par de cierre usted mismo. por ejemplo, en modo html, ()se puede reemplazar <>presionando M-D <. Sin embargo, en muchos modos <>no es un par reconocido, y M-D <dirá "No sé cómo cerrar <". Entonces puedes simplemente escribir >.

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

Para aquellos que usan el mal, puedes usar el mal envolvente que te da el c smovimiento (cambio, sonido envolvente).

Para su ejemplo, simplemente haga c s ( [(movimiento, desde el tipo de paren, hasta el tipo de paren)

Anntoin Wilkinson
fuente
¡¡¡Justo lo que necesitaba!!! ¡Gracias!
Hilman
2

ar-parentized2bracketed-atpt haría la tarea

Viene junto con ar-braced2parentized-atpty básicamente todas las combinaciones respectivas.

Consíguelo en thingatpt-transform-delimited.el de

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

Una clase de comandos abstraída transforma todas las formas delimitadas, por ejemplo:

ar-delimited2bracketed-atpt

Estos comandos se entregan en el mismo repositorio por

thingatpt-transform-generic-delimited.el

Andreas Röhler
fuente
0

Los paréntesis coincidentes se visualizan con show-paren-mode. El enfoque lógico es basar la función para cambiar parens a la misma lógica y función subyacentes. Cuando se resaltan parens coincidentes, puede llamar a la función toggle-parensdefinida a continuación:

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