diff options
author | Nathan Vegdahl | 2021-07-08 00:24:39 +0000 |
---|---|---|
committer | Nathan Vegdahl | 2021-07-08 00:24:39 +0000 |
commit | 753f7f381b96f591be3c0e37a93b90776c5405cb (patch) | |
tree | 749a0ac3a0f5a15b5fa8a8be70d2182cb79cf500 /helix-core/src/selection.rs | |
parent | 85d5b399de70ff075a455ce2858549d1ed012fe3 (diff) |
Implement `Range::put()` which manages range movements and extensions.
In particular, this wraps the annoying logic involved in keeping the
cursor width to 1 grapheme.
Diffstat (limited to 'helix-core/src/selection.rs')
-rw-r--r-- | helix-core/src/selection.rs | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/helix-core/src/selection.rs b/helix-core/src/selection.rs index 64ff51d8..8951899b 100644 --- a/helix-core/src/selection.rs +++ b/helix-core/src/selection.rs @@ -5,6 +5,7 @@ use crate::{ graphemes::{ ensure_grapheme_boundary_next, ensure_grapheme_boundary_prev, next_grapheme_boundary, + prev_grapheme_boundary, }, Assoc, ChangeSet, RopeSlice, }; @@ -208,6 +209,28 @@ impl Range { } } + /// Moves the `Range` to `char_idx`. If `extend == true`, then only the head + /// is moved to `char_idx`, and the anchor is adjusted only as needed to + /// preserve 1-width range semantics. + /// + /// This method assumes that the range and `char_idx` are already properly + /// grapheme-aligned. + #[must_use] + #[inline] + pub fn put(self, text: RopeSlice, extend: bool, char_idx: usize) -> Range { + let anchor = if !extend { + char_idx + } else if self.head >= self.anchor && char_idx < self.anchor { + next_grapheme_boundary(text, self.anchor) + } else if self.head < self.anchor && char_idx >= self.anchor { + prev_grapheme_boundary(text, self.anchor) + } else { + self.anchor + }; + + Range::new(anchor, char_idx) + } + // groupAt #[inline] |