Come sostituire le parentesi corrispondenti?


10

Scrivo (e riscrivo) molte formule matematiche in LaTeX con Emacs. Mi capita spesso di imbattermi in situazioni in cui desidero cambiare una coppia di parentesi corrispondenti, per migliorare la leggibilità. Il mio Emacs è abbastanza gentile da mostrarmi il delimitatore corrispondente, ma come posso modificarlo a livello di codice?

Ad esempio, modificare i delimitatori esterni in una volta sola:

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

per

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

2
Si noti inoltre sarebbe interessante se tale codice potrebbe cambiare ad esempio \bigl(...\bigr)al \Bigl(...\Bigr)ecc
Andrew Swann

1
Qui ho dato un esempio di una grammatica LaTeX semplificata usando PEG: emacs.stackexchange.com/questions/36541/… questo sarebbe un modo per affrontare questo problema.
wvxvw,

@wvxvw Ho esaminato il tuo approccio quando ho scritto questa domanda, e in effetti sembra interessante! Una speranza anche che ci sia qualcosa, forse più semplice, là fuori. Emacs è già a conoscenza del delimitatore corrispondente poiché è evidenziato. Forse questo potrebbe essere sfruttato?
Mankka,


Emacs sa evidenziare il delimitatore corrispondente perché la modalità implementa forward-sexp-function(cosa che, immagino, la modalità TeX fa), o userà scan-sexpsper trovare la possibile corrispondenza. Nel caso successivo, la corrispondenza non sarà sempre corretta. Quindi, se tutto ciò che serve è abbinare i delimitatori corrispondenti, puoi controllare la sintassi del carattere sotto il punto. Se lo è $, allora deve avere una corrispondenza e potresti usarlo forwad-sexpper arrivare alla sua corrispondenza.
wvxvw,

Risposte:


5

Uso il codice qui sotto e mi associo yf/replace-or-delete-paira M-D.

Esempio di utilizzo: con il punto acceso (, ho colpito M-D [e la ()coppia diventa una []coppia. Se M-D RETinvece colpisci , la coppia verrà rimossa.

Questo codice utilizza la tabella di sintassi, il che significa che per alcune coppie dovrai specificare tu stesso la parentesi di chiusura. ad es. in modalità HTML, ()può essere sostituito <>colpendo M-D <. Tuttavia, in molte modalità <>non è una coppia riconosciuta e M-D <dirà "Non so come chiudere <". Puoi quindi semplicemente digitare >.

(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

Per quelli che usano il male puoi usare il male-surround che ti dà il c smovimento (cambia, circonda).

Per il tuo esempio, fai semplicemente c s ( [(movimento, dal tipo di paren al tipo di paren)


Proprio quello di cui avevo bisogno !!! Grazie!
Hilman,

2

ar-parentized2bracketed-atpt farebbe il compito.

Viene fornito con ar-braced2parentized-atpte sostanzialmente tutte le rispettive combinazioni.

Scarica da thingatpt-transform-delimited.el di

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

Una classe di comandi astratta trasforma tutte le forme delimitate, ad esempio:

ar-delimited2bracketed-atpt

Questi comandi vengono consegnati nello stesso repository da

thingatpt-transform-generic-delimited.el


0

Le parentesi corrispondenti vengono visualizzate con show-paren-mode. L'approccio logico consiste nel basare la funzione per modificare le parentesi sulla stessa logica e funzione sottostanti. Quando le parentesi corrispondenti sono evidenziate, puoi chiamare la funzione toggle-parensdefinita di seguito:

(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)))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.