that have defined 'sexp-list' in 'treesit-thing-settings' to enable
the 'down-list' motion command.
+*** New function 'treesit-up-list'.
+Tree-sitter conditionally sets 'up-list-function' for major modes
+that have defined 'sexp-list' in 'treesit-thing-settings' to enable
+the 'up-list' motion command.
+
+++
*** New function 'treesit-language-display-name'.
This new function returns the display name of a language given the
(interactive "^p\nd\nd")
(up-list (- (or arg 1)) escape-strings no-syntax-crossing))
+(defvar up-list-function nil
+ "If non-nil, `up-list' delegates to this function.
+Should take the same arguments and behave similarly to `up-list'.")
+
(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
On error, location of point is unspecified."
(interactive "^p\nd\nd")
+ (if up-list-function
+ (funcall up-list-function arg escape-strings no-syntax-crossing)
+ (up-list-default-function arg escape-strings no-syntax-crossing)))
+
+(defun up-list-default-function (&optional arg escape-strings no-syntax-crossing)
+ "Default function for `up-list-function'."
(or arg (setq arg 1))
(let ((inc (if (> arg 0) 1 -1))
(pos nil))
(if pos (goto-char pos) (treesit--scan-error pred arg)))
(setq arg (- arg inc)))))
+(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
+`sexp-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 'sexp-list)
+ (arg (or arg 1))
+ (inc (if (> arg 0) 1 -1)))
+ (while (/= arg 0)
+ (let ((node (treesit-thing-at (point) pred)))
+ (while (and node (eq (point) (if (> arg 0)
+ (treesit-node-end node)
+ (treesit-node-start node))))
+ (setq node (treesit-parent-until node pred)))
+ (if node
+ (goto-char (if (> arg 0)
+ (treesit-node-end node)
+ (treesit-node-start node)))
+ (user-error "At top level")))
+ (setq arg (- arg inc)))))
+
(defun treesit-transpose-sexps (&optional arg)
"Tree-sitter `transpose-sexps' function.
ARG is the same as in `transpose-sexps'.
(when (treesit-thing-defined-p 'sexp-list nil)
(setq-local forward-sexp-function #'treesit-forward-sexp-list)
(setq-local forward-list-function #'treesit-forward-list)
- (setq-local down-list-function #'treesit-down-list))
+ (setq-local down-list-function #'treesit-down-list)
+ (setq-local up-list-function #'treesit-up-list))
(when (treesit-thing-defined-p 'sentence nil)
(setq-local forward-sentence-function #'treesit-forward-sentence))