Function: electric-pair--balance-info

electric-pair--balance-info is a byte-compiled function defined in elec-pair.el.gz.

Signature

(electric-pair--balance-info DIRECTION STRING-OR-COMMENT)

Documentation

Examine lists forward or backward according to DIRECTION's sign.

STRING-OR-COMMENT is the position of the start of the comment/string in which we are, if applicable.

Return a cons of two descriptions (MATCHED-P . PAIR) for the innermost and outermost lists that enclose point. The outermost list enclosing point is either the first top-level or first mismatched list found by listing up.

If the outermost list is matched, don't rely on its PAIR. If point is not enclosed by any lists, return ((t) . (t)).

Source Code

;; Defined in /usr/src/emacs/lisp/elec-pair.el.gz
;; Balancing means controlling pairing and skipping of parentheses
;; so that, if possible, the buffer ends up at least as balanced as
;; before, if not more.  The algorithm is slightly complex because
;; some situations like "()))" need pairing to occur at the end but
;; not at the beginning.  Balancing should also happen independently
;; for different types of parentheses, so that having your {}'s
;; unbalanced doesn't keep `electric-pair-mode' from balancing your
;; ()'s and your []'s.
(defun electric-pair--balance-info (direction string-or-comment)
  "Examine lists forward or backward according to DIRECTION's sign.

STRING-OR-COMMENT is the position of the start of the comment/string
in which we are, if applicable.

Return a cons of two descriptions (MATCHED-P . PAIR) for the
innermost and outermost lists that enclose point.  The outermost
list enclosing point is either the first top-level or first
mismatched list found by listing up.

If the outermost list is matched, don't rely on its PAIR.
If point is not enclosed by any lists, return ((t) . (t))."
  (let* (innermost
         outermost
         (at-top-level-or-equivalent-fn
          ;; called when `scan-sexps' ran perfectly, when it found
          ;; a parenthesis pointing in the direction of travel.
          ;; Also when travel started inside a comment and exited it.
          (lambda ()
            (setq outermost (list t))
            (unless innermost
              (setq innermost (list t)))))
         (ended-prematurely-fn
          ;; called when `scan-sexps' crashed against a parenthesis
          ;; pointing opposite the direction of travel.  After
          ;; traversing that character, the idea is to travel one sexp
          ;; in the opposite direction looking for a matching
          ;; delimiter.
          (lambda ()
            (let* ((pos (point))
                   (matched
                    (save-excursion
                      (cond ((< direction 0)
                             (condition-case nil
                                 (eq (char-after pos)
                                     (electric-pair--with-syntax
                                         string-or-comment
                                       (matching-paren
                                        (char-before
                                         (scan-sexps (point) 1)))))
                               (scan-error nil)))
                            (t
                             ;; In this case, no need to use
                             ;; `scan-sexps', we can use some
                             ;; `electric-pair--syntax-ppss' in this
                             ;; case (which uses the quicker
                             ;; `syntax-ppss' in some cases)
                             (let* ((ppss (electric-pair--syntax-ppss
                                           (1- (point))))
                                    (start (car (last (nth 9 ppss))))
                                    (opener (char-after start)))
                               (and start
                                    (eq (char-before pos)
                                        (or (electric-pair--with-syntax
                                                string-or-comment
                                              (matching-paren opener))
                                            opener))))))))
                   (actual-pair (if (> direction 0)
                                    (char-before (point))
                                  (char-after (point)))))
              (unless innermost
                (setq innermost (cons matched actual-pair)))
              (unless matched
                (setq outermost (cons matched actual-pair)))))))
    (save-excursion
      (while (not outermost)
        (condition-case err
            (electric-pair--with-syntax string-or-comment
              (scan-sexps (point) (if (> direction 0)
                                      (point-max)
                                    (- (point-max))))
              (funcall at-top-level-or-equivalent-fn))
          (scan-error
           (cond ((or
                   ;; some error happened and it is not of the "ended
                   ;; prematurely" kind...
                   (not (string-match "ends prematurely" (nth 1 err)))
                   ;; ... or we were in a comment and just came out of
                   ;; it.
                   (and string-or-comment
                        (not (nth 8 (syntax-ppss)))))
                  (funcall at-top-level-or-equivalent-fn))
                 (t
                  ;; exit the sexp
                  (goto-char (nth 3 err))
                  (funcall ended-prematurely-fn)))))))
    (cons innermost outermost)))