@ -1,42 +1,52 @@
use crate ::{ Range , RopeSlice , Selection , Syntax } ;
use crate ::{ syntax ::TreeCursor , Range , RopeSlice , Selection , Syntax } ;
use tree_sitter ::Node ;
pub fn expand_selection ( syntax : & Syntax , text : RopeSlice , selection : Selection ) -> Selection {
pub fn expand_selection ( syntax : & Syntax , text : RopeSlice , selection : Selection ) -> Selection {
select_node_impl ( syntax , text , selection , | mut node , from , to | {
let cursor = & mut syntax . walk ( ) ;
while node . start_byte ( ) = = from & & node . end_byte ( ) = = to {
node = node . parent ( ) ? ;
selection . transform ( | range | {
let from = text . char_to_byte ( range . from ( ) ) ;
let to = text . char_to_byte ( range . to ( ) ) ;
let byte_range = from .. to ;
cursor . reset_to_byte_range ( from , to ) ;
while cursor . node ( ) . byte_range ( ) = = byte_range {
if ! cursor . goto_parent ( ) {
break ;
}
}
}
Some ( node )
let node = cursor . node ( ) ;
let from = text . byte_to_char ( node . start_byte ( ) ) ;
let to = text . byte_to_char ( node . end_byte ( ) ) ;
Range ::new ( to , from ) . with_direction ( range . direction ( ) )
} )
} )
}
}
pub fn shrink_selection ( syntax : & Syntax , text : RopeSlice , selection : Selection ) -> Selection {
pub fn shrink_selection ( syntax : & Syntax , text : RopeSlice , selection : Selection ) -> Selection {
select_node_impl ( syntax , text , selection , | descendant , _from , _to | {
select_node_impl ( syntax , text , selection , | cursor | {
descendant . child ( 0 ) . or ( Some ( descendant ) )
cursor. goto_first_child ( ) ;
} )
} )
}
}
pub fn select_sibling < F > (
pub fn select_next_sibling ( syntax : & Syntax , text : RopeSlice , selection : Selection ) -> Selection {
syntax : & Syntax ,
select_node_impl ( syntax , text , selection , | cursor | {
text : RopeSlice ,
while ! cursor . goto_next_sibling ( ) {
selection : Selection ,
if ! cursor . goto_parent ( ) {
sibling_fn : & F ,
break ;
) -> Selection
}
where
}
F : Fn ( Node ) -> Option < Node > ,
{
select_node_impl ( syntax , text , selection , | descendant , _from , _to | {
find_sibling_recursive ( descendant , sibling_fn )
} )
} )
}
}
fn find_sibling_recursive < F > ( node : Node , sibling_fn : F ) -> Option < Node >
pub fn select_prev_sibling ( syntax : & Syntax , text : RopeSlice , selection : Selection ) -> Selection {
where
select_node_impl ( syntax , text , selection , | cursor | {
F : Fn ( Node ) -> Option < Node > ,
while ! cursor . goto_prev_sibling ( ) {
{
if ! cursor . goto_parent ( ) {
sibling_fn ( node ) . or_else ( | | {
break ;
node . parent ( )
}
. and_then ( | node | find_sibling_recursive ( node , sibling_fn ) )
}
} )
} )
}
}
@ -44,33 +54,25 @@ fn select_node_impl<F>(
syntax : & Syntax ,
syntax : & Syntax ,
text : RopeSlice ,
text : RopeSlice ,
selection : Selection ,
selection : Selection ,
select_f n: F ,
motio n: F ,
) -> Selection
) -> Selection
where
where
F : Fn ( Node , usize , usize ) -> Option < Node > ,
F : Fn ( & mut TreeCursor ) ,
{
{
let tree = syntax . tree ( ) ;
let cursor = & mut syntax . walk ( ) ;
selection . transform ( | range | {
selection . transform ( | range | {
let from = text . char_to_byte ( range . from ( ) ) ;
let from = text . char_to_byte ( range . from ( ) ) ;
let to = text . char_to_byte ( range . to ( ) ) ;
let to = text . char_to_byte ( range . to ( ) ) ;
let node = match tree
cursor . reset_to_byte_range ( from , to ) ;
. root_node ( )
. descendant_for_byte_range ( from , to )
motion ( cursor ) ;
. and_then ( | node | select_fn ( node , from , to ) )
{
Some ( node ) = > node ,
None = > return range ,
} ;
let node = cursor . node ( ) ;
let from = text . byte_to_char ( node . start_byte ( ) ) ;
let from = text . byte_to_char ( node . start_byte ( ) ) ;
let to = text . byte_to_char ( node . end_byte ( ) ) ;
let to = text . byte_to_char ( node . end_byte ( ) ) ;
if range . head < range . anchor {
Range ::new ( from , to ) . with_direction ( range . direction ( ) )
Range ::new ( to , from )
} else {
Range ::new ( from , to )
}
} )
} )
}
}