aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
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. */);
5912 5912
5913 defsubr (&Snative_comp_available_p); 5913 defsubr (&Snative_comp_available_p);
5914} 5914}
5915/* Local Variables: */
5916/* c-file-offsets: ((arglist-intro . +)) */
5917/* 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. */)
3312 return parent; 3312 return parent;
3313} 3313}
3314 3314
3315DEFUN ("treesit-subtree-stat",
3316 Ftreesit_subtree_stat,
3317 Streesit_subtree_stat, 1, 1, 0,
3318 doc: /* Return information about the subtree of NODE.
3319
3320Return a list (MAX-DEPTH MAX-WIDTH COUNT), where MAX-DEPTH is the
3321maximum depth of the subtree, MAX-WIDTH is the maximum number of
3322direct children of nodes in the subtree, and COUNT is the number of
3323nodes in the subtree, including NODE. */)
3324 (Lisp_Object node)
3325{
3326 /* Having a limit on the depth to traverse doesn't have much impact
3327 on the time it takes, so I left that out. */
3328 CHECK_TS_NODE (node);
3329
3330 treesit_initialize ();
3331
3332 TSTreeCursor cursor = ts_tree_cursor_new (XTS_NODE (node)->node);
3333 ptrdiff_t max_depth = 1;
3334 ptrdiff_t max_width = 0;
3335 ptrdiff_t count = 0;
3336 ptrdiff_t current_depth = 0;
3337
3338 /* Traverse the subtree depth-first. */
3339 while (true)
3340 {
3341 count++;
3342
3343 /* Go down depth-first. */
3344 while (ts_tree_cursor_goto_first_child (&cursor))
3345 {
3346 current_depth++;
3347 count++;
3348 /* While we're at here, measure the number of siblings. */
3349 ptrdiff_t width_count = 1;
3350 while (ts_tree_cursor_goto_next_sibling (&cursor))
3351 width_count++;
3352 max_width = max (max_width, width_count);
3353 /* Go back to the first sibling. */
3354 treesit_assume_true (ts_tree_cursor_goto_parent (&cursor));
3355 treesit_assume_true (ts_tree_cursor_goto_first_child (&cursor));
3356 }
3357 max_depth = max (max_depth, current_depth);
3358
3359 /* Go to next sibling. If there is no next sibling, go to
3360 parent's next sibling, and so on. If there is no more
3361 parent, we've traversed the whole subtree, stop. */
3362 while (!ts_tree_cursor_goto_next_sibling (&cursor))
3363 {
3364 if (ts_tree_cursor_goto_parent (&cursor))
3365 current_depth--;
3366 else
3367 {
3368 ts_tree_cursor_delete (&cursor);
3369 return list3 (make_fixnum (max_depth),
3370 make_fixnum (max_width),
3371 make_fixnum (count));
3372 }
3373 }
3374 }
3375}
3376
3315#endif /* HAVE_TREE_SITTER */ 3377#endif /* HAVE_TREE_SITTER */
3316 3378
3317DEFUN ("treesit-available-p", Ftreesit_available_p, 3379DEFUN ("treesit-available-p", Ftreesit_available_p,
@@ -3511,6 +3573,7 @@ then in the system default locations for dynamic libraries, in that order. */);
3511 defsubr (&Streesit_search_subtree); 3573 defsubr (&Streesit_search_subtree);
3512 defsubr (&Streesit_search_forward); 3574 defsubr (&Streesit_search_forward);
3513 defsubr (&Streesit_induce_sparse_tree); 3575 defsubr (&Streesit_induce_sparse_tree);
3576 defsubr (&Streesit_subtree_stat);
3514#endif /* HAVE_TREE_SITTER */ 3577#endif /* HAVE_TREE_SITTER */
3515 defsubr (&Streesit_available_p); 3578 defsubr (&Streesit_available_p);
3516} 3579}