Skip to content

Commit a2119cb

Browse files
committed
Add APIs for retrieving tree cursor's depth and descendant index
1 parent 9dd725b commit a2119cb

File tree

6 files changed

+47
-28
lines changed

6 files changed

+47
-28
lines changed

lib/binding_rust/bindings.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,12 @@ extern "C" {
615615
extern "C" {
616616
#[doc = " Get the index of the cursor's current node out of all of the"]
617617
#[doc = " descendants of the original node that the cursor was constructed with."]
618-
pub fn ts_tree_cursor_descendant_index(arg1: *mut TSTreeCursor) -> u32;
618+
pub fn ts_tree_cursor_current_descendant_index(arg1: *const TSTreeCursor) -> u32;
619+
}
620+
extern "C" {
621+
#[doc = " Get the depth of the cursor's current node relative to the original"]
622+
#[doc = " node that the cursor was constructed with."]
623+
pub fn ts_tree_cursor_current_depth(arg1: *const TSTreeCursor) -> u32;
619624
}
620625
extern "C" {
621626
#[doc = " Move the cursor to the first child of its current node that extends beyond"]

lib/binding_rust/lib.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,6 +1266,21 @@ impl<'a> TreeCursor<'a> {
12661266
}
12671267
}
12681268

1269+
/// Get the numerical field id of this tree cursor's current node.
1270+
///
1271+
/// See also [field_name](TreeCursor::field_name).
1272+
#[doc(alias = "ts_tree_cursor_current_depth")]
1273+
pub fn depth(&self) -> u32 {
1274+
unsafe { ffi::ts_tree_cursor_current_depth(&self.0) }
1275+
}
1276+
1277+
/// Get the index of the cursor's current node out of all of the
1278+
/// descendants of the original node that the cursor was constructed with
1279+
#[doc(alias = "ts_tree_cursor_current_descendant_index")]
1280+
pub fn descendant_index(&self) -> usize {
1281+
unsafe { ffi::ts_tree_cursor_current_descendant_index(&self.0) as usize }
1282+
}
1283+
12691284
/// Move this cursor to the first child of its current node.
12701285
///
12711286
/// This returns `true` if the cursor successfully moved, and returns `false`

lib/binding_web/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ WebAssembly bindings to the [Tree-sitter](https://github.com/tree-sitter/tree-si
1212
You can download the `tree-sitter.js` and `tree-sitter.wasm` files from [the latest GitHub release](https://github.com/tree-sitter/tree-sitter/releases/latest) and load them using a standalone script:
1313

1414
```html
15-
<script src="/the/path/to/tree-sitter.js"/>
15+
<script src="/the/path/to/tree-sitter.js"></script>
1616

1717
<script>
1818
const Parser = window.TreeSitter;

lib/include/tree_sitter/api.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,13 @@ void ts_tree_cursor_goto_descendant(TSTreeCursor *, uint32_t);
689689
* Get the index of the cursor's current node out of all of the
690690
* descendants of the original node that the cursor was constructed with.
691691
*/
692-
uint32_t ts_tree_cursor_descendant_index(TSTreeCursor *);
692+
uint32_t ts_tree_cursor_current_descendant_index(const TSTreeCursor *);
693+
694+
/**
695+
* Get the depth of the cursor's current node relative to the original
696+
* node that the cursor was constructed with.
697+
*/
698+
uint32_t ts_tree_cursor_current_depth(const TSTreeCursor *);
693699

694700
/**
695701
* Move the cursor to the first child of its current node that extends beyond

lib/src/tree_cursor.c

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -261,22 +261,10 @@ bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *self) {
261261
bool ts_tree_cursor_goto_parent(TSTreeCursor *_self) {
262262
TreeCursor *self = (TreeCursor *)_self;
263263
for (unsigned i = self->stack.size - 2; i + 1 > 0; i--) {
264-
TreeCursorEntry *entry = &self->stack.contents[i];
265-
if (ts_subtree_visible(*entry->subtree)) {
264+
if (ts_tree_cursor_is_entry_visible(self, i)) {
266265
self->stack.size = i + 1;
267266
return true;
268267
}
269-
if (i > 0 && !ts_subtree_extra(*entry->subtree)) {
270-
TreeCursorEntry *parent_entry = &self->stack.contents[i - 1];
271-
if (ts_language_alias_at(
272-
self->tree->language,
273-
parent_entry->subtree->ptr->production_id,
274-
entry->structural_child_index
275-
)) {
276-
self->stack.size = i + 1;
277-
return true;
278-
}
279-
}
280268
}
281269
return false;
282270
}
@@ -331,7 +319,7 @@ void ts_tree_cursor_goto_descendant(
331319
} while (did_descend);
332320
}
333321

334-
uint32_t ts_tree_cursor_descendant_index(TSTreeCursor *_self) {
322+
uint32_t ts_tree_cursor_current_descendant_index(const TSTreeCursor *_self) {
335323
const TreeCursor *self = (const TreeCursor *)_self;
336324
TreeCursorEntry *last_entry = array_back(&self->stack);
337325
return last_entry->descendant_index;
@@ -479,6 +467,17 @@ void ts_tree_cursor_current_status(
479467
}
480468
}
481469

470+
uint32_t ts_tree_cursor_current_depth(const TSTreeCursor *_self) {
471+
const TreeCursor *self = (const TreeCursor *)_self;
472+
uint32_t depth = 0;
473+
for (unsigned i = 1; i < self->stack.size; i++) {
474+
if (ts_tree_cursor_is_entry_visible(self, i)) {
475+
depth++;
476+
}
477+
}
478+
return depth;
479+
}
480+
482481
TSNode ts_tree_cursor_parent_node(const TSTreeCursor *_self) {
483482
const TreeCursor *self = (const TreeCursor *)_self;
484483
for (int i = (int)self->stack.size - 2; i >= 0; i--) {
@@ -515,17 +514,10 @@ TSFieldId ts_tree_cursor_current_field_id(const TSTreeCursor *_self) {
515514
TreeCursorEntry *parent_entry = &self->stack.contents[i - 1];
516515

517516
// Stop walking up when another visible node is found.
518-
if (i != self->stack.size - 1) {
519-
if (ts_subtree_visible(*entry->subtree)) break;
520-
if (
521-
!ts_subtree_extra(*entry->subtree) &&
522-
ts_language_alias_at(
523-
self->tree->language,
524-
parent_entry->subtree->ptr->production_id,
525-
entry->structural_child_index
526-
)
527-
) break;
528-
}
517+
if (
518+
i != self->stack.size - 1 &&
519+
ts_tree_cursor_is_entry_visible(self, i)
520+
) break;
529521

530522
if (ts_subtree_extra(*entry->subtree)) break;
531523

script/generate-bindings

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ output_path=lib/binding_rust/bindings.rs
44
header_path='lib/include/tree_sitter/api.h'
55

66
bindgen \
7+
--size_t-is-usize \
78
--no-layout-tests \
89
--allowlist-type '^TS.*' \
910
--allowlist-function '^ts_.*' \

0 commit comments

Comments
 (0)