aboutsummaryrefslogtreecommitdiff
path: root/helix-core/src
diff options
context:
space:
mode:
Diffstat (limited to 'helix-core/src')
-rw-r--r--helix-core/src/graphemes.rs24
1 files changed, 24 insertions, 0 deletions
diff --git a/helix-core/src/graphemes.rs b/helix-core/src/graphemes.rs
index 2e6a925f..e2f7c3f3 100644
--- a/helix-core/src/graphemes.rs
+++ b/helix-core/src/graphemes.rs
@@ -121,6 +121,30 @@ pub fn next_grapheme_boundary(slice: RopeSlice, char_idx: usize) -> usize {
nth_next_grapheme_boundary(slice, char_idx, 1)
}
+/// Returns the passed char index if it's already a grapheme boundary,
+/// or the next grapheme boundary char index if not.
+pub fn ensure_grapheme_boundary(slice: RopeSlice, char_idx: usize) -> usize {
+ if char_idx == 0 {
+ 0
+ } else {
+ next_grapheme_boundary(slice, char_idx - 1)
+ }
+}
+
+/// Returns the passed byte index if it's already a grapheme boundary,
+/// or the next grapheme boundary byte index if not.
+pub fn ensure_grapheme_boundary_byte(slice: RopeSlice, byte_idx: usize) -> usize {
+ // TODO: we can avoid the byte/char conversions entirely
+ // if we also make byte versions of the other functions.
+ let char_idx = slice.byte_to_char(byte_idx);
+ let fixed_char_idx = ensure_grapheme_boundary(slice, char_idx);
+ if fixed_char_idx == char_idx {
+ byte_idx
+ } else {
+ slice.char_to_byte(fixed_char_idx)
+ }
+}
+
/// Returns whether the given char position is a grapheme boundary.
pub fn is_grapheme_boundary(slice: RopeSlice, char_idx: usize) -> bool {
// Bounds check