aboutsummaryrefslogtreecommitdiff
path: root/helix-core
diff options
context:
space:
mode:
authorBlaž Hrastnik2021-02-22 06:50:41 +0000
committerBlaž Hrastnik2021-02-22 08:02:32 +0000
commit6cfb1acb9d1456e854a2c44ee8fc057f45b29ea9 (patch)
tree13cff77a4a8fe007b6cd6eff3af863c7cdeffe9e /helix-core
parent33c67f138835d4407e076ebcf2d29322fda44114 (diff)
commands: Implement expand_selection.
Diffstat (limited to 'helix-core')
-rw-r--r--helix-core/src/lib.rs1
-rw-r--r--helix-core/src/object.rs32
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)
+ }
+ })
+}