Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-core/src/graphemes.rs')
| -rw-r--r-- | helix-core/src/graphemes.rs | 158 |
1 files changed, 1 insertions, 157 deletions
diff --git a/helix-core/src/graphemes.rs b/helix-core/src/graphemes.rs index 98dfa365..e6adeee9 100644 --- a/helix-core/src/graphemes.rs +++ b/helix-core/src/graphemes.rs @@ -1,7 +1,7 @@ //! Utility functions to traverse the unicode graphemes of a `Rope`'s text contents. //! //! Based on <https://github.com/cessen/led/blob/c4fa72405f510b7fd16052f90a598c429b3104a6/src/graphemes.rs> -use ropey::{iter::Chunks, str_utils::byte_to_char_idx, RopeSlice}; +use ropey::{str_utils::byte_to_char_idx, RopeSlice}; use unicode_segmentation::{GraphemeCursor, GraphemeIncomplete}; use unicode_width::UnicodeWidthStr; @@ -270,162 +270,6 @@ pub fn is_grapheme_boundary(slice: RopeSlice, char_idx: usize) -> bool { } } -/// An iterator over the graphemes of a `RopeSlice`. -#[derive(Clone)] -pub struct RopeGraphemes<'a> { - text: RopeSlice<'a>, - chunks: Chunks<'a>, - cur_chunk: &'a str, - cur_chunk_start: usize, - cursor: GraphemeCursor, -} - -impl fmt::Debug for RopeGraphemes<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("RopeGraphemes") - .field("text", &self.text) - .field("chunks", &self.chunks) - .field("cur_chunk", &self.cur_chunk) - .field("cur_chunk_start", &self.cur_chunk_start) - // .field("cursor", &self.cursor) - .finish() - } -} - -impl RopeGraphemes<'_> { - #[must_use] - pub fn new(slice: RopeSlice) -> RopeGraphemes { - let mut chunks = slice.chunks(); - let first_chunk = chunks.next().unwrap_or(""); - RopeGraphemes { - text: slice, - chunks, - cur_chunk: first_chunk, - cur_chunk_start: 0, - cursor: GraphemeCursor::new(0, slice.len_bytes(), true), - } - } -} - -impl<'a> Iterator for RopeGraphemes<'a> { - type Item = RopeSlice<'a>; - - fn next(&mut self) -> Option<RopeSlice<'a>> { - let a = self.cursor.cur_cursor(); - let b; - loop { - match self - .cursor - .next_boundary(self.cur_chunk, self.cur_chunk_start) - { - Ok(None) => { - return None; - } - Ok(Some(n)) => { - b = n; - break; - } - Err(GraphemeIncomplete::NextChunk) => { - self.cur_chunk_start += self.cur_chunk.len(); - self.cur_chunk = self.chunks.next().unwrap_or(""); - } - Err(GraphemeIncomplete::PreContext(idx)) => { - let (chunk, byte_idx, _, _) = self.text.chunk_at_byte(idx.saturating_sub(1)); - self.cursor.provide_context(chunk, byte_idx); - } - _ => unreachable!(), - } - } - - if a < self.cur_chunk_start { - Some(self.text.byte_slice(a..b)) - } else { - let a2 = a - self.cur_chunk_start; - let b2 = b - self.cur_chunk_start; - Some((&self.cur_chunk[a2..b2]).into()) - } - } -} - -/// An iterator over the graphemes of a `RopeSlice` in reverse. -#[derive(Clone)] -pub struct RevRopeGraphemes<'a> { - text: RopeSlice<'a>, - chunks: Chunks<'a>, - cur_chunk: &'a str, - cur_chunk_start: usize, - cursor: GraphemeCursor, -} - -impl fmt::Debug for RevRopeGraphemes<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("RevRopeGraphemes") - .field("text", &self.text) - .field("chunks", &self.chunks) - .field("cur_chunk", &self.cur_chunk) - .field("cur_chunk_start", &self.cur_chunk_start) - // .field("cursor", &self.cursor) - .finish() - } -} - -impl RevRopeGraphemes<'_> { - #[must_use] - pub fn new(slice: RopeSlice) -> RevRopeGraphemes { - let (mut chunks, mut cur_chunk_start, _, _) = slice.chunks_at_byte(slice.len_bytes()); - chunks.reverse(); - let first_chunk = chunks.next().unwrap_or(""); - cur_chunk_start -= first_chunk.len(); - RevRopeGraphemes { - text: slice, - chunks, - cur_chunk: first_chunk, - cur_chunk_start, - cursor: GraphemeCursor::new(slice.len_bytes(), slice.len_bytes(), true), - } - } -} - -impl<'a> Iterator for RevRopeGraphemes<'a> { - type Item = RopeSlice<'a>; - - fn next(&mut self) -> Option<RopeSlice<'a>> { - let a = self.cursor.cur_cursor(); - let b; - loop { - match self - .cursor - .prev_boundary(self.cur_chunk, self.cur_chunk_start) - { - Ok(None) => { - return None; - } - Ok(Some(n)) => { - b = n; - break; - } - Err(GraphemeIncomplete::PrevChunk) => { - self.cur_chunk = self.chunks.next().unwrap_or(""); - self.cur_chunk_start -= self.cur_chunk.len(); - } - Err(GraphemeIncomplete::PreContext(idx)) => { - let (chunk, byte_idx, _, _) = self.text.chunk_at_byte(idx.saturating_sub(1)); - self.cursor.provide_context(chunk, byte_idx); - } - _ => unreachable!(), - } - } - - if a >= self.cur_chunk_start + self.cur_chunk.len() { - Some(self.text.byte_slice(b..a)) - } else { - let a2 = a - self.cur_chunk_start; - let b2 = b - self.cur_chunk_start; - Some((&self.cur_chunk[b2..a2]).into()) - } - } -} - /// A highly compressed Cow<'a, str> that holds /// atmost u31::MAX bytes and is readonly pub struct GraphemeStr<'a> { |