aboutsummaryrefslogtreecommitdiff
path: root/helix-core
diff options
context:
space:
mode:
Diffstat (limited to 'helix-core')
-rw-r--r--helix-core/src/lib.rs2
-rw-r--r--helix-core/src/selection.rs30
-rw-r--r--helix-core/src/transaction.rs7
3 files changed, 37 insertions, 2 deletions
diff --git a/helix-core/src/lib.rs b/helix-core/src/lib.rs
index e027f943..421d8f3c 100644
--- a/helix-core/src/lib.rs
+++ b/helix-core/src/lib.rs
@@ -13,4 +13,4 @@ pub use selection::Selection;
pub use state::State;
-pub use transaction::{Change, ChangeSet, Transaction};
+pub use transaction::{Assoc, Change, ChangeSet, Transaction};
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 {
diff --git a/helix-core/src/transaction.rs b/helix-core/src/transaction.rs
index c6be89ac..8da01c09 100644
--- a/helix-core/src/transaction.rs
+++ b/helix-core/src/transaction.rs
@@ -242,6 +242,13 @@ impl ChangeSet {
}
}
+ /// `true` when the set is empty.
+ #[inline]
+ pub fn is_empty(&self) -> bool {
+ let len = self.changes.len();
+ len == 0 || (len == 1 && self.changes[0] == Change::Retain(self.len))
+ }
+
/// Map a position through the changes.
///
/// `assoc` indicates which size to associate the position with. `Before` will keep the