diff options
author | Blaž Hrastnik | 2021-03-11 01:44:38 +0000 |
---|---|---|
committer | Blaž Hrastnik | 2021-03-11 01:44:38 +0000 |
commit | 62c991230f511b2dc11f8d1701260511800429d4 (patch) | |
tree | 0cb7cc0102134a973c5f600e61bca350ad39d74d /helix-core | |
parent | 90f9cd6d6275048db664afa4139e7f2bdfaeacb0 (diff) |
find-till (f) prototype, on_next_key mode implementation.
Diffstat (limited to 'helix-core')
-rw-r--r-- | helix-core/src/lib.rs | 1 | ||||
-rw-r--r-- | helix-core/src/search.rs | 70 | ||||
-rw-r--r-- | helix-core/src/state.rs | 14 |
3 files changed, 32 insertions, 53 deletions
diff --git a/helix-core/src/lib.rs b/helix-core/src/lib.rs index 7b401557..89b82c4e 100644 --- a/helix-core/src/lib.rs +++ b/helix-core/src/lib.rs @@ -8,6 +8,7 @@ pub mod macros; pub mod object; mod position; pub mod register; +pub mod search; pub mod selection; pub mod state; pub mod syntax; diff --git a/helix-core/src/search.rs b/helix-core/src/search.rs index 7d790d66..c03f60df 100644 --- a/helix-core/src/search.rs +++ b/helix-core/src/search.rs @@ -1,69 +1,39 @@ use crate::RopeSlice; -pub fn find_nth_next(text: RopeSlice, ch: char, pos: usize, n: usize) -> Option<usize> { +pub fn find_nth_next(text: RopeSlice, ch: char, mut 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)..]; + let mut chars = text.chars_at(pos + 1); 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; - } - }, + let c = chars.next()?; + + pos += 1; + + if c == ch { + break; } } } - Some(text.byte_to_char(byte_idx)) + + Some(pos) } -pub fn find_nth_prev(text: RopeSlice, ch: char, pos: usize, n: usize) -> Option<usize> { +pub fn find_nth_prev(text: RopeSlice, ch: char, mut 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]; + let mut chars = text.chars_at(pos.saturating_sub(1)); 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, - }, + let c = chars.prev()?; + + pos = pos.saturating_sub(1); + + if c == ch { + break; } } } - Some(text.byte_to_char(byte_idx)) + + Some(pos) } diff --git a/helix-core/src/state.rs b/helix-core/src/state.rs index d2ebca47..8ff86f0c 100644 --- a/helix-core/src/state.rs +++ b/helix-core/src/state.rs @@ -123,6 +123,8 @@ impl State { pub fn move_next_word_start(slice: RopeSlice, mut pos: usize, count: usize) -> usize { // TODO: confirm it's fine without using graphemes, I think it should be for _ in 0..count { + // TODO: if end return end + let ch = slice.char(pos); let next = slice.char(pos.saturating_add(1)); if categorize(ch) != categorize(next) { @@ -148,8 +150,12 @@ impl State { pub fn move_prev_word_start(slice: RopeSlice, mut pos: usize, count: usize) -> usize { // TODO: confirm it's fine without using graphemes, I think it should be for _ in 0..count { + if pos == 0 { + return pos; + } + let ch = slice.char(pos); - let prev = slice.char(pos.saturating_sub(1)); // TODO: just return original pos if at start + let prev = slice.char(pos - 1); if categorize(ch) != categorize(prev) { pos -= 1; @@ -176,6 +182,8 @@ impl State { pub fn move_next_word_end(slice: RopeSlice, mut pos: usize, count: usize) -> usize { for _ in 0..count { + // TODO: if end return end + // TODO: confirm it's fine without using graphemes, I think it should be let ch = slice.char(pos); let next = slice.char(pos.saturating_add(1)); @@ -303,7 +311,7 @@ where if !fun(ch) { break; } - *pos += 1; + *pos += 1; // TODO: can go 1 over end of doc } } @@ -319,7 +327,7 @@ where if !fun(ch) { break; } - *pos -= 1; + *pos -= pos.saturating_sub(1); } } |