(point))
nil t))))
+(defun forward-list-default-function (&optional arg)
+ "Default function for `forward-list-function'."
+ (goto-char (or (scan-lists (point) arg 0) (buffer-end arg))))
+
+(defvar forward-list-function nil
+ "If non-nil, `forward-list' delegates to this function.
+Should take the same arguments and behave similarly to `forward-list'.")
+
(defun forward-list (&optional arg interactive)
"Move forward across one balanced group of parentheses.
This command will also work on other parentheses-like expressions
With ARG, do it that many times.
Negative arg -N means move backward across N groups of parentheses.
This command assumes point is not in a string or comment.
+Calls `forward-list-function' to do the work, if that is non-nil.
If INTERACTIVE is non-nil, as it is interactively,
report errors as appropriate for this kind of usage."
(interactive "^p\nd")
"No next group"
"No previous group"))))
(or arg (setq arg 1))
- (goto-char (or (scan-lists (point) arg 0) (buffer-end arg)))))
+ (if forward-list-function
+ (funcall forward-list-function arg)
+ (forward-list-default-function arg))))
(defun backward-list (&optional arg interactive)
"Move backward across one balanced group of parentheses.
With ARG, do it that many times.
Negative arg -N means move forward across N groups of parentheses.
This command assumes point is not in a string or comment.
+Uses `forward-list' to do the work.
If INTERACTIVE is non-nil, as it is interactively,
report errors as appropriate for this kind of usage."
(interactive "^p\nd")
however, smaller in scope than sentences. This is used by
`treesit-forward-sexp' and friends.")
-(defun treesit-forward-list (&optional arg)
- "Move forward across a list.
-What constitutes a list is determined by `sexp-list' in
-`treesit-thing-settings' that usually defines
-parentheses-like expressions.
-
-Unlike `forward-sexp', this command moves only across a list,
-but not across atoms (such as symbols or words) inside the list.
-
-This command is the tree-sitter variant of `forward-list'. But since
-`forward-list' has no \"forward-list-function\" like there is
-`forward-sexp-function' for `forward-sexp', this command
-can be used on its own.
-
-ARG is described in the docstring of `forward-list'."
- (interactive "^p")
- (let ((treesit-sexp-type-regexp 'sexp-list))
- (treesit-forward-sexp arg)))
-
(defun treesit-forward-sexp (&optional arg)
"Tree-sitter implementation for `forward-sexp-function'.
-ARG is described in the docstring of `forward-sexp-function'.
+ARG is described in the docstring of `forward-sexp'.
If point is inside a text environment where tree-sitter is not
supported, go forward a sexp using `forward-sexp-default-function'.
(goto-char default-pos))
(treesit-forward-list arg))))
+(defun treesit-forward-list (&optional arg)
+ "Move forward across a list.
+What constitutes a list is determined by `sexp-list' in
+`treesit-thing-settings' that usually defines
+parentheses-like expressions.
+
+Unlike `forward-sexp', this command moves only across a list,
+but not across atoms (such as symbols or words) inside the list.
+
+This command is the tree-sitter variant of `forward-list'
+redefined by the variable `forward-list-function'.
+
+ARG is described in the docstring of `forward-list'."
+ (interactive "^p")
+ (let ((arg (or arg 1))
+ (pred 'sexp-list))
+ (or (if (> arg 0)
+ (treesit-end-of-thing pred (abs arg) 'restricted)
+ (treesit-beginning-of-thing pred (abs arg) 'restricted))
+ (when-let* ((parent (treesit-thing-at (point) pred t))
+ (boundary (if (> arg 0)
+ (treesit-node-child parent -1)
+ (treesit-node-child parent 0))))
+ (signal 'scan-error (list "No more group to move across"
+ (treesit-node-start boundary)
+ (treesit-node-end boundary)))))))
+
(defun treesit-transpose-sexps (&optional arg)
"Tree-sitter `transpose-sexps' function.
ARG is the same as in `transpose-sexps'.
(setq-local transpose-sexps-function #'treesit-transpose-sexps))
(when (treesit-thing-defined-p 'sexp-list nil)
- (setq-local forward-sexp-function #'treesit-forward-sexp-list))
+ (setq-local forward-sexp-function #'treesit-forward-sexp-list)
+ (setq-local forward-list-function #'treesit-forward-list))
(when (treesit-thing-defined-p 'sentence nil)
(setq-local forward-sentence-function #'treesit-forward-sentence))