Add new variable 'down-list-function' for 'treesit-down-list'
* lisp/emacs-lisp/lisp.el (down-list-default-function): New function. (down-list-function): New variable (bug#73404). (down-list): Move meat to 'down-list-default-function', and call 'down-list-function' when non-nil. Don't raise an error in strings or comments when 'down-list-function' is non-nil. * lisp/treesit.el (treesit--scan-error): New internal function. (treesit-forward-sexp, treesit-forward-list): Use 'treesit--scan-error'. (treesit-down-list): New function. (treesit-major-mode-setup): Set 'down-list-function' to 'treesit-down-list'.
This commit is contained in:
parent
3db984c72b
commit
3c50edb2b5
3 changed files with 60 additions and 20 deletions
5
etc/NEWS
5
etc/NEWS
|
@ -1007,6 +1007,11 @@ Tree-sitter conditionally sets 'forward-list-function' for major modes
|
|||
that have defined 'sexp-list' in 'treesit-thing-settings' to enable
|
||||
the 'forward-list' motion command.
|
||||
|
||||
*** New function 'treesit-down-list'.
|
||||
Tree-sitter conditionally sets 'down-list-function' for major modes
|
||||
that have defined 'sexp-list' in 'treesit-thing-settings' to enable
|
||||
the 'down-list' motion command.
|
||||
|
||||
+++
|
||||
*** New function 'treesit-language-display-name'.
|
||||
This new function returns the display name of a language given the
|
||||
|
|
|
@ -187,6 +187,17 @@ report errors as appropriate for this kind of usage."
|
|||
(or arg (setq arg 1))
|
||||
(forward-list (- arg) interactive))
|
||||
|
||||
(defun down-list-default-function (&optional arg)
|
||||
"Default function for `down-list-function'."
|
||||
(let ((inc (if (> arg 0) 1 -1)))
|
||||
(while (/= arg 0)
|
||||
(goto-char (or (scan-lists (point) inc -1) (buffer-end arg)))
|
||||
(setq arg (- arg inc)))))
|
||||
|
||||
(defvar down-list-function nil
|
||||
"If non-nil, `down-list' delegates to this function.
|
||||
Should take the same arguments and behave similarly to `down-list'.")
|
||||
|
||||
(defun down-list (&optional arg interactive)
|
||||
"Move forward down one level of parentheses.
|
||||
This command will also work on other parentheses-like expressions
|
||||
|
@ -194,20 +205,21 @@ defined by the current language mode.
|
|||
With ARG, do this that many times.
|
||||
A negative argument means move backward but still go down a level.
|
||||
This command assumes point is not in a string or comment.
|
||||
Calls `down-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")
|
||||
(when (ppss-comment-or-string-start (syntax-ppss))
|
||||
(when (and (null down-list-function)
|
||||
(ppss-comment-or-string-start (syntax-ppss)))
|
||||
(user-error "This command doesn't work in strings or comments"))
|
||||
(if interactive
|
||||
(condition-case _
|
||||
(down-list arg nil)
|
||||
(scan-error (user-error "At bottom level")))
|
||||
(or arg (setq arg 1))
|
||||
(let ((inc (if (> arg 0) 1 -1)))
|
||||
(while (/= arg 0)
|
||||
(goto-char (or (scan-lists (point) inc -1) (buffer-end arg)))
|
||||
(setq arg (- arg inc))))))
|
||||
(if down-list-function
|
||||
(funcall down-list-function arg)
|
||||
(down-list-default-function arg))))
|
||||
|
||||
(defun backward-up-list (&optional arg escape-strings no-syntax-crossing)
|
||||
"Move backward out of one level of parentheses.
|
||||
|
|
|
@ -2420,6 +2420,13 @@ delimits medium sized statements in the source code. It is,
|
|||
however, smaller in scope than sentences. This is used by
|
||||
`treesit-forward-sexp' and friends.")
|
||||
|
||||
(defun treesit--scan-error (pred arg)
|
||||
(when-let* ((parent (treesit-thing-at (point) pred t))
|
||||
(boundary (treesit-node-child parent (if (> arg 0) -1 0))))
|
||||
(signal 'scan-error (list (format-message "No more %S to move across" pred)
|
||||
(treesit-node-start boundary)
|
||||
(treesit-node-end boundary)))))
|
||||
|
||||
(defun treesit-forward-sexp (&optional arg)
|
||||
"Tree-sitter implementation for `forward-sexp-function'.
|
||||
|
||||
|
@ -2460,13 +2467,7 @@ across atoms (such as symbols or words) inside the list."
|
|||
;; the obstacle, like `forward-sexp' does. If we couldn't
|
||||
;; find a parent, we simply return nil without moving point,
|
||||
;; then functions like `up-list' will signal "at top level".
|
||||
(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 sexp to move across"
|
||||
(treesit-node-start boundary)
|
||||
(treesit-node-end boundary)))))))
|
||||
(treesit--scan-error pred arg))))
|
||||
|
||||
(defun treesit-forward-sexp-list (&optional arg)
|
||||
"Alternative tree-sitter implementation for `forward-sexp-function'.
|
||||
|
@ -2541,13 +2542,34 @@ ARG is described in the docstring of `forward-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)))))))
|
||||
(treesit--scan-error pred arg))))
|
||||
|
||||
(defun treesit-down-list (&optional arg)
|
||||
"Move forward down 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 `down-list'
|
||||
redefined by the variable `down-list-function'.
|
||||
|
||||
ARG is described in the docstring of `down-list'."
|
||||
(interactive "^p")
|
||||
(let* ((pred 'sexp-list)
|
||||
(arg (or arg 1))
|
||||
(inc (if (> arg 0) 1 -1)))
|
||||
(while (/= arg 0)
|
||||
(let* ((node (if (> arg 0)
|
||||
(treesit-thing-next (point) pred)
|
||||
(treesit-thing-prev (point) pred)))
|
||||
(child (when node
|
||||
(treesit-node-child node (if (> arg 0) 0 -1))))
|
||||
(pos (when child
|
||||
(if (> arg 0)
|
||||
(treesit-node-end child)
|
||||
(treesit-node-start child)))))
|
||||
(if pos (goto-char pos) (treesit--scan-error pred arg)))
|
||||
(setq arg (- arg inc)))))
|
||||
|
||||
(defun treesit-transpose-sexps (&optional arg)
|
||||
"Tree-sitter `transpose-sexps' function.
|
||||
|
@ -3474,7 +3496,8 @@ before calling this function."
|
|||
|
||||
(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 forward-list-function #'treesit-forward-list)
|
||||
(setq-local down-list-function #'treesit-down-list))
|
||||
|
||||
(when (treesit-thing-defined-p 'sentence nil)
|
||||
(setq-local forward-sentence-function #'treesit-forward-sentence))
|
||||
|
|
Loading…
Add table
Reference in a new issue