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 delimiters
;; 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 delimiter, 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)))