@@ -0,0 +1,32 @@
1+use crate::{Range, RopeSlice, Selection, Syntax};
2+use smallvec::smallvec;
3+
4+// TODO: to contract_selection we'd need to store the previous ranges before expand.
5+// Maybe just contract to the first child node?
6+pub fn expand_selection(syntax: &Syntax, text: RopeSlice, selection: &Selection) -> Selection {
7+ let tree = syntax.root_layer.tree.as_ref().unwrap();
8+
9+ selection.transform(|range| {
10+ let from = text.char_to_byte(range.from());
11+ let to = text.char_to_byte(range.to());
12+
13+ // find parent of a descendant that matches the range
14+ let parent = match tree
15+ .root_node()
16+ .descendant_for_byte_range(from, to)
17+ .and_then(|node| node.parent())
18+ {
19+ Some(parent) => parent,
20+ None => return range,
21+ };
22+
23+ let from = text.byte_to_char(parent.start_byte());
24+ let to = text.byte_to_char(parent.end_byte());
25+
26+ if range.head < range.anchor {
27+ Range::new(to, from)
28+ } else {
29+ Range::new(from, to)
30+ }
31+ })
32+}