More efficient line block boundary finding.

This commit is contained in:
Nathan Vegdahl 2020-02-06 19:18:50 +09:00
parent f95cb7f641
commit d1de3aacb3

View File

@ -4,7 +4,7 @@ use ropey::RopeSlice;
use crate::{ use crate::{
buffer::Buffer, buffer::Buffer,
utils::{is_grapheme_boundary, RopeGraphemes}, utils::{is_grapheme_boundary, prev_grapheme_boundary, RopeGraphemes},
}; };
// Maximum chars in a line before a soft line break is forced. // Maximum chars in a line before a soft line break is forced.
@ -202,29 +202,41 @@ pub fn find_good_break(slice: &RopeSlice, lower_limit: usize, char_idx: usize) -
let char_idx = char_idx.min(slice_len); let char_idx = char_idx.min(slice_len);
let lower_limit = lower_limit.min(slice_len); let lower_limit = lower_limit.min(slice_len);
// Early out in trivial cases.
if char_idx < (LINE_BLOCK_LENGTH - LINE_BLOCK_FUDGE) {
return char_idx;
}
// Find a whitespace break, if any. // Find a whitespace break, if any.
let mut i = char_idx; let mut i = char_idx;
let mut prev = if i == slice_len {
None
} else {
Some(slice.char(char_idx))
};
let mut char_itr = slice.chars_at(char_idx);
while i > lower_limit { while i > lower_limit {
if (i == slice_len || !WS_CHARS.contains(&slice.char(i))) let c = char_itr.prev();
&& WS_CHARS.contains(&slice.char(i - 1)) if WS_CHARS.contains(&c.unwrap()) && prev.map(|pc| !WS_CHARS.contains(&pc)).unwrap_or(true)
{ {
return i; return i;
} }
prev = c;
i -= 1; i -= 1;
} }
// Otherwise, at least try to find a grapheme break. // Otherwise, at least try to find a grapheme break.
let mut i = char_idx; if is_grapheme_boundary(slice, char_idx) {
while i > lower_limit && !is_grapheme_boundary(slice, i) { char_idx
i -= 1; } else {
} let i = prev_grapheme_boundary(slice, char_idx);
if i > lower_limit { if i > lower_limit {
i i
} else { } else {
char_idx char_idx
} }
} }
}
pub fn char_range_from_block_index(slice: &RopeSlice, block_idx: usize) -> (usize, usize) { pub fn char_range_from_block_index(slice: &RopeSlice, block_idx: usize) -> (usize, usize) {
let start = { let start = {