aboutsummaryrefslogtreecommitdiff
path: root/helix-core/src/selection.rs
diff options
context:
space:
mode:
authorBlaž Hrastnik2020-05-28 05:59:50 +0000
committerBlaž Hrastnik2020-05-28 05:59:50 +0000
commit1984410ac998ac5561f4a3de87d3d125f2f61178 (patch)
treea9a267d6db8763733da5bf468cad870be3acb650 /helix-core/src/selection.rs
parente52e848fd72f2d7fdc9ebe1c8f7bf215d85a02ee (diff)
Selection mapping over changesets.
Diffstat (limited to 'helix-core/src/selection.rs')
-rw-r--r--helix-core/src/selection.rs30
1 files changed, 29 insertions, 1 deletions
diff --git a/helix-core/src/selection.rs b/helix-core/src/selection.rs
index 0b2cd5a3..98bbdb7f 100644
--- a/helix-core/src/selection.rs
+++ b/helix-core/src/selection.rs
@@ -2,6 +2,7 @@
//! single selection range.
//!
//! All positioning is done via `char` offsets into the buffer.
+use crate::{Assoc, ChangeSet};
use smallvec::{smallvec, SmallVec};
#[inline]
@@ -59,7 +60,18 @@ impl Range {
}
}
- // TODO: map
+ /// Map a range through a set of changes. Returns a new range representing the same position
+ /// after the changes are applied.
+ pub fn map(self, changes: &ChangeSet) -> Self {
+ let anchor = changes.map_pos(self.anchor, Assoc::Before);
+ let head = changes.map_pos(self.head, Assoc::Before);
+
+ // TODO: possibly unnecessary
+ if self.anchor == anchor && self.head == head {
+ return self;
+ }
+ Self { anchor, head }
+ }
/// Extend the range to cover at least `from` `to`.
#[must_use]
@@ -115,6 +127,22 @@ impl Selection {
// add_range // push
// replace_range
+ /// Map selections over a set of changes. Useful for adjusting the selection position after
+ /// applying changes to a document.
+ pub fn map(self, changes: &ChangeSet) -> Self {
+ if changes.is_empty() {
+ return self;
+ }
+
+ Self::new(
+ self.ranges
+ .into_iter()
+ .map(|range| range.map(changes))
+ .collect(),
+ self.primary_index,
+ )
+ }
+
#[must_use]
/// Constructs a selection holding a single range.
pub fn single(anchor: usize, head: usize) -> Self {