diff --git a/Cargo.lock b/Cargo.lock index c1ddb89..24dddd7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -88,7 +88,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "ropey" version = "0.6.3" -source = "git+https://github.com/cessen/ropey#41fb82d82279e8f20c2be680f661ee2f6c0e1c78" +source = "git+https://github.com/cessen/ropey#48af097f84f458baa6e72a96fb7aa5905ad218ed" dependencies = [ "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/src/utils.rs b/src/utils.rs index 65cc292..2c809bf 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -33,25 +33,28 @@ pub fn prev_grapheme_boundary(slice: &RopeSlice, char_idx: usize) -> usize { // We work with bytes for this, so convert. let byte_idx = slice.char_to_byte(char_idx); - // Get the chunk with our byte index in it, and calculate its starting - // byte within the total rope slice. - let (mut chunk, byte_offset) = slice.chunk_at_byte(byte_idx); - let mut chunk_start_idx = byte_idx - byte_offset; + // Get the chunk with our byte index in it. + let (mut chunk, mut chunk_byte_idx, mut chunk_char_idx) = slice.chunk_at_byte(byte_idx); // Set up the grapheme cursor. let mut gc = GraphemeCursor::new(byte_idx, slice.len_bytes(), true); // Find the previous grapheme cluster boundary. loop { - match gc.prev_boundary(chunk, chunk_start_idx) { + match gc.prev_boundary(chunk, chunk_byte_idx) { Ok(None) => return 0, - Ok(Some(n)) => return slice.byte_to_char(n), + Ok(Some(n)) => { + let tmp = chunk[..(n - chunk_byte_idx)].chars().count(); + return chunk_char_idx + tmp; + } Err(GraphemeIncomplete::PrevChunk) => { - chunk = slice.chunk_at_byte(chunk_start_idx - 1).0; - chunk_start_idx -= chunk.len(); + let (a, b, c) = slice.chunk_at_byte(chunk_byte_idx - 1); + chunk = a; + chunk_byte_idx = b; + chunk_char_idx = c; } Err(GraphemeIncomplete::PreContext(n)) => { - let (ctx_chunk, _) = slice.chunk_at_byte(n - 1); + let ctx_chunk = slice.chunk_at_byte(n - 1).0; gc.provide_context(ctx_chunk, n - ctx_chunk.len()); } _ => unreachable!(), @@ -67,25 +70,28 @@ pub fn next_grapheme_boundary(slice: &RopeSlice, char_idx: usize) -> usize { // We work with bytes for this, so convert. let byte_idx = slice.char_to_byte(char_idx); - // Get the chunk with our byte index in it, and calculate its starting - // byte within the total rope slice. - let (mut chunk, byte_offset) = slice.chunk_at_byte(byte_idx); - let mut chunk_start_idx = byte_idx - byte_offset; + // Get the chunk with our byte index in it. + let (mut chunk, mut chunk_byte_idx, mut chunk_char_idx) = slice.chunk_at_byte(byte_idx); // Set up the grapheme cursor. let mut gc = GraphemeCursor::new(byte_idx, slice.len_bytes(), true); // Find the next grapheme cluster boundary. loop { - match gc.next_boundary(chunk, chunk_start_idx) { + match gc.next_boundary(chunk, chunk_byte_idx) { Ok(None) => return slice.len_chars(), - Ok(Some(n)) => return slice.byte_to_char(n), + Ok(Some(n)) => { + let tmp = chunk[..(n - chunk_byte_idx)].chars().count(); + return chunk_char_idx + tmp; + } Err(GraphemeIncomplete::NextChunk) => { - chunk_start_idx += chunk.len(); - chunk = slice.chunk_at_byte(chunk_start_idx).0; + chunk_byte_idx += chunk.len(); + let (a, _, c) = slice.chunk_at_byte(chunk_byte_idx); + chunk = a; + chunk_char_idx = c; } Err(GraphemeIncomplete::PreContext(n)) => { - let (ctx_chunk, _) = slice.chunk_at_byte(n - 1); + let ctx_chunk = slice.chunk_at_byte(n - 1).0; gc.provide_context(ctx_chunk, n - ctx_chunk.len()); } _ => unreachable!(), @@ -101,21 +107,19 @@ pub fn is_grapheme_boundary(slice: &RopeSlice, char_idx: usize) -> bool { // We work with bytes for this, so convert. let byte_idx = slice.char_to_byte(char_idx); - // Get the chunk with our byte index in it, and calculate its starting - // byte within the total rope slice. - let (chunk, byte_offset) = slice.chunk_at_byte(byte_idx); - let chunk_start_idx = byte_idx - byte_offset; + // Get the chunk with our byte index in it. + let (chunk, chunk_byte_idx, _) = slice.chunk_at_byte(byte_idx); // Set up the grapheme cursor. let mut gc = GraphemeCursor::new(byte_idx, slice.len_bytes(), true); // Determine if the given position is a grapheme cluster boundary. loop { - match gc.is_boundary(chunk, chunk_start_idx) { + match gc.is_boundary(chunk, chunk_byte_idx) { Ok(n) => return n, Err(GraphemeIncomplete::PreContext(n)) => { - let (ctx_chunk, _) = slice.chunk_at_byte(n - 1); - gc.provide_context(ctx_chunk, n - ctx_chunk.len()); + let (ctx_chunk, ctx_byte_start, _) = slice.chunk_at_byte(n - 1); + gc.provide_context(ctx_chunk, ctx_byte_start); } _ => unreachable!(), }