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::{
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.
@ -202,28 +202,40 @@ pub fn find_good_break(slice: &RopeSlice, lower_limit: usize, char_idx: usize) -
let char_idx = char_idx.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.
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 {
if (i == slice_len || !WS_CHARS.contains(&slice.char(i)))
&& WS_CHARS.contains(&slice.char(i - 1))
let c = char_itr.prev();
if WS_CHARS.contains(&c.unwrap()) && prev.map(|pc| !WS_CHARS.contains(&pc)).unwrap_or(true)
{
return i;
}
prev = c;
i -= 1;
}
// Otherwise, at least try to find a grapheme break.
let mut i = char_idx;
while i > lower_limit && !is_grapheme_boundary(slice, i) {
i -= 1;
}
if is_grapheme_boundary(slice, char_idx) {
char_idx
} else {
let i = prev_grapheme_boundary(slice, char_idx);
if i > lower_limit {
i
} else {
char_idx
}
}
}
pub fn char_range_from_block_index(slice: &RopeSlice, block_idx: usize) -> (usize, usize) {