search: draft f/t

This commit is contained in:
Blaž Hrastnik 2021-03-10 17:50:46 +09:00
parent 8fe4590666
commit 90f9cd6d62

69
helix-core/src/search.rs Normal file
View file

@ -0,0 +1,69 @@
use crate::RopeSlice;
pub fn find_nth_next(text: RopeSlice, ch: char, pos: usize, n: usize) -> Option<usize> {
// start searching right after pos
let mut byte_idx = text.char_to_byte(pos + 1);
let (mut chunks, mut chunk_byte_idx, _chunk_char_idx, _chunk_line_idx) =
text.chunks_at_byte(byte_idx);
let mut chunk = chunks.next().unwrap_or("");
chunk = &chunk[(byte_idx - chunk_byte_idx)..];
for _ in 0..n {
loop {
match chunk.find(ch) {
Some(pos) => {
byte_idx += pos;
chunk = &chunk[pos + 1..];
break;
}
None => match chunks.next() {
Some(next_chunk) => {
byte_idx += chunk.len();
chunk = next_chunk;
}
None => {
log::info!("no more chunks");
return None;
}
},
}
}
}
Some(text.byte_to_char(byte_idx))
}
pub fn find_nth_prev(text: RopeSlice, ch: char, pos: usize, n: usize) -> Option<usize> {
// start searching right before pos
let mut byte_idx = text.char_to_byte(pos.saturating_sub(1));
let (mut chunks, mut chunk_byte_idx, _chunk_char_idx, _chunk_line_idx) =
text.chunks_at_byte(byte_idx);
let mut chunk = chunks.prev().unwrap_or("");
// start searching from pos
chunk = &chunk[..=byte_idx - chunk_byte_idx];
for _ in 0..n {
loop {
match chunk.rfind(ch) {
Some(pos) => {
byte_idx = chunk_byte_idx + pos;
chunk = &chunk[..pos];
break;
}
None => match chunks.prev() {
Some(prev_chunk) => {
chunk_byte_idx -= chunk.len();
chunk = prev_chunk;
}
None => return None,
},
}
}
}
Some(text.byte_to_char(byte_idx))
}