summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2023-01-30 21:19:55 +0800
committerPo Lu <luangruo@yahoo.com>2023-01-30 21:19:55 +0800
commit46e8ab23eaeb5e453042f430fc016cf9ffc2ac37 (patch)
treee01b8db7b92c7e823b0957f4c3cd5db7a68fef23 /src
parentf69583941c873506b017bd5f5a81a3dfe15d7e22 (diff)
parent3f069bd796b0024033640051b5f74ba9834985f8 (diff)
Merge remote-tracking branch 'origin/master' into feature/android
Diffstat (limited to 'src')
-rw-r--r--src/comp.c3
-rw-r--r--src/treesit.c63
2 files changed, 63 insertions, 3 deletions
diff --git a/src/comp.c b/src/comp.c
index 6ff1915ef5b..ba549155925 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -5912,6 +5912,3 @@ file -> CU. */);
defsubr (&Snative_comp_available_p);
}
-/* Local Variables: */
-/* c-file-offsets: ((arglist-intro . +)) */
-/* End: */
diff --git a/src/treesit.c b/src/treesit.c
index 917db582676..b210ec0923a 100644
--- a/src/treesit.c
+++ b/src/treesit.c
@@ -3312,6 +3312,68 @@ a regexp. */)
return parent;
}
+DEFUN ("treesit-subtree-stat",
+ Ftreesit_subtree_stat,
+ Streesit_subtree_stat, 1, 1, 0,
+ doc: /* Return information about the subtree of NODE.
+
+Return a list (MAX-DEPTH MAX-WIDTH COUNT), where MAX-DEPTH is the
+maximum depth of the subtree, MAX-WIDTH is the maximum number of
+direct children of nodes in the subtree, and COUNT is the number of
+nodes in the subtree, including NODE. */)
+ (Lisp_Object node)
+{
+ /* Having a limit on the depth to traverse doesn't have much impact
+ on the time it takes, so I left that out. */
+ CHECK_TS_NODE (node);
+
+ treesit_initialize ();
+
+ TSTreeCursor cursor = ts_tree_cursor_new (XTS_NODE (node)->node);
+ ptrdiff_t max_depth = 1;
+ ptrdiff_t max_width = 0;
+ ptrdiff_t count = 0;
+ ptrdiff_t current_depth = 0;
+
+ /* Traverse the subtree depth-first. */
+ while (true)
+ {
+ count++;
+
+ /* Go down depth-first. */
+ while (ts_tree_cursor_goto_first_child (&cursor))
+ {
+ current_depth++;
+ count++;
+ /* While we're at here, measure the number of siblings. */
+ ptrdiff_t width_count = 1;
+ while (ts_tree_cursor_goto_next_sibling (&cursor))
+ width_count++;
+ max_width = max (max_width, width_count);
+ /* Go back to the first sibling. */
+ treesit_assume_true (ts_tree_cursor_goto_parent (&cursor));
+ treesit_assume_true (ts_tree_cursor_goto_first_child (&cursor));
+ }
+ max_depth = max (max_depth, current_depth);
+
+ /* Go to next sibling. If there is no next sibling, go to
+ parent's next sibling, and so on. If there is no more
+ parent, we've traversed the whole subtree, stop. */
+ while (!ts_tree_cursor_goto_next_sibling (&cursor))
+ {
+ if (ts_tree_cursor_goto_parent (&cursor))
+ current_depth--;
+ else
+ {
+ ts_tree_cursor_delete (&cursor);
+ return list3 (make_fixnum (max_depth),
+ make_fixnum (max_width),
+ make_fixnum (count));
+ }
+ }
+ }
+}
+
#endif /* HAVE_TREE_SITTER */
DEFUN ("treesit-available-p", Ftreesit_available_p,
@@ -3511,6 +3573,7 @@ then in the system default locations for dynamic libraries, in that order. */);
defsubr (&Streesit_search_subtree);
defsubr (&Streesit_search_forward);
defsubr (&Streesit_induce_sparse_tree);
+ defsubr (&Streesit_subtree_stat);
#endif /* HAVE_TREE_SITTER */
defsubr (&Streesit_available_p);
}