diff options
author | Blaž Hrastnik | 2021-02-22 06:50:41 +0000 |
---|---|---|
committer | Blaž Hrastnik | 2021-02-22 08:02:32 +0000 |
commit | 6cfb1acb9d1456e854a2c44ee8fc057f45b29ea9 (patch) | |
tree | 13cff77a4a8fe007b6cd6eff3af863c7cdeffe9e /helix-core | |
parent | 33c67f138835d4407e076ebcf2d29322fda44114 (diff) |
commands: Implement expand_selection.
Diffstat (limited to 'helix-core')
-rw-r--r-- | helix-core/src/lib.rs | 1 | ||||
-rw-r--r-- | helix-core/src/object.rs | 32 |
2 files changed, 33 insertions, 0 deletions
diff --git a/helix-core/src/lib.rs b/helix-core/src/lib.rs index 14e58293..7b401557 100644 --- a/helix-core/src/lib.rs +++ b/helix-core/src/lib.rs @@ -5,6 +5,7 @@ pub mod graphemes; mod history; pub mod indent; pub mod macros; +pub mod object; mod position; pub mod register; pub mod selection; diff --git a/helix-core/src/object.rs b/helix-core/src/object.rs new file mode 100644 index 00000000..19ff9d96 --- /dev/null +++ b/helix-core/src/object.rs @@ -0,0 +1,32 @@ +use crate::{Range, RopeSlice, Selection, Syntax}; +use smallvec::smallvec; + +// 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.root_layer.tree.as_ref().unwrap(); + + selection.transform(|range| { + let from = text.char_to_byte(range.from()); + let to = text.char_to_byte(range.to()); + + // find parent of a descendant that matches the range + let parent = match tree + .root_node() + .descendant_for_byte_range(from, to) + .and_then(|node| node.parent()) + { + Some(parent) => parent, + None => return range, + }; + + let from = text.byte_to_char(parent.start_byte()); + let to = text.byte_to_char(parent.end_byte()); + + if range.head < range.anchor { + Range::new(to, from) + } else { + Range::new(from, to) + } + }) +} |