@@ -13,6 +13,27 @@ use crate::{
1313 lang:: Language ,
1414} ;
1515
16+ emacs:: use_symbols! {
17+ wrong_type_argument
18+ tree_or_node_p
19+
20+ _type => ":type"
21+ _named_p => ":named-p"
22+ _extra_p => ":extra-p"
23+ _error_p => ":error-p"
24+ _missing_p => ":missing-p"
25+ _has_error_p => ":has-error-p"
26+ _start_byte => ":start-byte"
27+ _start_point => ":start-point"
28+ _end_byte => ":end-byte"
29+ _end_point => ":end-point"
30+ _range => ":range"
31+ _byte_range => ":byte-range"
32+
33+ _field => ":field"
34+ _depth => ":depth"
35+ }
36+
1637// -------------------------------------------------------------------------------------------------
1738
1839/// Wrapper around `tree_sitter::TreeCursor` that can have 'static lifetime, by keeping a
@@ -89,8 +110,6 @@ impl RCursor {
89110 }
90111}
91112
92- // -------------------------------------------------------------------------------------------------
93-
94113pub enum TreeOrNode < ' e > {
95114 Tree ( & ' e Shared < Tree > ) ,
96115 Node ( & ' e RefCell < RNode > ) ,
@@ -120,6 +139,8 @@ impl<'e> TreeOrNode<'e> {
120139 }
121140}
122141
142+ // -------------------------------------------------------------------------------------------------
143+
123144/// Create a new cursor starting from the given TREE-OR-NODE.
124145///
125146/// A cursor allows you to walk a syntax tree more efficiently than is possible
@@ -138,34 +159,69 @@ fn current_node(cursor: &RCursor) -> Result<RNode> {
138159 Ok ( RNode :: new ( cursor. clone_tree ( ) , |_| cursor. borrow ( ) . node ( ) ) )
139160}
140161
141- emacs:: use_symbols! {
142- wrong_type_argument
143- tree_or_node_p
162+ /// Return the field id of CURSOR's current node.
163+ /// Return nil if the current node doesn't have a field.
164+ #[ defun]
165+ fn current_field_id ( cursor : & RCursor ) -> Result < Option < u16 > > {
166+ Ok ( cursor. borrow ( ) . field_id ( ) )
167+ }
144168
145- _type => ":type"
146- _named_p => ":named-p"
147- _extra_p => ":extra-p"
148- _error_p => ":error-p"
149- _missing_p => ":missing-p"
150- _has_error_p => ":has-error-p"
151- _start_byte => ":start-byte"
152- _start_point => ":start-point"
153- _end_byte => ":end-byte"
154- _end_point => ":end-point"
155- _range => ":range"
156- _byte_range => ":byte-range"
169+ /// Return the field associated with CURSOR's current node, as a keyword.
170+ /// Return nil if the current node is not associated with a field.
171+ #[ defun]
172+ fn current_field ( cursor : & RCursor ) -> Result < Option < & ' static GlobalRef > > {
173+ let cursor = cursor. borrow ( ) ;
174+ let language: Language = cursor. reft . language ( ) . into ( ) ;
175+ Ok ( cursor. field_id ( ) . and_then ( |id| language. info ( ) . field_name ( id) ) )
176+ }
157177
158- _field => ":field"
159- _depth => ":depth"
178+ macro_rules! defun_cursor_walks {
179+ ( $( $( #[ $meta: meta] ) * $( $lisp_name: literal) ? fn $name: ident $( ( $( $param: ident $( $into: ident) ? : $itype: ty ) ,* ) ) ? -> $type: ty) * ) => {
180+ $(
181+ $( #[ $meta] ) *
182+ #[ defun$( ( name = $lisp_name) ) ?]
183+ fn $name( cursor: & mut RCursor , $( $( $param: $itype ) ,* ) ? ) -> Result <$type> {
184+ Ok ( cursor. borrow_mut( ) . $name( $( $( $param $( . $into( ) ) ? ) ,* ) ? ) )
185+ }
186+ ) *
187+ } ;
188+ }
189+
190+ defun_cursor_walks ! {
191+ /// Move CURSOR to the first child of its current node.
192+ /// Return t if CURSOR successfully moved, nil if there were no children.
193+ fn goto_first_child -> bool
194+
195+ /// Move CURSOR to the parent node of its current node.
196+ /// Return t if CURSOR successfully moved, nil if it was already on the root node.
197+ fn goto_parent -> bool
198+
199+ /// Move CURSOR to the next sibling of its current node.
200+ /// Return t if CURSOR successfully moved, nil if there was no next sibling node.
201+ fn goto_next_sibling -> bool
202+
203+ /// Move CURSOR to the first child that extends beyond the given BYTEPOS.
204+ /// Return the index of the child node if one was found, nil otherwise.
205+ "goto-first-child-for-byte" fn goto_first_child_for_byte( bytepos into: BytePos ) -> Option <usize >
160206}
161207
208+ /// Re-initialize CURSOR to start at a different NODE.
209+ #[ defun]
210+ fn reset_cursor ( cursor : & mut RCursor , node : & RNode ) -> Result < ( ) > {
211+ Ok ( cursor. borrow_mut ( ) . reset ( * node. borrow ( ) ) )
212+ }
213+
214+ // -------------------------------------------------------------------------------------------------
215+
162216enum TraversalState {
163217 Start ,
164218 Down ,
165219 Right ,
166220 Done ,
167221}
168222
223+ use TraversalState :: * ;
224+
169225struct DepthFirstIterator {
170226 cursor : RCursor ,
171227 state : TraversalState ,
@@ -195,8 +251,6 @@ impl DepthFirstIterator {
195251 }
196252}
197253
198- use TraversalState :: * ;
199-
200254impl Iterator for DepthFirstIterator {
201255 type Item = ( RNode , usize ) ;
202256
@@ -385,55 +439,3 @@ fn _traverse_mapc(func: Value, tree_or_node: TreeOrNode, props: Option<Vector>)
385439 // }
386440 Ok ( ( ) )
387441}
388-
389- /// Return the field id of CURSOR's current node.
390- /// Return nil if the current node doesn't have a field.
391- #[ defun]
392- fn current_field_id ( cursor : & RCursor ) -> Result < Option < u16 > > {
393- Ok ( cursor. borrow ( ) . field_id ( ) )
394- }
395-
396- /// Return the field associated with CURSOR's current node, as a keyword.
397- /// Return nil if the current node is not associated with a field.
398- #[ defun]
399- fn current_field ( cursor : & RCursor ) -> Result < Option < & ' static GlobalRef > > {
400- let cursor = cursor. borrow ( ) ;
401- let language: Language = cursor. reft . language ( ) . into ( ) ;
402- Ok ( cursor. field_id ( ) . and_then ( |id| language. info ( ) . field_name ( id) ) )
403- }
404-
405- macro_rules! defun_cursor_walks {
406- ( $( $( #[ $meta: meta] ) * $( $lisp_name: literal) ? fn $name: ident $( ( $( $param: ident $( $into: ident) ? : $itype: ty ) ,* ) ) ? -> $type: ty) * ) => {
407- $(
408- $( #[ $meta] ) *
409- #[ defun$( ( name = $lisp_name) ) ?]
410- fn $name( cursor: & mut RCursor , $( $( $param: $itype ) ,* ) ? ) -> Result <$type> {
411- Ok ( cursor. borrow_mut( ) . $name( $( $( $param $( . $into( ) ) ? ) ,* ) ? ) )
412- }
413- ) *
414- } ;
415- }
416-
417- defun_cursor_walks ! {
418- /// Move CURSOR to the first child of its current node.
419- /// Return t if CURSOR successfully moved, nil if there were no children.
420- fn goto_first_child -> bool
421-
422- /// Move CURSOR to the parent node of its current node.
423- /// Return t if CURSOR successfully moved, nil if it was already on the root node.
424- fn goto_parent -> bool
425-
426- /// Move CURSOR to the next sibling of its current node.
427- /// Return t if CURSOR successfully moved, nil if there was no next sibling node.
428- fn goto_next_sibling -> bool
429-
430- /// Move CURSOR to the first child that extends beyond the given BYTEPOS.
431- /// Return the index of the child node if one was found, nil otherwise.
432- "goto-first-child-for-byte" fn goto_first_child_for_byte( bytepos into: BytePos ) -> Option <usize >
433- }
434-
435- /// Re-initialize CURSOR to start at a different NODE.
436- #[ defun]
437- fn reset_cursor ( cursor : & mut RCursor , node : & RNode ) -> Result < ( ) > {
438- Ok ( cursor. borrow_mut ( ) . reset ( * node. borrow ( ) ) )
439- }
0 commit comments