emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 293029458c8 2/7: Make use of the new pred shapes in treesit.el


From: Yuan Fu
Subject: master 293029458c8 2/7: Make use of the new pred shapes in treesit.el
Date: Fri, 14 Apr 2023 20:04:47 -0400 (EDT)

branch: master
commit 293029458c87d6ec18a6f6a5958d0b499310ca3b
Author: Yuan Fu <casouri@gmail.com>
Commit: Yuan Fu <casouri@gmail.com>

    Make use of the new pred shapes in treesit.el
    
    treesit-search-forward and friends now accept more shapes for PRED,
    make use of it in navigation functions.
    
    * lisp/treesit.el (treesit-node-top-level): Use treesit-node-match-p.
    (treesit--thing-unpack-pattern): Remove function.
    (treesit-beginning-of-thing)
    (treesit-end-of-thing): Remove PRED argument.
    (treesit--things-around): Remove PRED argument, use
    treesit-node-match-p.
    (treesit--top-level-thing): Remove function.
    (treesit--navigate-thing): Remove PRED argument.
    (treesit-thing-at-point): Update docstring, don't unpack PATTERN.
    
    * test/src/treesit-tests.el:
    (treesit--ert-test-defun-navigation): Don't unpack pattern.
---
 lisp/treesit.el           | 86 +++++++++++++++--------------------------------
 test/src/treesit-tests.el |  4 +--
 2 files changed, 28 insertions(+), 62 deletions(-)

diff --git a/lisp/treesit.el b/lisp/treesit.el
index 3932920a962..e7e336f4609 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -88,6 +88,7 @@
 (declare-function treesit-search-forward "treesit.c")
 (declare-function treesit-induce-sparse-tree "treesit.c")
 (declare-function treesit-subtree-stat "treesit.c")
+(declare-function treesit-node-match-p "treesit.c")
 
 (declare-function treesit-available-p "treesit.c")
 
@@ -245,21 +246,19 @@ is nil, try to guess the language at BEG using 
`treesit-language-at'."
 Specifically, return the highest parent of NODE that has the same
 type as it.  If no such parent exists, return nil.
 
-If PRED is non-nil, match each parent's type with PRED as a
-regexp, rather than using NODE's type.  PRED can also be a
-function that takes the node as an argument, and return
-non-nil/nil for match/no match.
+If PRED is non-nil, match each parent's type with PRED rather
+than using NODE's type.  PRED can also be a predicate function,
+and more.  See `treesit-things-definition' for detail.
 
 If INCLUDE-NODE is non-nil, return NODE if it satisfies PRED."
-  (let ((pred (or pred (treesit-node-type node)))
+  (let ((pred (or pred (rx-to-string
+                        `(bos ,(treesit-node-type node) eos))))
         (result nil))
     (cl-loop for cursor = (if include-node node
                             (treesit-node-parent node))
              then (treesit-node-parent cursor)
              while cursor
-             if (if (stringp pred)
-                    (string-match-p pred (treesit-node-type cursor))
-                  (funcall pred cursor))
+             if (treesit-node-match-p cursor pred)
              do (setq result cursor))
     result))
 
@@ -1887,17 +1886,6 @@ nil.")
   "The delimiter used to connect several defun names.
 This is used in `treesit-add-log-current-defun'.")
 
-(defsubst treesit--thing-unpack-pattern (pattern)
-  "Unpack PATTERN in the shape of `treesit-defun-type-regexp'.
-
-Basically,
-
-    (unpack REGEXP) = (REGEXP . nil)
-    (unpack (REGEXP . PRED)) = (REGEXP . PRED)"
-  (if (consp pattern)
-      pattern
-    (cons pattern nil)))
-
 (defun treesit-beginning-of-thing (pattern &optional arg tactic)
   "Like `beginning-of-defun', but generalized into things.
 
@@ -1916,10 +1904,8 @@ should there be one.  If omitted, TACTIC is considered 
to be
 
 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 tactic)))
+                      (point) (- arg) 'beg pattern tactic)))
     (when dest
       (goto-char dest))))
 
@@ -1941,10 +1927,8 @@ should there be one.  If omitted, TACTIC is considered 
to be
 
 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 tactic)))
