Function: treesit-up-list

treesit-up-list is an interactive and byte-compiled function defined in treesit.el.gz.

Signature

(treesit-up-list &optional ARG ESCAPE-STRINGS NO-SYNTAX-CROSSING)

Documentation

Move forward out of one level of parentheses.

What constitutes a level of parentheses is determined by list in treesit-thing-settings that usually defines parentheses-like expressions.

This command is the tree-sitter variant of up-list redefined by the variable up-list-function.

ARG is described in the docstring of up-list.

Probably introduced at or before Emacs version 31.1.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/treesit.el.gz
(defun treesit-up-list (&optional arg escape-strings no-syntax-crossing)
  "Move forward out of one level of parentheses.
What constitutes a level of parentheses is determined by
`list' in `treesit-thing-settings' that usually defines
parentheses-like expressions.

This command is the tree-sitter variant of `up-list'
redefined by the variable `up-list-function'.

ARG is described in the docstring of `up-list'."
  (interactive "^p")
  (let* ((pred (or treesit-sexp-thing-up-list
                   treesit-sexp-thing
                   'list))
         (arg (or arg 1))
         (treesit--parser-overlay-offset -1)
         (cnt arg)
         (inc (if (> arg 0) 1 -1)))
    (while (/= cnt 0)
      (let* ((default-pos
              (condition-case _
                  (save-excursion
                    (let ((forward-sexp-function nil))
                      (up-list-default-function
                       inc escape-strings no-syntax-crossing))
                    (point))
                (scan-error nil)
                (user-error nil)))
             (parent (treesit-thing-at (point) pred)))
        (while (and parent (eq (point) (if (> arg 0)
                                           (treesit-node-end parent)
                                         (treesit-node-start parent))))
          (setq parent (treesit-parent-until parent pred)))

        (unless parent
          (let ((parsers (mapcar #'cdr (treesit-parsers-at (point) nil t '(global local)))))
            (while (and (not parent) parsers)
              (setq parent (treesit-parent-until
                            (treesit-node-at (point) (car parsers)) pred)
                    parsers (cdr parsers)))))

        (or (when (and (null (or treesit-sexp-thing-up-list
                                 treesit-sexp-thing))
                       default-pos
                       ;; The default function returns wrong results
                       ;; when crossing multi-language boundaries:
                       (eq (treesit-language-at default-pos)
                           (treesit-language-at (point)))
                       (or (null parent)
                           (if (> arg 0)
                               (<= default-pos (treesit-node-end parent))
                             (>= default-pos (treesit-node-start parent)))))
              (goto-char default-pos))
            (when parent
              (goto-char (if (> arg 0)
                             (treesit-node-end parent)
                           (treesit-node-start parent))))
            (if no-syntax-crossing
                ;; Assume called interactively; don't signal an error.
                (user-error "At top level")
              (signal 'scan-error
                      (list (format-message "No more %S to move across" pred)
                            (point) (point))))))
      (setq cnt (- cnt inc)))))