Comment remplacer les parenthèses correspondantes?


10

J'écris (et réécris) beaucoup de formules mathématiques dans LaTeX avec Emacs. Je rencontre fréquemment des situations où je souhaite changer une paire de parenthèses correspondantes, pour améliorer la lisibilité. Mon Emacs est assez aimable pour me montrer le délimiteur correspondant, mais comment le modifier par programme?

Par exemple, modifiez les délimiteurs externes en une seule fois:

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

à

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

2
Notez qu'il serait également intéressant si un tel code pouvait changer par exemple \bigl(...\bigr)en \Bigl(...\Bigr)etc.
Andrew Swann

1
Ici, j'ai donné un exemple d'une grammaire LaTeX simplifiée utilisant PEG: emacs.stackexchange.com/questions/36541/… ce serait une façon d'aborder ce problème.
wvxvw

@wvxvw J'ai regardé votre approche lorsque j'ai écrit cette question, et en effet elle semble intéressante! J'espère aussi qu'il y a quelque chose, peut-être plus simple, là-bas. Emacs connaît déjà le délimiteur correspondant car il est mis en surbrillance. Peut-être que cela pourrait être exploité?
Mankka


Emacs sait mettre en évidence le délimiteur correspondant parce que le mode implémente forward-sexp-function(ce qui, je suppose que le mode TeX le fait), ou qu'il utilisera scan-sexpspour trouver la correspondance possible. Dans le dernier cas, la correspondance ne sera pas toujours correcte. Donc, si tout ce dont vous avez besoin est de faire correspondre les délimiteurs correspondants, vous pouvez vérifier la syntaxe du caractère sous le point. Si c'est le cas $, alors il doit avoir une correspondance, et vous pouvez l'utiliser forwad-sexppour arriver à sa correspondance.
wvxvw

Réponses:


5

J'utilise le code ci-dessous et me lie yf/replace-or-delete-pairàM-D .

Exemple d'utilisation: avec point sur (, je frappe M-D [et la ()paire devient une []paire. Si vous frappez à la M-D RETplace, la paire sera supprimée.

Ce code utilise la table de syntaxe, ce qui signifie que pour certaines paires, vous devrez spécifier vous-même le paren de fermeture. par exemple en mode html, ()peut être remplacé par <>en appuyant sur M-D <. Cependant, dans de nombreux modes, ce <>n'est pas une paire reconnue, et M-D <dira "Je ne sais pas comment fermer <". Vous pouvez alors simplement taper >.

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

7

Pour ceux qui utilisent le mal, vous pouvez utiliser le mal-surround qui vous donne lac s mouvement (changement, surround).

Pour votre exemple, faites simplement c s ( [(mouvement, du type de paren au type de paren)


Juste ce dont j'avais besoin !!! Merci!
Hilman

2

ar-parentized2bracketed-atpt ferait la tâche.

Il vient avec ar-braced2parentized-atpt et essentiellement toutes les combinaisons respectives.

Obtenez-le à partir de thingatpt-transform-delimited.el de

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

Une classe de commandes abstraite transforme toutes les formes délimitées, par exemple:

ar-delimited2bracketed-atpt

Ces commandes sont livrées dans le même repo par

thingatpt-transform-generic-delimited.el


0

Les parenthèses correspondantes sont visualisées avec show-paren-mode. L'approche logique consiste à baser la fonction pour changer les parens à la même logique et fonction sous-jacente. Lorsque les parens correspondants sont mis en surbrillance, vous pouvez appeler la fonction toggle-parensdéfinie ci-dessous:

(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)))
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.