+                      (point) arg 'end pattern tactic)))
     (when dest
       (goto-char dest))))
 
@@ -2069,7 +2053,7 @@ the current line if the beginning of the defun is 
indented."
 ;; parent:
 ;; 1. node covers pos
 ;; 2. smallest such node
-(defun treesit--things-around (pos regexp &optional pred)
+(defun treesit--things-around (pos regexp)
   "Return the previous, next, and parent thing around POS.
 
 Return a list of (PREV NEXT PARENT), where PREV and NEXT are
@@ -2077,7 +2061,8 @@ previous and next sibling things around POS, and PARENT 
is the
 parent thing surrounding POS.  All of three could be nil if no
 sound things exists.
 
-REGEXP and PRED are the same as in `treesit-thing-at-point'."
+REGEXP can be a regexp, a predicate function, and more.  See
+`treesit-things-definition' for details."
   (let* ((node (treesit-node-at pos))
          (result (list nil nil nil)))
     ;; 1. Find previous and next sibling defuns.
@@ -2100,9 +2085,7 @@ REGEXP and PRED are the same as in 
`treesit-thing-at-point'."
      when node
      do (let ((cursor node)
               (iter-pred (lambda (node)
-                           (and (string-match-p
-                                 regexp (treesit-node-type node))
-                                (or (null pred) (funcall pred node))
+                           (and (treesit-node-match-p node regexp)
                                 (funcall pos-pred node)))))
           ;; Find the node just before/after POS to start searching.
           (save-excursion
@@ -2120,9 +2103,7 @@ REGEXP and PRED are the same as in 
`treesit-thing-at-point'."
     ;; 2. Find the parent defun.
     (let ((cursor (or (nth 0 result) (nth 1 result) node))
           (iter-pred (lambda (node)
-                       (and (string-match-p
-                             regexp (treesit-node-type node))
-                            (or (null pred) (funcall pred node))
+                       (and (treesit-node-match-p node regexp)
                             (not (treesit-node-eq node (nth 0 result)))
                             (not (treesit-node-eq node (nth 1 result)))
                             (< (treesit-node-start node)
@@ -2132,15 +2113,6 @@ REGEXP and PRED are the same as in 
`treesit-thing-at-point'."
             (treesit-parent-until cursor iter-pred)))
     result))
 
-(defun treesit--top-level-thing (node regexp &optional pred)
-  "Return the top-level parent thing of NODE.
-REGEXP and PRED are the same as in `treesit-thing-at-point'."
-  (treesit-node-top-level
-   node (lambda (node)
-          (and (string-match-p regexp (treesit-node-type node))
-               (or (null pred) (funcall pred node))))
-   t))
-
 ;; The basic idea for nested defun navigation is that we first try to
 ;; move across sibling defuns in the same level, if no more siblings
 ;; exist, we move to parents's beg/end, rinse and repeat.  We never
@@ -2168,7 +2140,7 @@ REGEXP and PRED are the same as in 
`treesit-thing-at-point'."
 ;;    -> Obviously we don't want to go to parent's end, instead, we
 ;;       want to go to parent's prev-sibling's end.  Again, we recurse
 ;;       in the function to do that.
-(defun treesit--navigate-thing (pos arg side regexp &optional pred tactic 
recursing)
+(defun treesit--navigate-thing (pos arg side regexp &optional tactic recursing)
   "Navigate thing ARG steps from POS.
 
 If ARG is positive, move forward that many steps, if negative,
@@ -2179,7 +2151,8 @@ This function doesn't actually move point, it just 
returns the
 position it would move to.  If there aren't enough things to move
 across, return nil.
 
-REGEXP and PRED are the same as in `treesit-thing-at-point'.
+REGEXP can be a regexp, a predicate function, and more.  See
+`treesit-things-definition' for detail.
 
 TACTIC determines how does this function move between things.  It
 can be `nested', `top-level', `restricted', or nil.  `nested'
@@ -2208,14 +2181,13 @@ function is called recursively."
       (while (> counter 0)
         (pcase-let
             ((`(,prev ,next ,parent)
-              (treesit--things-around pos regexp pred)))
+              (treesit--things-around pos regexp)))
           ;; When PARENT is nil, nested and top-level are the same, if
           ;; there is a PARENT, make PARENT to be the top-level parent
           ;; and pretend there is no nested PREV and NEXT.
           (when (and (eq tactic 'top-level)
                      parent)
-            (setq parent (treesit--top-level-thing
-                          parent regexp pred)
+            (setq parent (treesit-node-top-level parent regexp t)
                   prev nil
                   next nil))
           ;; If TACTIC is `restricted', the implementation is very simple.
@@ -2247,7 +2219,7 @@ function is called recursively."
                     ;; the end of next before recurring.)
                     (setq pos (or (treesit--navigate-thing
                                    (treesit-node-end (or next parent))
-                                   1 'beg regexp pred tactic t)
+                                   1 'beg regexp tactic t)
                                   (throw 'term nil)))
                   ;; Normal case.
                   (setq pos (funcall advance (or next parent))))
@@ -2259,7 +2231,7 @@ function is called recursively."
                   ;; Special case: go to prev end-of-defun.
                   (setq pos (or (treesit--navigate-thing
                                  (treesit-node-start (or prev parent))
-                                 -1 'end regexp pred tactic t)
+                                 -1 'end regexp tactic t)
                                 (throw 'term nil)))
                 ;; Normal case.
                 (setq pos (funcall advance (or prev parent))))))
@@ -2272,18 +2244,14 @@ function is called recursively."
 (defun treesit-thing-at-point (pattern tactic)
   "Return the thing node at point or nil if none is found.
 
-\"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.
+\"Thing\" is defined by PATTERN, which can be a regexp, a
+predication function, and more, see `treesit-things-definition'
+for detail.
 
 Return the top-level defun if TACTIC is `top-level', return the
 immediate parent thing if TACTIC is `nested'."
-  (pcase-let* ((`(,regexp . ,pred)
-                (treesit--thing-unpack-pattern pattern))
-               (`(,_ ,next ,parent)
-                (treesit--things-around (point) regexp pred))
+  (pcase-let* ((`(,_ ,next ,parent)
+                (treesit--things-around (point) pattern))
                ;; If point is at the beginning of a thing, we
                ;; prioritize that thing over the parent in nested
                ;; mode.
@@ -2291,7 +2259,7 @@ immediate parent thing if TACTIC is `nested'."
                               next)
                          parent)))
     (if (eq tactic 'top-level)
-        (treesit--top-level-thing node regexp pred)
+        (treesit-node-top-level node pattern t)
       node)))
 
 (defun treesit-defun-at-point ()
diff --git a/test/src/treesit-tests.el b/test/src/treesit-tests.el
index ecdee3c26e4..5b2955c34e3 100644
--- a/test/src/treesit-tests.el
+++ b/test/src/treesit-tests.el
@@ -916,8 +916,6 @@ and \"]\"."
                    collect
                    (cl-loop for pos in record
                             collect (alist-get pos marker-alist))))
-         (`(,regexp . ,pred) (treesit--thing-unpack-pattern
-                              treesit-defun-type-regexp))
          ;; Collect positions each function returns.
          (positions
           (treesit--ert-collect-positions
@@ -929,7 +927,7 @@ and \"]\"."
                        (if-let ((pos (funcall
                                       #'treesit--navigate-thing
                                       (point) (car conf) (cdr conf)
-                                      regexp pred tactic)))
+                                      treesit-defun-type-regexp tactic)))
                            (save-excursion
                              (goto-char pos)
                              (funcall treesit-defun-skipper)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]