aboutsummaryrefslogtreecommitdiff
path: root/helix-core
diff options
context:
space:
mode:
authorBlaž Hrastnik2021-03-11 01:44:38 +0000
committerBlaž Hrastnik2021-03-11 01:44:38 +0000
commit62c991230f511b2dc11f8d1701260511800429d4 (patch)
tree0cb7cc0102134a973c5f600e61bca350ad39d74d /helix-core
parent90f9cd6d6275048db664afa4139e7f2bdfaeacb0 (diff)
find-till (f) prototype, on_next_key mode implementation.
Diffstat (limited to 'helix-core')
-rw-r--r--helix-core/src/lib.rs1
-rw-r--r--helix-core/src/search.rs70
-rw-r--r--helix-core/src/state.rs14
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);
}
}