Jak zastąpić pasujące nawiasy?

10

Piszę (i przepisuję) wiele formuł matematycznych w LaTeX z Emacsem. Często spotykam się z sytuacjami, w których chcę zmienić parę pasujących nawiasów, aby poprawić czytelność. Mój Emacs jest na tyle miły, że pokazuje mi pasujący separator, ale jak mogę to zmienić programowo?

Na przykład zmień zewnętrzne ograniczniki za jednym razem:

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

do

[ (\sqrt{a} + b)^{-1} + c^{-1} ]
Mankka
źródło
2
Warto również zauważyć, że taki kod mógłby się zmienić np. \bigl(...\bigr)Na \Bigl(...\Bigr)itp.
Andrew Swann,
1
Tutaj podałem przykład uproszczonej gramatyki LaTeX przy użyciu PEG: emacs.stackexchange.com/questions/36541/... to byłby jeden sposób na rozwiązanie tego problemu.
wvxvw,
@wvxvw Spojrzałem na twoje podejście, kiedy napisałem to pytanie, i rzeczywiście wygląda interesująco! Mam też nadzieję, że jest tam coś, być może prostszego. Emacs jest już świadomy pasującego separatora, ponieważ jest podświetlony. Może można to wykorzystać?
Mankka,
Emacs wie, jak wyróżnić pasujący separator, ponieważ albo tryb implementuje forward-sexp-function(co, jak sądzę, robi w trybie TeX), albo użyje go scan-sexpsdo znalezienia możliwego dopasowania. W późniejszym przypadku dopasowanie nie zawsze będzie poprawne. Tak więc, jeśli wszystko, czego potrzebujesz, to dopasowanie pasujących ograniczników, możesz sprawdzić składnię znaku w punkcie. Jeśli tak $, to musi mieć dopasowanie, a możesz użyć, forwad-sexpaby dostać się do dopasowania.
wvxvw,

Odpowiedzi:

2

Użyj smartparenspakietu. Zawiera funkcję o nazwie sp-rewrap-sexp, która jest dokładnie tym, czego potrzebujesz. Strona główna projektu ( https://github.com/Fuco1/smartparens ) ma kilka gifów wyraźnie pokazujących funkcjonalność.

dxu
źródło
7

Dla tych, którzy używają zła, możesz użyć Evil-Surround, który daje ci c sruch (zmiana, surround).

Na przykład wykonaj po prostu c s ( [(ruch, od rodzaju parena do rodzaju parena)

Anntoin Wilkinson
źródło
Dokładnie to, czego potrzebowałem!!! Dzięki!
Hilman
6

Korzystam z poniższego kodu i wiążę się yf/replace-or-delete-pairz M-D.

Przykładowe użycie: z włączonym punktem (uderzam, M-D [a ()para staje się []parą. Jeśli M-D RETzamiast tego uderzysz , para zostanie usunięta.

Ten kod korzysta z tabeli składni, co oznacza, że ​​dla niektórych par musisz sam określić paren zamykający. np. w trybie HTML, ()można go zastąpić <>przez naciśnięcie M-D <. Jednak w wielu trybach <>nie jest rozpoznawana para i M-D <powie „Nie wiem, jak zamknąć <”. Następnie możesz po prostu wpisać >.

(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
źródło
2

ar-parentized2bracketed-atpt wykona zadanie.

Jest dostarczany ar-braced2parentized-atpti zasadniczo wszystkie odpowiednie kombinacje.

Pobierz go z thingatpt-transform-delimited.el z

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

Abstrakcyjna klasa poleceń przekształca wszystkie rozdzielane formy, na przykład:

ar-delimited2bracketed-atpt

Te komendy są dostarczane w tym samym repozytorium przez

thingatpt-transform-generic-delimited.el

Andreas Röhler
źródło
0

Pasujące nawiasy są wizualizowane show-paren-mode. Logicznym podejściem jest oparcie funkcji na zmianie parens na tę samą podstawową logikę i funkcję. Gdy podświetlone pasujące pareny są podświetlone, możesz wywołać funkcję toggle-parenszdefiniowaną poniżej:

(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
źródło