]> git.eshelyaron.com Git - emacs.git/commitdiff
Further generalize treesit-defun functions
authorYuan Fu <casouri@gmail.com>
Sun, 25 Dec 2022 06:08:17 +0000 (22:08 -0800)
committerYuan Fu <casouri@gmail.com>
Sun, 25 Dec 2022 09:11:47 +0000 (01:11 -0800)
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

index 40e70f47f59dcc41144545fab6ecc3427af498f4..e8e93d09de40d7649384c1a21c9636f65fd70f7b 100644 (file)
@@ -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.