tree_house/
tree_cursor.rs1use std::collections::VecDeque;
2
3use crate::tree_sitter::Node;
4use crate::{Layer, Syntax};
5
6pub struct TreeCursor<'tree> {
7 syntax: &'tree Syntax,
8 current: Layer,
9 cursor: tree_sitter::TreeCursor<'tree>,
10}
11
12impl<'tree> TreeCursor<'tree> {
13 pub(crate) fn new(syntax: &'tree Syntax) -> Self {
14 let cursor = syntax.tree().walk();
15
16 Self {
17 syntax,
18 current: syntax.root,
19 cursor,
20 }
21 }
22
23 pub fn node(&self) -> Node<'tree> {
24 self.cursor.node()
25 }
26
27 pub fn goto_parent(&mut self) -> bool {
28 if self.cursor.goto_parent() {
29 return true;
30 };
31
32 loop {
33 let Some(parent) = self.syntax.layer(self.current).parent else {
35 return false;
36 };
37
38 self.current = parent;
39 if let Some(tree) = self.syntax.layer(self.current).tree() {
40 self.cursor = tree.walk();
41 break;
42 }
43 }
44
45 true
46 }
47
48 pub fn goto_parent_with<P>(&mut self, predicate: P) -> bool
49 where
50 P: Fn(&Node) -> bool,
51 {
52 while self.goto_parent() {
53 if predicate(&self.node()) {
54 return true;
55 }
56 }
57
58 false
59 }
60
61 pub fn goto_first_child(&mut self) -> bool {
62 let range = self.cursor.node().byte_range();
63 let layer = self.syntax.layer(self.current);
64 if let Some((layer, tree)) = layer
65 .injection_at_byte_idx(range.start)
66 .filter(|injection| injection.range.end >= range.end)
67 .and_then(|injection| {
68 Some((injection.layer, self.syntax.layer(injection.layer).tree()?))
69 })
70 {
71 self.current = layer;
73 self.cursor = tree.walk();
74 return true;
75 }
76
77 self.cursor.goto_first_child()
78 }
79
80 pub fn goto_next_sibling(&mut self) -> bool {
81 self.cursor.goto_next_sibling()
82 }
83
84 pub fn goto_previous_sibling(&mut self) -> bool {
85 self.cursor.goto_previous_sibling()
86 }
87
88 pub fn reset_to_byte_range(&mut self, start: u32, end: u32) {
89 let (layer, tree) = self.syntax.layer_and_tree_for_byte_range(start, end);
90 self.current = layer;
91 self.cursor = tree.walk();
92
93 loop {
94 let node = self.cursor.node();
95 if start < node.start_byte() || end > node.end_byte() {
96 self.cursor.goto_parent();
97 break;
98 }
99 if self.cursor.goto_first_child_for_byte(start).is_none() {
100 break;
101 }
102 }
103 }
104
105 pub fn children<'a>(&'a mut self) -> ChildIter<'a, 'tree> {
108 let parent = self.node();
109
110 ChildIter {
111 cursor: self,
112 parent,
113 }
114 }
115}
116
117pub struct ChildIter<'a, 'tree> {
118 cursor: &'a mut TreeCursor<'tree>,
119 parent: Node<'tree>,
120}
121
122impl<'tree> Iterator for ChildIter<'_, 'tree> {
123 type Item = Node<'tree>;
124
125 fn next(&mut self) -> Option<Self::Item> {
126 if self.cursor.node() == self.parent {
128 self.cursor.goto_first_child().then(|| self.cursor.node())
129 } else {
130 self.cursor.goto_next_sibling().then(|| self.cursor.node())
131 }
132 }
133}
134
135impl<'cursor, 'tree> IntoIterator for &'cursor mut TreeCursor<'tree> {
136 type Item = Node<'tree>;
137 type IntoIter = TreeRecursiveWalker<'cursor, 'tree>;
138
139 fn into_iter(self) -> Self::IntoIter {
140 let mut queue = VecDeque::new();
141 let root = self.node();
142 queue.push_back(root.clone());
143
144 TreeRecursiveWalker {
145 cursor: self,
146 queue,
147 root,
148 }
149 }
150}
151
152pub struct TreeRecursiveWalker<'cursor, 'tree> {
153 cursor: &'cursor mut TreeCursor<'tree>,
154 queue: VecDeque<Node<'tree>>,
155 root: Node<'tree>,
156}
157
158impl<'tree> Iterator for TreeRecursiveWalker<'_, 'tree> {
159 type Item = Node<'tree>;
160
161 fn next(&mut self) -> Option<Self::Item> {
162 let current = self.cursor.node();
163
164 if current != self.root && self.cursor.goto_next_sibling() {
165 self.queue.push_back(current);
166 return Some(self.cursor.node());
167 }
168
169 while let Some(queued) = self.queue.pop_front() {
170 self.cursor.cursor.reset(&queued);
171
172 if !self.cursor.goto_first_child() {
173 continue;
174 }
175
176 return Some(self.cursor.node());
177 }
178
179 None
180 }
181}