Function: up-list
up-list is an interactive and byte-compiled function defined in
lisp.el.gz.
Signature
(up-list &optional ARG ESCAPE-STRINGS NO-SYNTAX-CROSSING)
Documentation
Move forward out of one level of parentheses.
This command will also work on other parentheses-like expressions defined by the current language mode. With ARG, do this that many times. A negative argument means move backward but still to a less deep spot.
If ESCAPE-STRINGS is non-nil (as it is interactively), move out of enclosing strings as well.
If NO-SYNTAX-CROSSING is non-nil (as it is interactively), prefer to break out of any enclosing string instead of moving to the end of a list broken across multiple strings.
On error, location of point is unspecified.
Probably introduced at or before Emacs version 19.20.
Key Bindings
Source Code
;; Defined in /usr/src/emacs/lisp/emacs-lisp/lisp.el.gz
(defun up-list (&optional arg escape-strings no-syntax-crossing)
"Move forward out of one level of parentheses.
This command will also work on other parentheses-like expressions
defined by the current language mode. With ARG, do this that
many times. A negative argument means move backward but still to
a less deep spot.
If ESCAPE-STRINGS is non-nil (as it is interactively), move out
of enclosing strings as well.
If NO-SYNTAX-CROSSING is non-nil (as it is interactively), prefer
to break out of any enclosing string instead of moving to the
end of a list broken across multiple strings.
On error, location of point is unspecified."
(interactive "^p\nd\nd")
(or arg (setq arg 1))
(let ((inc (if (> arg 0) 1 -1))
(pos nil))
(while (/= arg 0)
(condition-case err
(save-restriction
;; If we've been asked not to cross string boundaries
;; and we're inside a string, narrow to that string so
;; that scan-lists doesn't find a match in a different
;; string.
(when no-syntax-crossing
(let* ((syntax (syntax-ppss))
(string-comment-start (nth 8 syntax)))
(when string-comment-start
(save-excursion
(goto-char string-comment-start)
(narrow-to-region
(point)
(if (nth 3 syntax) ; in string
(condition-case nil
(progn (forward-sexp) (point))
(scan-error (point-max)))
(forward-comment 1)
(point)))))))
(if (null forward-sexp-function)
(goto-char (or (scan-lists (point) inc 1)
(buffer-end arg)))
(condition-case err
(while (progn (setq pos (point))
(forward-sexp inc)
(/= (point) pos)))
(scan-error (goto-char (nth (if (> arg 0) 3 2) err))))
(if (= (point) pos)
(signal 'scan-error
(list "Unbalanced parentheses" (point) (point))))))
(scan-error
(let ((syntax nil))
(or
;; If we bumped up against the end of a list, see whether
;; we're inside a string: if so, just go to the beginning
;; or end of that string.
(and escape-strings
(or syntax (setf syntax (syntax-ppss)))
(nth 3 syntax)
(goto-char (nth 8 syntax))
(progn (when (> inc 0)
(forward-sexp))
t))
;; If we narrowed to a comment above and failed to escape
;; it, the error might be our fault, not an indication
;; that we're out of syntax. Try again from beginning or
;; end of the comment.
(and no-syntax-crossing
(or syntax (setf syntax (syntax-ppss)))
(nth 4 syntax)
(goto-char (nth 8 syntax))
(or (< inc 0)
(forward-comment 1))
(setf arg (+ arg inc)))
(if no-syntax-crossing
;; Assume called interactively; don't signal an error.
(user-error "At top level")
(signal (car err) (cdr err)))))))
(setq arg (- arg inc)))))