diff options
author | Blaž Hrastnik | 2020-05-28 05:59:50 +0000 |
---|---|---|
committer | Blaž Hrastnik | 2020-05-28 05:59:50 +0000 |
commit | 1984410ac998ac5561f4a3de87d3d125f2f61178 (patch) | |
tree | a9a267d6db8763733da5bf468cad870be3acb650 /helix-core | |
parent | e52e848fd72f2d7fdc9ebe1c8f7bf215d85a02ee (diff) |
Selection mapping over changesets.
Diffstat (limited to 'helix-core')
-rw-r--r-- | helix-core/src/lib.rs | 2 | ||||
-rw-r--r-- | helix-core/src/selection.rs | 30 | ||||
-rw-r--r-- | helix-core/src/transaction.rs | 7 |
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 |