branch: externals/tex-parens
commit 145e9eafc4f196714d713f00c3626a17135a9fb8
Author: Paul Nelson <[email protected]>
Commit: Paul Nelson <[email protected]>

    lots of cleanup, support for $\text{..$..$..}$, etc
---
 tex-parens.el | 663 +++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 376 insertions(+), 287 deletions(-)

diff --git a/tex-parens.el b/tex-parens.el
index 0e752f1f2d..74f0eb17c3 100644
--- a/tex-parens.el
+++ b/tex-parens.el
@@ -20,9 +20,16 @@
 
 ;;; Commentary:
 
-;; This package provides sexp and list-based navigation, much like
-;; those in lisp.el, but for tex modes, tailored to my use cases
-;; (cf. https://github.com/Fuco1/smartparens/issues/1193).
+;; This package provides commands for working with lists, sexps and
+;; defuns, much like those in lisp.el, but for tex buffers.  Here, the
+;; role of parentheses is played by begin/end blocks, math delimiters
+;; and mathematical parenthesis-like constructions (e.g.,
+;; langle/rangle), together with their tex modifiers (e.g.,
+;; left/right, bigl/bigr).  See README.org for more details.
+
+;; There are many packages that aim to provide such features for
+;; general modes, but I was unable to find one that provides the
+;; desired functionality for the special case of tex buffers.
 
 ;; Sample configuration:
 ;;
@@ -31,376 +38,461 @@
 ;;                  :depth nil)
 ;;   :bind
 ;;   (:map LaTeX-mode-map
-;;         ("C-M-f" . tex-parens-forward-sexp)
-;;         ("C-M-b" . tex-parens-backward-sexp)
-;;         ("C-M-n" . tex-parens-forward-list)
-;;         ("C-M-p" . tex-parens-backward-list)
-;;         ("C-M-u" . tex-parens-backward-up-list)
-;;         ("M-u" . tex-parens-up-list)
-;;         ("C-M-g" . tex-parens-down-list)
-;;         ("M-_" . tex-parens-delete-pair)
-;;         ("C-M-SPC" . tex-parens-mark-sexp)
-;;         ("C-M-k" . tex-parens-kill-sexp)
+;;         ("C-M-f" . tp-forward-sexp)
+;;         ("C-M-b" . tp-backward-sexp)
+;;         ("C-M-n" . tp-forward-list)
+;;         ("C-M-p" . tp-backward-list)
+;;         ("C-M-u" . tp-backward-up-list)
+;;         ("M-u" . tp-up-list)
+;;         ("C-M-g" . tp-down-list)
+;;         ("M-_" . tp-delete-pair)
+;;         ("C-M-SPC" . tp-mark-sexp)
+;;         ("C-M-k" . tp-kill-sexp)
 ;;         ("C-M-t" . transpose-sexps)
-;;         ("C-M-<backspace>" . tex-parens-backward-kill-sexp)
-;;         ("M-+" . tex-parens-raise-sexp))
+;;         ("C-M-<backspace>" . tp-backward-kill-sexp)
+;;         ("M-+" . tp-raise-sexp))
 ;;   :hook
