[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 3db984c72b8 1/3: Add new variable 'forward-list-function' for 'tr
From: |
Juri Linkov |
Subject: |
master 3db984c72b8 1/3: Add new variable 'forward-list-function' for 'treesit-forward-list' |
Date: |
Sun, 29 Dec 2024 12:59:11 -0500 (EST) |
branch: master
commit 3db984c72b8609c84f06a0fd62e59b4823ea0876
Author: Juri Linkov <juri@linkov.net>
Commit: Juri Linkov <juri@linkov.net>
Add new variable 'forward-list-function' for 'treesit-forward-list'
* lisp/emacs-lisp/lisp.el (forward-list-default-function): New function.
(forward-list-function): New variable (bug#73404).
(forward-list): Move meat to 'forward-list-default-function',
and call 'forward-list-function' when non-nil.
* lisp/treesit.el (treesit-forward-list): Rewrite to not rely on
'treesit-forward-sexp'.
(treesit-major-mode-setup): Set 'forward-list-function' to
'treesit-forward-list'.
---
etc/NEWS | 5 +++++
lisp/emacs-lisp/lisp.el | 14 +++++++++++++-
lisp/treesit.el | 51 +++++++++++++++++++++++++++++--------------------
3 files changed, 48 insertions(+), 22 deletions(-)
diff --git a/etc/NEWS b/etc/NEWS
index ed17a7a2bb9..a66899e83e0 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1002,6 +1002,11 @@ The new function 'treesit-forward-sexp-list' uses
'sexp-list'
to move across lists. But to move across atoms inside the list
it uses `forward-sexp-default-function'.
+*** New function 'treesit-forward-list'.
+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-language-display-name'.
This new function returns the display name of a language given the
diff --git a/lisp/emacs-lisp/lisp.el b/lisp/emacs-lisp/lisp.el
index c9e27e78c33..e45064a459b 100644
--- a/lisp/emacs-lisp/lisp.el
+++ b/lisp/emacs-lisp/lisp.el
@@ -143,6 +143,14 @@ This command assumes point is not in a string or comment."
(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
@@ -150,6 +158,7 @@ defined by the current language mode.
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")
@@ -160,7 +169,9 @@ report errors as appropriate for this kind of usage."
"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.
@@ -169,6 +180,7 @@ defined by the current language mode.
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")
diff --git a/lisp/treesit.el b/lisp/treesit.el
index eb3e26fff7e..7ded154eba8 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -2420,29 +2420,10 @@ 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-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'.
@@ -2541,6 +2522,33 @@ ARG is described in the docstring of
`forward-sexp-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'.
@@ -3465,7 +3473,8 @@ before calling this function."
(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))