From 90f9cd6d6275048db664afa4139e7f2bdfaeacb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Wed, 10 Mar 2021 17:50:46 +0900 Subject: [PATCH] search: draft f/t --- helix-core/src/search.rs | 69 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 helix-core/src/search.rs diff --git a/helix-core/src/search.rs b/helix-core/src/search.rs new file mode 100644 index 00000000..7d790d66 --- /dev/null +++ b/helix-core/src/search.rs @@ -0,0 +1,69 @@ +use crate::RopeSlice; + +pub fn find_nth_next(text: RopeSlice, ch: char, pos: usize, n: usize) -> Option { + // 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 { + // 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)) +}