-;;   (LaTeX-mode . tex-parens-setup))
+;;   (LaTeX-mode . tp-setup))
 
 ;;; Code:
 
 (require 'cl-lib)
 
-(defun tex-parens--beginning-of-defun ()
+(defgroup tex-parens nil
+  "Like lisp.el but for tex."
+  :group 'tex
+  :prefix "tp-")
+
+(defun tp--beginning-of-defun ()
   "Move to the beginning of the current defun.
 Here `defun' means top-level environment."
   (interactive)
   (re-search-backward "^\\\\begin{[^}]+}" nil t))
 
-(defun tex-parens--end-of-defun ()
+(defun tp--end-of-defun ()
   "Move to the end of the current defun.
 Here `defun' means top-level environment."
   (interactive)
   (re-search-forward "^\\\\end{[^}]+}\n" nil t))
 
-(defun tex-parens--generate-pairs ()
-  "Generate list of left/right pairs of delimiters."
-  (let ((unambiguous-parens
-         '(("(" . ")")
-           ("[" . "]")
-           ("\\{" . "\\}")
-           ("\\langle" . "\\rangle")
-           ("\\lvert" . "\\rvert")
-           ("\\lVert" . "\\rVert")
-           ("\\lfloor" . "\\rfloor")
-           ("\\lceil" . "\\rceil")))
-        (ambiguous-parens
-         '("|" "\\|" "\\vert" "\\Vert"))
-        (unambiguous-modifiers
-         '(("\\left" . "\\right")
-           ("\\bigl" . "\\bigr")
-           ("\\Bigl" . "\\Bigr")
-           ("\\biggl" . "\\biggr")
-           ("\\Biggl" . "\\Biggr")))
-        (ambiguous-modifiers
-         '("\\big" "\\Big" "\\bigg" "\\Bigg"))
-        (other-parens
-         '(("``" . "''")
-           ("$" . "$")
-           ("{" . "}")
-           ("$$" . "$$")
-           ("\\(" . "\\)")
-           ("\\[" . "\\]")
-           ("\\left." . "\\right."))))
+(defcustom tp-left-right-delimiter-pairs
+  '(("(" . ")")
+    ("[" . "]")
+    ("\\{" . "\\}")
+    ("\\langle" . "\\rangle")
+    ("\\lvert" . "\\rvert")
+    ("\\lVert" . "\\rVert")
+    ("\\lfloor" . "\\rfloor")
+    ("\\lceil" . "\\rceil"))
+  "Left/right pairs of delimiters."
+  :type '(repeat (cons string string)))
+
+(defcustom tp-solo-delimiters
+  '("|" "\\|" "\\vert" "\\Vert")
+  "Delimiters that do come in pairs."
+  :type '(repeat string))
+
+(defcustom tp-left-right-modifier-pairs
+  '(("\\left" . "\\right")
+    ("\\bigl" . "\\bigr")
+    ("\\Bigl" . "\\Bigr")
+    ("\\biggl" . "\\biggr")
+    ("\\Biggl" . "\\Biggr"))
+  "Left/right pairs of delimiter modifiers."
+  :type '(repeat (cons string string)))
+
+(defcustom tp-solo-modifiers
+  '("\\big" "\\Big" "\\bigg" "\\Bigg")
+  "Delimiter modifiers that do not come in pairs."
+  :type '(repeat string))
+
+(defcustom tp-other-parens
+  '(("``" . "''")
+    ("{" . "}")
+    ("\\(" . "\\)")
+    ("\\[" . "\\]")
+    ("\\left." . "\\right."))
+  "Left/right delimiters not to be combined with modifiers."
+  :type '(repeat (cons string string)))
+
+(defun tp--reduce-append (func list1 list2)
+  "List consisting of FUNC applied to pairs from LIST1 and LIST2."
+  (cl-reduce #'append
+             (mapcar (lambda (item1)
+                       (mapcar (lambda (item2)
+                                 (funcall func item1 item2))
+                               list2))
+                     list1)))
+
+(defun tp--generate-pairs ()
+  "Generate list of left/right pairs of delimiters.
+With the exception of the math delimiters `$' and `$$', we only
+form delimiters which are visibly `left'/`opening' or
+`right'/`closing'."
+  (let ((unambiguous-parens tp-left-right-delimiter-pairs)
+        (ambiguous-parens tp-solo-delimiters)
+        (unambiguous-modifiers tp-left-right-modifier-pairs)
+        (ambiguous-modifiers tp-solo-modifiers))
     (append
-     other-parens unambiguous-parens
-     (cl-reduce #'append
-                (mapcar
-                 (lambda (unam-par)
-                   (mapcar
-                    (lambda (unam-mod)
-                      (cons (concat (car unam-mod) (car unam-par))
-                            (concat (cdr unam-mod) (cdr unam-par))))
-                    unambiguous-modifiers))
-                 unambiguous-parens))
-     (cl-reduce #'append
-                (mapcar
-                 (lambda (unam-par)
-                   (mapcar
-                    (lambda (am-mod)
-                      (cons (concat am-mod (car unam-par))
-                            (concat am-mod (cdr unam-par))))
-                    ambiguous-modifiers))
-                 unambiguous-parens))
-     (cl-reduce #'append
-                (mapcar
-                 (lambda (am-par)
-                   (mapcar
-                    (lambda (unam-mod)
-                      (cons (concat (car unam-mod) am-par)
-                            (concat (cdr unam-mod) am-par)))
-                    unambiguous-modifiers))
-                 ambiguous-parens)))))
-
-(defvar tex-parens--pairs nil)
-(defvar tex-parens--pairs-swap nil)
-(defvar tex-parens--delims nil)
-(defvar tex-parens--regexp nil)
-(defvar tex-parens--regexp-reverse nil)
+     tp-other-parens
+     '(("$" . "$")
+       ("$$" . "$$"))
+     unambiguous-parens
+     (tp--reduce-append
+      (lambda (up um)
+        (cons (concat (car um) (car up))
+              (concat (cdr um) (cdr up))))
+      unambiguous-parens unambiguous-modifiers)
+     (tp--reduce-append
+      (lambda (up m)
+        (cons (concat m (car up))
+              (concat m (cdr up))))
+      unambiguous-parens ambiguous-modifiers)
+     (tp--reduce-append
+      (lambda (p um)
+        (cons (concat (car um) p)
+              (concat (cdr um) p)))
+      ambiguous-parens unambiguous-modifiers))))
+
+(defvar tp--pairs nil)
+(defvar tp--pairs-swap nil)
+(defvar tp--delims nil)
+(defvar tp--regexp nil)
+(defvar tp--regexp-reverse nil)
 
 (defvar preview-auto-reveal)
 
-(defun tex-parens-setup ()
+(defun tp-setup ()
   "Set up tex-parens.  Intended as a hook for `LaTeX-mode'."
   (setq
    preview-auto-reveal
    '(eval (preview-arrived-via (key-binding [left])
                                (key-binding [right])
-                               #'backward-char #'forward-char 
#'tex-parens-down-list)))
-  (setq-local beginning-of-defun-function #'tex-parens--beginning-of-defun)
-  (setq-local transpose-sexps-default-function 
#'tex-parens-transpose-sexps-default-function)
-  (setq end-of-defun-function #'tex-parens--end-of-defun)
-  (setq tex-parens--pairs (tex-parens--generate-pairs))
-  (setq tex-parens--pairs-swap
-        (mapcar (lambda (x) (cons (cdr x) (car x))) tex-parens--pairs))
-  (setq tex-parens--delims (append (mapcar #'car tex-parens--pairs)
-                                   (mapcar #'cdr tex-parens--pairs)))
-  (setq tex-parens--regexp
-        (concat (regexp-opt tex-parens--delims)
+                               #'backward-char #'forward-char #'tp-down-list)))
+  (setq-local beginning-of-defun-function #'tp--beginning-of-defun)
+  (setq-local transpose-sexps-default-function 
#'tp-transpose-sexps-default-function)
+  (setq end-of-defun-function #'tp--end-of-defun)
+  (setq tp--pairs (tp--generate-pairs))
+  (setq tp--pairs-swap
+        (mapcar (lambda (x) (cons (cdr x) (car x))) tp--pairs))
+  (setq tp--delims (append (mapcar #'car tp--pairs)
+                                   (mapcar #'cdr tp--pairs)))
+  (setq tp--regexp
+        (concat (regexp-opt tp--delims)
                 "\\|\\\\begin{[^}]+}\\|\\\\end{[^}]+}"))
-  (setq tex-parens--regexp-reverse
+  (setq tp--regexp-reverse
         (concat "}[^{]+{nigeb\\\\\\|}[^{]+{dne\\\\\\|"
-                (regexp-opt (mapcar #'reverse tex-parens--delims))))
+                (regexp-opt (mapcar #'reverse tp--delims))))
 
   ;; Don't know why, but Emacs freezes with the following line
   ;; uncommented.  For this reason, we have to go through the
   ;; awkwardness of duplicating several functions near the bottom of
   ;; this file.
 
-  ;; (setq-local forward-sexp-function #'tex-parens-forward-sexp)
+  ;; (setq-local forward-sexp-function #'tp-forward-sexp)
   )
 
-(defcustom tex-parens-search-limit 10000
+(defcustom tp-search-limit 10000
   "How far to search for a delimiter, in either direction.
 This should exceed the length, in characters, of the longest
-theorem-like environments that you encounter in practice."
+theorem-like environments to which you care about applying the
+list and sexp-based navigation commands.  Longer environments
+typically occur at the top level and are best navigated using the
+defun-based commands."
   :type 'integer
   :group 'tex-parens)
 
-(defun tex-parens--forward-bound ()
+(defun tp--math-face-p ()
+  "Check if point is in a math face."
+  (let ((face (plist-get (text-properties-at (point))
+                         'face)))
+    (cond
+     ((memq face '(tex-math font-latex-math-face))
+      1)
+     ((listp face)
+      (let ((total 0))
+        (dolist (f face)
+          (when (memq f '(tex-math font-latex-math-face))
+            (setq total (1+ total))))
+        total))
+     (t 0))))
+
+(defcustom tp-ignore-comments t
+  "Whether to ignore comments when searching for delimiters."
+  :type 'boolean
+  :group 'tex-parens)
+
+(defun tp--ignore (m-str m-begin m-end)
+  (or
+   (and
+    tp-ignore-comments
+    (let ((face (plist-get (text-properties-at (point))
+                           'face)))
+      (eq face 'font-lock-comment-face)))
+   (and
+    ;; ignore double prime in math-mode
+    (equal m-str "''")
+    (> (tp--math-face-p) 0))
+   ;; (and
+   ;;  ;; ignore dollar signs that don't matter for whatever reason
+   ;;  (member m-str '("$" "$$"))
+   ;;  (equal
+   ;;   (save-excursion
+   ;;     (goto-char (1- m-begin))
+   ;;     (tp--math-face-p))
+   ;;   (save-excursion
+   ;;     (goto-char m-end)
+   ;;     (tp--math-face-p))))
+   ))
+
+(defun tp--search-forward (regexp bound)
+  (let (success done)
+    (while (not done)
+      (if (re-search-forward regexp bound t)
+          (when (not (tp--ignore (match-string 0)
+                                 (match-beginning 0)
+                                 (match-end 0)))
+            (setq done t
+                  success t))
+        (setq done t)))
+    (when success
+      (match-string 0))))
+
+(defun tp--search-backward (regexp bound)
+  (let* ((text (buffer-substring bound (point)))
+         (buf (current-buffer))
+         result)
+    (with-temp-buffer
+      (insert (reverse text))
+      (goto-char (point-min))
+      (setq result
+            (let (success done)
+              (while (not done)
+                (if (re-search-forward regexp bound t)
+                    (when (not
+                           (let ((new-point (point))
+                                 (m-string (match-string 0))
+                                 (m-begin (match-beginning 0))
+                                 (m-end (match-end 0)))
+                             (with-current-buffer buf
+                               (save-excursion
+                                 (backward-char (1- new-point))
+                                 (tp--ignore m-string m-begin m-end)))))
+                      (setq done t
+                            success t))
+                  (setq done t)))
+              (when success
+                (cons (point) (match-string 0))))))
+    (when result
+      (let ((new-point (car result))
+            (match (cdr result)))
+        (backward-char (1- new-point))
+        (reverse match)))))
+
+(defun tp--forward-bound ()
   "Return the bound for forward search."
   (save-excursion
     (min
      (point-max)
-     (+ (point) tex-parens-search-limit))))
+     (+ (point) tp-search-limit))))
 
-(defun tex-parens--backward-bound ()
+(defun tp--backward-bound ()
   "Return the bound for backward search."
   (save-excursion
     (max
      (point-min)
-     (- (point) tex-parens-search-limit))))
+     (- (point) tp-search-limit))))
 
-(defun tex-parens--forward-delim (&optional bound)
-  "Search for the next delimiter up to BOUND."
-  (interactive)
-  (unless bound (setq bound (tex-parens--forward-bound)))
-  (when (re-search-forward tex-parens--regexp bound t)
-    (match-string 0)))
+(defun tp--forward-delim (&optional bound)
+  "Search for the next delimiter up to BOUND.
+Return the delimiter found, or nil if none is found."
+  (unless bound (setq bound (tp--forward-bound)))
+  (tp--search-forward tp--regexp bound))
 
-(defun tex-parens--backward-delim (&optional bound)
-  "Search for the previous delimiter up to BOUND."
-  (interactive)
-  (unless bound (setq bound (tex-parens--backward-bound)))
-  (let* ((text (buffer-substring-no-properties bound (point)))
-         match result)
-    (with-temp-buffer
-      (insert (reverse text))
-      (goto-char (point-min))
-      (setq result (re-search-forward tex-parens--regexp-reverse nil t))
-      (when result (setq match (match-string 0))))
-    (when result
-      (backward-char (1- result))
-      (reverse match))))
+(defun tp--backward-delim (&optional bound)
+  "Search for the previous delimiter up to BOUND.
+Return the delimiter found, or nil if none is found."
+  (unless bound (setq bound (tp--backward-bound)))
+  (tp--search-backward tp--regexp-reverse bound))
 
-(defun tex-parens--close-of-open (delim)
+(defun tp--close-of-open (delim)
   "Check if DELIM is opening, return the corresponding closing.
 If DELIM is an opening delimiter, return the corresponding closing
 delimiter.  Otherwise, return nil."
   (or
-   (cdr (assoc delim tex-parens--pairs))
+   (cdr (assoc delim tp--pairs))
    (and (stringp delim)
         (string-match "\\\\begin{\\([^}]+\\)}" delim)
         (let ((type (match-string 1 delim)))
           (format "\\end{%s}" type)))))
 
-(defun tex-parens--open-of-close (delim)
+(defun tp--open-of-close (delim)
   "Check if DELIM is closing, return the corresponding opening.
 If DELIM is a closing delimiter, return the corresponding opening
 delimiter.  Otherwise, return nil."
   (or
-   (cdr (assoc delim tex-parens--pairs-swap))
+   (cdr (assoc delim tp--pairs-swap))
    (and (stringp delim)
         (string-match "\\\\end{\\([^}]+\\)}" delim)
         (let ((type (match-string 1 delim)))
           (format "\\begin{%s}" type)))))
 
-(defun tex-parens--math-face-p ()
-  "Check if point is in a math face."
-  (let ((face (plist-get (text-properties-at (point))
-                         'face)))
-    (or (eq face 'font-latex-math-face)
-        (and (listp face)
-             (memq 'font-latex-math-face face)))))
-
-(defvar tex-parens--debug nil)
-
-(defun tex-parens-forward-list (&optional bound)
+(defvar tp--debug nil)
+
+(defun tp--forward-search-found-open (delim)
+  "Check if DELIM is an opening delimiter found by forward search."
+  (cond
+   ((member delim '("$" "$$"))
+    (>
+     (tp--math-face-p)
+     (save-excursion
+       (backward-char (1+ (length delim)))
+       (tp--math-face-p))
+     ))
+   (t
+    (tp--close-of-open delim))))
+
+(defun tp--backward-search-found-close (delim)
+  "Check if DELIM is a closing delimiter found by backward search."
+  (cond
+   ((member delim '("$" "$$"))
+    (>
+     (save-excursion
+       (backward-char 1)
+       (tp--math-face-p))
+     (save-excursion
+       (forward-char (length delim))
+       (tp--math-face-p))))
+   (t
+    (tp--open-of-close delim))))
+
+(defun tp--check-match (delim other stack-top)
+  "Internal function used for debugging.
+Check that OTHER is non-nil.  This should always be the case.
+Then, if debugging is enabled, check whether STACK-TOP and DELIM
+coincide.  Sometimes this is intentional (e.g., when `\right.'
+terminates `\left{'), so we do not treat it as an error."
+  (cl-assert other)
+  (when tp--debug
+    (unless (equal other stack-top)
+      (message "Mismatched delimiters: %s %s" stack-top delim))))
+
+(defun tp-forward-list (&optional bound)
   "Move forward across one balanced group.
 Search up to BOUND."
   (interactive)
-  (unless bound (setq bound (tex-parens--forward-bound)))
+  (unless bound (setq bound (tp--forward-bound)))
   (let ((start (point))
-        (delim (tex-parens--forward-delim bound))
-        (stack ()))
+        (delim (tp--forward-delim bound))
+        (stack ())
+        success)
     (while delim
-      (if (or (and (member delim '("$" "$$"))
-                   (tex-parens--math-face-p))
-              (and (not (member delim '("$" "$$")))
-                   (tex-parens--close-of-open delim)))
+      (if (tp--forward-search-found-open delim)
           (push delim stack)
-        (let ((other (tex-parens--open-of-close delim)))
-          (cl-assert other)
-          (if stack
-              (progn
-                (when tex-parens--debug
-                  (unless (equal other (car stack))
-                    (message "Mismatched delimiters: %s %s" (car stack) 
delim)))
-                (pop stack))
-            (backward-char (length delim)))))
-      (setq delim (and stack (tex-parens--forward-delim bound))))
-    (when stack
+        (if stack
+            (progn
+              (tp--check-match delim (tp--open-of-close delim) (car stack))
+              (pop stack)
+              (unless stack
+                (setq success t)))
+          (backward-char (length delim))
+          (setq success t)))
+      (setq delim (and (not success) (tp--forward-delim bound))))
+    (unless success
       (goto-char start)
-      (when tex-parens--debug
+      (when tp--debug
         (message "Unmatched delimiters: %s" (car stack))))))
 
-(defun tex-parens-backward-list (&optional bound)
+(defun tp-backward-list (&optional bound)
   "Move backward across one balanced group.
 Search up to BOUND."
   (interactive)
-  (unless bound (setq bound (tex-parens--backward-bound)))
+  (unless bound (setq bound (tp--backward-bound)))
   (let ((start (point))
-        (delim (tex-parens--backward-delim bound))
-        (stack ()))
+        (delim (tp--backward-delim bound))
+        (stack ())
+        success)
     (while delim
-      (if (or (and (member delim '("$" "$$"))
-                   (save-excursion
-                     (backward-char (length delim))
-                     (tex-parens--math-face-p)))
-              (and (not (member delim '("$" "$$")))
-                   (tex-parens--open-of-close delim)))
+      (if (tp--backward-search-found-close delim)
           (push delim stack)
-        (let ((other (tex-parens--close-of-open delim)))
-          (cl-assert other)
-          (if stack
-              (progn
-                (when tex-parens--debug
-                  (unless (equal other (car stack))
-                    (message "Mismatched delimiters: %s %s" delim (car 
stack))))
-                (pop stack))
-            (forward-char (length delim)))))
-      (setq delim (and stack (tex-parens--backward-delim bound))))
-    (when stack
+        (if stack
+            (progn
+              (tp--check-match delim (tp--close-of-open delim) (car stack))
+              (pop stack)
+              (unless stack
+                (setq success t)))
+          (forward-char (length delim))
+          (setq success t)))
+      (setq delim (and (not success) (tp--backward-delim bound))))
+    (unless success
       (goto-char start)
-      (when tex-parens--debug
+      (when tp--debug
         (message "Unmatched delimiters: %s" (car stack))))))
 
-(defun tex-parens-backward-up-list (&optional bound)
+(defun tp-backward-up-list (&optional bound)
   "Move backward out of one balanced group.
 Search up to BOUND."
   (interactive)
-  (unless bound (setq bound (tex-parens--backward-bound)))
+  (unless bound (setq bound (tp--backward-bound)))
   (let ((start (point))
         success
-        (delim (tex-parens--backward-delim bound))
+        (delim (tp--backward-delim bound))
         (stack ()))
     (while delim
-      (cond
-       ((or
-         (and (member delim '("$" "$$"))
-              (save-excursion
-                (backward-char (length delim))
-                (tex-parens--math-face-p)))
-         (and (not (member delim '("$" "$$")))
-              (tex-parens--open-of-close delim)))
-        (push delim stack))
-       (t
-        (let ((other (tex-parens--close-of-open delim)))
-          (cl-assert other)
-          (if stack
-              (progn
-                (when tex-parens--debug
-                  (unless (equal other (car stack))
-                    (message "Mismatched delimiters: %s %s" delim (car 
stack))))
-                (pop stack))
-            (setq success t))
-          ;; (push delim stack))
-          
-          ;; (if (equal other (car stack))
-          ;;     (pop stack)
-          ;;   (setq success t))
-          )
-        ;; (assoc delim tex-parens-pairs)
-                                        ; Opening delimiter
-        ;; (if (equal (cdr (tex-parens-delim-pair delim)) (car stack))
-        ;;     (pop stack)
-        ;;   (setq success t))
-        )
-       )
-      (setq delim (and (not success) (tex-parens--backward-delim bound))))
+      (if (tp--backward-search-found-close delim)
+          (push delim stack)
+        (if stack
+            (progn
+              (tp--check-match delim (tp--close-of-open delim) (car stack))
+              (pop stack))
+          (setq success t)))
+      (setq delim (and (not success) (tp--backward-delim bound))))
     (unless success
       (goto-char start))))
 
-(defun tex-parens-up-list (&optional bound)
+(defun tp-up-list (&optional bound)
   "Move forward out of one balanced group.
 Search up to BOUND."
   (interactive)
-  (unless bound (setq bound (tex-parens--forward-bound)))
+  (unless bound (setq bound (tp--forward-bound)))
   (let ((start (point))
         success
-        (delim (tex-parens--forward-delim bound))
+        (delim (tp--forward-delim bound))
         (stack ()))
     (while delim
-      (cond
-       ((or
-         (and (member delim '("$" "$$"))
-              (tex-parens--math-face-p))
-         (and (not (member delim '("$" "$$")))
-              (tex-parens--close-of-open delim)))
-        (push delim stack))
-       (t
-        (let ((other (tex-parens--open-of-close delim)))
-          (cl-assert other)
-          (if stack
-              (progn
-                (when tex-parens--debug
-                  (unless (equal other (car stack))
-                    (message "Mismatched delimiters: %s %s" delim (car 
stack))))
-                (pop stack))
-            (setq success t)))
-        ;; (cdr (tex-parens-delim-pair delim))
-                                        ; Closing delimiter
-        ;; (if (equal (cdr (tex-parens-delim-pair delim)) (car stack))
-        ;;     (pop stack)
-        ;;   (setq success t))
-        )
-       )
-      (setq delim (and (not success) (tex-parens--forward-delim bound))))
+      (if (tp--forward-search-found-open delim)
+          (push delim stack)
+        (if stack
+            (progn
+              (tp--check-match delim (tp--open-of-close delim) (car stack))
+              (pop stack))
+          (setq success t)))
+      (setq delim (and (not success) (tp--forward-delim bound))))
     (unless success
       (goto-char start))))
 
-(defun tex-parens-forward-sexp-1 ()
-  "Move forward across one balanced expression (sexp)."
-  (interactive)
+(defun tp--forward-sexp-1 ()
+  "Move forward across one balanced expression (sexp).
+Helper function for `tp-backward-sexp'."
   (let ((delim-beg (save-excursion
-                     (tex-parens--forward-delim)
+                     (tp--forward-delim)
                      (match-beginning 0)))
         (vanilla (save-excursion
                    (goto-char (or (scan-sexps (point) 1) (buffer-end 1)))
                    (point))))
     (if (and delim-beg
              (> vanilla delim-beg))
-        (tex-parens-forward-list)
+        (tp-forward-list)
       (goto-char vanilla))))
 
-(defun tex-parens-backward-sexp ()
+(defun tp-backward-sexp ()
   "Move backward across one balanced expression (sexp).
 If `backward-sexp' does not take us beyond the ending point of
 the previous delimiter, then do that.  Otherwise, do
-`tex-parens-backward-list'."
+`tp-backward-list'."
   (interactive)
   (let ((delim-end (save-excursion
-                     (when-let ((delim (tex-parens--backward-delim)))
+                     (when-let ((delim (tp--backward-delim)))
                        (forward-char (length delim))
                        (point))))
         (vanilla (save-excursion
@@ -409,40 +501,36 @@ the previous delimiter, then do that.  Otherwise, do
                    (point))))
     (if (and delim-end
              (< vanilla delim-end))
-        (tex-parens-backward-list)
+        (tp-backward-list)
       (goto-char vanilla))))
 
-(defun tex-parens-forward-sexp (&optional arg)
+(defun tp-forward-sexp (&optional arg)
   "Move forward across one balanced expression (sexp).
 If `forward-sexp' does not take us past the starting point of the
 next delimiter, then do that.  Otherwise, do
-`tex-parens-forward-list'.
+`tp-forward-list'.
 
 With ARG, do it that many times.  Negative arg -N means move
 backward across N balanced expressions."
   (interactive "^p")
   (or arg (setq arg 1))
   (while (> arg 0)
-    (tex-parens-forward-sexp-1)
+    (tp--forward-sexp-1)
     (setq arg (1- arg)))
   (while (< arg 0)
-    (tex-parens-backward-sexp)
+    (tp-backward-sexp)
     (setq arg (1+ arg))))
 
-(defun tex-parens-down-list (&optional bound)
+(defun tp-down-list (&optional bound)
   "Move forward into one balanced group.
 Search up to BOUND.  Return t if successful, nil otherwise."
   (interactive)
-  (unless bound (setq bound (tex-parens--forward-bound)))
+  (unless bound (setq bound (tp--forward-bound)))
   (let ((start (point))
-        (delim (tex-parens--forward-delim bound))
+        (delim (tp--forward-delim bound))
         success)
     (when (and delim
-               (or
-                (and (equal delim "$")
-                     (tex-parens--math-face-p))
-                (and (not (equal delim "$"))
-                     (tex-parens--close-of-open delim))))
+               (tp--forward-search-found-open delim))
       (setq success t))
     (unless success
       (goto-char start))
@@ -450,31 +538,32 @@ Search up to BOUND.  Return t if successful, nil 
otherwise."
       (preview-move-point))
     success))
 
-(defun tex-parens-delete-pair (&optional bound)
+(defun tp-delete-pair (&optional bound)
   "Delete a balanced pair of delimiters that follow point.
 Push a mark at the end of the contents of the pair.
 Search up to BOUND."
   (interactive)
-  (unless bound (setq bound (tex-parens--forward-bound)))
-  (when (tex-parens-down-list bound)
+  (unless bound (setq bound (tp--forward-bound)))
+  (when (tp-down-list bound)
     (save-excursion
-      (tex-parens-up-list)
+      (tp-up-list)
       (let ((q (point)))
-        (tex-parens--backward-delim)
+        (tp--backward-delim)
         (delete-region (point) q)
         (push-mark)))
     (let ((q (point)))
-      (tex-parens--backward-delim)
+      (tp--backward-delim)
       (delete-region (point) q))))
 
 ;;; AWKWARDNESS BEGINS HERE
 
-;; it shouldn't be necessary to define any of the following -- it
-;; should suffice to set forward-sexp-function to
-;; tex-parens-forward-sexp -- but for some reason, Emacs freezes when
-;; I do so.  whatever.  the ad hoc solution works fine
+;; it shouldn't be necessary to define any of the following (via
+;; copy/paste from lisp.el and simple.el) -- it should suffice to set
+;; forward-sexp-function to tp-forward-sexp -- but for some
+;; reason, Emacs freezes when I do so.  I haven't been able to debug
+;; why.  alas.
 
-(defun tex-parens-mark-sexp (&optional arg allow-extend)
+(defun tp-mark-sexp (&optional arg allow-extend)
   "Set mark ARG sexps from point or move mark one sexp.
 When called from Lisp with ALLOW-EXTEND omitted or nil, mark is
 set ARG sexps from point.
@@ -502,7 +591,7 @@ This command assumes point is not in a string or comment."
                 (save-excursion
                   (goto-char (mark))
             (condition-case error
-                      (tex-parens-forward-sexp arg)
+                      (tp-forward-sexp arg)
               (scan-error
                (user-error (if (equal (cadr error)
                                       "Containing expression ends prematurely")
@@ -513,7 +602,7 @@ This command assumes point is not in a string or comment."
                (push-mark
                 (save-excursion
             (condition-case error
-                      (tex-parens-forward-sexp (prefix-numeric-value arg))
+                      (tp-forward-sexp (prefix-numeric-value arg))
               (scan-error
                (user-error (if (equal (cadr error)
                                       "Containing expression ends prematurely")
@@ -522,7 +611,7 @@ This command assumes point is not in a string or comment."
                   (point))
                 nil t))))
 
-(defun tex-parens-kill-sexp (&optional arg interactive)
+(defun tp-kill-sexp (&optional arg interactive)
   "Kill the sexp (balanced expression) following point.
 With ARG, kill that many sexps after point.
 Negative arg -N means kill N sexps before point.
@@ -537,10 +626,10 @@ report errors as appropriate for this kind of usage."
                                     "No next sexp"
                                   "No previous sexp"))))
     (let ((opoint (point)))
-      (tex-parens-forward-sexp (or arg 1))
+      (tp-forward-sexp (or arg 1))
       (kill-region opoint (point)))))
 
-(defun tex-parens-backward-kill-sexp (&optional arg interactive)
+(defun tp-backward-kill-sexp (&optional arg interactive)
   "Kill the sexp (balanced expression) preceding point.
 With ARG, kill that many sexps before point.
 Negative arg -N means kill N sexps after point.
@@ -548,9 +637,9 @@ This command assumes point is not in a string or comment.
 If INTERACTIVE is non-nil, as it is interactively,
 report errors as appropriate for this kind of usage."
   (interactive "p\nd")
-  (tex-parens-kill-sexp (- (or arg 1)) interactive))
+  (tp-kill-sexp (- (or arg 1)) interactive))
 
-(defun tex-parens-transpose-sexps-default-function (arg)
+(defun tp-transpose-sexps-default-function (arg)
   "Default method to locate a pair of points for `transpose-sexps'.
 ARG is as in the docstring for `transpose-sexps'."
   ;; Here we should try to simulate the behavior of
@@ -569,13 +658,13 @@ ARG is as in the docstring for `transpose-sexps'."
       (progn (funcall (if (> arg 0)
                                               #'skip-syntax-backward 
#'skip-syntax-forward)
                                    "w_")
-                   (cons (save-excursion (tex-parens-forward-sexp arg) 
(point)) (point)))
+                   (cons (save-excursion (tp-forward-sexp arg) (point)) 
(point)))
     ;; Otherwise, we're between sexps.  Take a step back before jumping
     ;; to make sure we'll obey the same precedence no matter which
     ;; direction we're going.
     (funcall (if (> arg 0) #'skip-syntax-backward #'skip-syntax-forward)
              " .")
-    (cons (save-excursion (tex-parens-forward-sexp arg) (point))
+    (cons (save-excursion (tp-forward-sexp arg) (point))
                 (progn (while (or (forward-comment (if (> arg 0) 1 -1))
                                                 (not (zerop (funcall (if (> 
arg 0)
                                                                                
               #'skip-syntax-forward
@@ -583,7 +672,7 @@ ARG is as in the docstring for `transpose-sexps'."
                                                                                
           ".")))))
                               (point)))))
 
-(defun tex-parens-raise-sexp (&optional n)
+(defun tp-raise-sexp (&optional n)
   "Raise N sexps one level higher up the tree.
 
 This function removes the sexp enclosing the form which follows
@@ -609,9 +698,9 @@ and point is before (zot), \\[raise-sexp] will give you
                (buffer-substring (region-beginning) (region-end))
              (buffer-substring
               (point)
-              (save-excursion (tex-parens-forward-sexp n) (point))))))
-    (tex-parens-backward-up-list)
-    (delete-region (point) (save-excursion (tex-parens-forward-sexp 1) 
(point)))
+              (save-excursion (tp-forward-sexp n) (point))))))
+    (tp-backward-up-list)
+    (delete-region (point) (save-excursion (tp-forward-sexp 1) (point)))
     (save-excursion (insert s))))
 
 (provide 'tex-parens)

Reply via email to