diff options
author | Gokul Soumya | 2022-01-06 05:56:35 +0000 |
---|---|---|
committer | Gokul Soumya | 2022-01-06 06:02:03 +0000 |
commit | 449624965b05fd2abc9e3ba2f791f8de8b1eeb3e (patch) | |
tree | cbe060df6a61330e6a470c521ed254f5c7dc4f4f /helix-core/src/object.rs | |
parent | c0bbadcaaf42698d102fa03f6f9267021f3efec0 (diff) | |
parent | 2e02a1d6bc004212033b9c4e5ed0de0fd880796c (diff) |
Merge branch 'master' into cursor-shape-new
Diffstat (limited to 'helix-core/src/object.rs')
-rw-r--r-- | helix-core/src/object.rs | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/helix-core/src/object.rs b/helix-core/src/object.rs index 717c5994..21fa24fb 100644 --- a/helix-core/src/object.rs +++ b/helix-core/src/object.rs @@ -1,7 +1,5 @@ use crate::{Range, RopeSlice, Selection, Syntax}; -// TODO: to contract_selection we'd need to store the previous ranges before expand. -// Maybe just contract to the first child node? pub fn expand_selection(syntax: &Syntax, text: RopeSlice, selection: &Selection) -> Selection { let tree = syntax.tree(); @@ -34,3 +32,30 @@ pub fn expand_selection(syntax: &Syntax, text: RopeSlice, selection: &Selection) } }) } + +pub fn shrink_selection(syntax: &Syntax, text: RopeSlice, selection: &Selection) -> Selection { + let tree = syntax.tree(); + + selection.clone().transform(|range| { + let from = text.char_to_byte(range.from()); + let to = text.char_to_byte(range.to()); + + let descendant = match tree.root_node().descendant_for_byte_range(from, to) { + // find first child, if not possible, fallback to the node that contains selection + Some(descendant) => match descendant.child(0) { + Some(child) => child, + None => descendant, + }, + None => return range, + }; + + let from = text.byte_to_char(descendant.start_byte()); + let to = text.byte_to_char(descendant.end_byte()); + + if range.head < range.anchor { + Range::new(to, from) + } else { + Range::new(from, to) + } + }) +} |