emacs-diffs
[Top][All Lists]
Advanced

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

master 73a320801e9: Add treesit-node-get


From: Yuan Fu
Subject: master 73a320801e9: Add treesit-node-get
Date: Fri, 31 Mar 2023 00:55:56 -0400 (EDT)

branch: master
commit 73a320801e9af61a48fd0e803afcd02b059b2338
Author: Yuan Fu <casouri@gmail.com>
Commit: Yuan Fu <casouri@gmail.com>

    Add treesit-node-get
    
    * doc/lispref/parsing.texi (Retrieving Nodes): Add manual entry.
    * lisp/treesit.el (treesit-node--get): New function.
---
 doc/lispref/parsing.texi | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 lisp/treesit.el          | 44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 91 insertions(+)

diff --git a/doc/lispref/parsing.texi b/doc/lispref/parsing.texi
index 86a5d9f2e52..38c9ec8c2f0 100644
--- a/doc/lispref/parsing.texi
+++ b/doc/lispref/parsing.texi
@@ -849,6 +849,53 @@ Each node in the returned tree looks like
 
 @heading More convenience functions
 
+@defun treesit-node-get node instructions
+This is a convenience function that chains together multiple node
+accessor functions together.  For example, to get @var{node}'s
+parent's next sibling's second child's text:
+
+@example
+@group
+(treesit-node-get node
+   '((parent 1)
+    (sibling 1 nil)
+    (child 1 nil)
+    (text nil)))
+@end group
+@end example
+
+@var{instruction} is a list of INSTRUCTIONs of the form
+@w{@code{(@var{fn} @var{arg}...)}}.  The following @var{fn}'s are
+supported:
+
+@table @code
+@item (child @var{idx} @var{named})
+Get the @var{idx}'th child.
+
+@item (parent @var{n})
+Go to parent @var{n} times.
+
+@item (field-name)
+Get the field name of the current node.
+
+@item (type)
+Get the type of the current node.
+
+@item (text @var{no-property})
+Get the text of the current node.
+
+@item (children @var{named})
+Get a list of children.
+
+@item (sibling @var{step} @var{named})
+Get the nth prev/next sibling, negative @var{step} means prev sibling,
+positive means next sibling.
+@end table
+
+Note that arguments like @var{named} and @var{no-property} can't be
+omitted, unlike in their original functions.
+@end defun
+
 @defun treesit-filter-child node predicate &optional named
 This function finds immediate children of @var{node} that satisfy
 @var{predicate}.
diff --git a/lisp/treesit.el b/lisp/treesit.el
index e3c7d569ea6..4c4ba4ad6ac 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -363,6 +363,50 @@ If NAMED is non-nil, count named child only."
              (idx (treesit-node-index node)))
     (treesit-node-field-name-for-child parent idx)))
 
+(defun treesit-node-get (node instructions)
+  "Get things from NODE by INSTRUCTIONS.
+
+This is a convenience function that chains together multiple node
+accessor functions together.  For example, to get NODE's parent's
+next sibling's second child's text, call
+
+   (treesit-node-get node
+     \\='((parent 1)
+       (sibling 1 nil)
+       (child 1 nil)
+       (text nil)))
+
+INSTRUCTION is a list of INSTRUCTIONs of the form (FN ARG...).
+The following FN's are supported:
+
+\(child IDX NAMED)    Get the IDX'th child
+\(parent N)           Go to parent N times
+\(field-name)         Get the field name of the current node
+\(type)               Get the type of the current node
+\(text NO-PROPERTY)   Get the text of the current node
+\(children NAMED)     Get a list of children
+\(sibling STEP NAMED) Get the nth prev/next sibling, negative STEP
+                     means prev sibling, positive means next
+
+Note that arguments like NAMED and NO-PROPERTY can't be omitted,
+unlike in their original functions."
+  (declare (indent 1))
+  (while (and node instructions)
+    (pcase (pop instructions)
+      ('(field-name) (setq node (treesit-node-field-name node)))
+      ('(type) (setq node (treesit-node-type node)))
+      (`(child ,idx ,named) (setq node (treesit-node-child node idx named)))
+      (`(parent ,n) (dotimes (_ n)
+                      (setq node (treesit-node-parent node))))
+      (`(text ,no-property) (setq node (treesit-node-text node no-property)))
+      (`(children ,named) (setq node (treesit-node-children node named)))
+      (`(sibling ,step ,named)
+       (dotimes (_ (abs step))
+         (setq node (if (> step 0)
+                        (treesit-node-next-sibling node named)
+                      (treesit-node-prev-sibling node named)))))))
+  node)
+
 ;;; Query API supplement
 
 (defun treesit-query-string (string query language)



reply via email to

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