[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
emacs-29 79584a206b 2/5: Further generalize treesit-defun functions
From: |
Yuan Fu |
Subject: |
emacs-29 79584a206b 2/5: Further generalize treesit-defun functions |
Date: |
Sun, 25 Dec 2022 04:11:59 -0500 (EST) |
branch: emacs-29
commit 79584a206b9b36e4937c32845464bfc9b438dade
Author: Yuan Fu <casouri@gmail.com>
Commit: Yuan Fu <casouri@gmail.com>
Further generalize treesit-defun functions
Two new functions, treesit-beginning/end-of-thing. And
treesit-thing-at-point's signature changes.
* lisp/treesit.el (treesit-block-type-regexp): New variable.
(treesit-beginning-of-thing)
(treesit-end-of-thing): Generalized from
treesit-beginning/end-of-defun.
(treesit-beginning-of-defun)
(treesit-end-of-defun): Use the new functions.
(treesit-thing-at-point): Accept PATTERN rather than REGEXP and PRED.
(treesit-defun-at-point): Adjust for the new signature of
treesit-thing-at-point.
---
lisp/treesit.el | 82 ++++++++++++++++++++++++++++++++++++---------------------
1 file changed, 52 insertions(+), 30 deletions(-)
diff --git a/lisp/treesit.el b/lisp/treesit.el
index 40e70f47f5..e8e93d09de 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -1582,7 +1582,7 @@ BACKWARD and ALL are the same as in
`treesit-search-forward'."
(goto-char current-pos)))
node))
-;;; Navigation
+;;; Navigation, defun, things
(defvar-local treesit-defun-type-regexp nil
"A regexp that matches the node type of defun nodes.
@@ -1596,6 +1596,9 @@ for invalid node.
This is used by `treesit-beginning-of-defun' and friends.")
+(defvar-local treesit-block-type-regexp nil
+ "Like `treesit-defun-type-regexp', but for blocks.")
+
(defvar-local treesit-defun-tactic 'nested
"Determines how does Emacs treat nested defuns.
If the value is `top-level', Emacs only moves across top-level
@@ -1632,6 +1635,36 @@ Basically,
pattern
(cons pattern nil)))
+(defun treesit-beginning-of-thing (pattern &optional arg)
+ "Like `beginning-of-defun', but generalized into things.
+
+PATTERN is like `treesit-defun-type-regexp', ARG
+is the same as in `beginning-of-defun'.
+
+Return non-nil if successfully moved, nil otherwise."
+ (pcase-let* ((arg (or arg 1))
+ (`(,regexp . ,pred) (treesit--thing-unpack-pattern
+ pattern))
+ (dest (treesit--navigate-thing
+ (point) (- arg) 'beg regexp pred)))
+ (when dest
+ (goto-char dest))))
+
+(defun treesit-end-of-thing (pattern &optional arg)
+ "Like `end-of-defun', but generalized into things.
+
+PATTERN is like `treesit-defun-type-regexp', ARG is the same as
+in `end-of-defun'.
+
+Return non-nil if successfully moved, nil otherwise."
+ (pcase-let* ((arg (or arg 1))
+ (`(,regexp . ,pred) (treesit--thing-unpack-pattern
+ pattern))
+ (dest (treesit--navigate-thing
+ (point) arg 'end regexp pred)))
+ (when dest
+ (goto-char dest))))
+
(defun treesit-beginning-of-defun (&optional arg)
"Move backward to the beginning of a defun.
@@ -1644,16 +1677,10 @@ This is a tree-sitter equivalent of
`beginning-of-defun'.
Behavior of this function depends on `treesit-defun-type-regexp'
and `treesit-defun-skipper'."
(interactive "^p")
- (pcase-let* ((arg (or arg 1))
- (`(,regexp . ,pred)
- (treesit--thing-unpack-pattern treesit-defun-type-regexp))
- (dest (treesit--navigate-thing
- (point) (- arg) 'beg regexp pred)))
- (when dest
- (goto-char dest)
- (when treesit-defun-skipper
- (funcall treesit-defun-skipper))
- t)))
+ (when (treesit-beginning-of-thing treesit-defun-type-regexp arg)
+ (when treesit-defun-skipper
+ (funcall treesit-defun-skipper))
+ t))
(defun treesit-end-of-defun (&optional arg _)
"Move forward to next end of defun.
@@ -1665,15 +1692,9 @@ This is a tree-sitter equivalent of `end-of-defun'.
Behavior of
this function depends on `treesit-defun-type-regexp' and
`treesit-defun-skipper'."
(interactive "^p\nd")
- (pcase-let* ((arg (or arg 1))
- (`(,regexp . ,pred)
- (treesit--thing-unpack-pattern treesit-defun-type-regexp))
- (dest (treesit--navigate-thing
- (point) arg 'end regexp pred)))
- (when dest
- (goto-char dest)
- (when treesit-defun-skipper
- (funcall treesit-defun-skipper)))))
+ (when (treesit-end-of-thing treesit-defun-type-regexp arg)
+ (when treesit-defun-skipper
+ (funcall treesit-defun-skipper))))
(defun treesit-default-defun-skipper ()
"Skips spaces after navigating a defun.
@@ -1890,17 +1911,20 @@ function is called recursively."
(if (eq counter 0) pos nil)))
;; TODO: In corporate into thing-at-point.
-(defun treesit-thing-at-point (regexp tactic &optional pred)
+(defun treesit-thing-at-point (pattern tactic)
"Return the thing node at point or nil if none is found.
-\"Thing\" is defined by REGEXP: if a node's type matches REGEXP,
-it is a thing. The \"thing\" could be further restricted by
-PRED: if non-nil, PRED should be a function that takes a node and
-returns t if the node is a \"thing\", and nil if not.
+\"Thing\" is defined by PATTERN, which can be either a string
+REGEXP or a cons cell (REGEXP . PRED): if a node's type matches
+REGEXP, it is a thing. The \"thing\" could be further restricted
+by PRED: if non-nil, PRED should be a function that takes a node
+and returns t if the node is a \"thing\", and nil if not.
Return the top-level defun if TACTIC is `top-level', return the
immediate parent thing if TACTIC is `nested'."
- (pcase-let* ((`(,_ ,next ,parent)
+ (pcase-let* ((`(,regexp . ,pred)
+ (treesit--thing-unpack-pattern pattern))
+ (`(,_ ,next ,parent)
(treesit--things-around (point) regexp pred))
;; If point is at the beginning of a thing, we
;; prioritize that thing over the parent in nested
@@ -1921,10 +1945,8 @@ is `top-level', return the immediate parent defun if it
is
Return nil if `treesit-defun-type-regexp' is not set."
(when treesit-defun-type-regexp
- (pcase-let ((`(,regexp . ,pred)
- (treesit--thing-unpack-pattern
- treesit-defun-type-regexp)))
- (treesit-thing-at-point regexp treesit-defun-tactic pred))))
+ (treesit-thing-at-point
+ treesit-defun-type-regexp treesit-defun-tactic)))
(defun treesit-defun-name (node)
"Return the defun name of NODE.