diff options
Diffstat (limited to 'helix-core/src')
-rw-r--r-- | helix-core/src/lib.rs | 1 | ||||
-rw-r--r-- | helix-core/src/movement.rs | 8 | ||||
-rw-r--r-- | helix-core/src/words.rs | 33 |
3 files changed, 38 insertions, 4 deletions
diff --git a/helix-core/src/lib.rs b/helix-core/src/lib.rs index 6b93de78..4be3e71b 100644 --- a/helix-core/src/lib.rs +++ b/helix-core/src/lib.rs @@ -16,6 +16,7 @@ pub mod selection; mod state; pub mod syntax; mod transaction; +pub mod words; pub(crate) fn find_first_non_whitespace_char2(line: RopeSlice) -> Option<usize> { // find first non-whitespace char diff --git a/helix-core/src/movement.rs b/helix-core/src/movement.rs index 297911ae..c5e2df4a 100644 --- a/helix-core/src/movement.rs +++ b/helix-core/src/movement.rs @@ -174,22 +174,22 @@ pub fn move_next_word_end(slice: RopeSlice, mut begin: usize, count: usize) -> O // used for by-word movement -fn is_word(ch: char) -> bool { +pub(crate) fn is_word(ch: char) -> bool { ch.is_alphanumeric() || ch == '_' } -fn is_horiz_blank(ch: char) -> bool { +pub(crate) fn is_horiz_blank(ch: char) -> bool { matches!(ch, ' ' | '\t') } #[derive(Debug, Eq, PartialEq)] -enum Category { +pub(crate) enum Category { Whitespace, Eol, Word, Punctuation, } -fn categorize(ch: char) -> Category { +pub(crate) fn categorize(ch: char) -> Category { if ch == '\n' { Category::Eol } else if ch.is_ascii_whitespace() { diff --git a/helix-core/src/words.rs b/helix-core/src/words.rs new file mode 100644 index 00000000..0099d56a --- /dev/null +++ b/helix-core/src/words.rs @@ -0,0 +1,33 @@ +use crate::movement::{categorize, is_horiz_blank, is_word, skip_over_prev}; +use ropey::RopeSlice; + +#[must_use] +pub fn nth_prev_word_boundary(slice: RopeSlice, mut char_idx: usize, count: usize) -> usize { + let mut with_end = false; + + for _ in 0..count { + if char_idx == 0 { + break; + } + + // return if not skip while? + skip_over_prev(slice, &mut char_idx, |ch| ch == '\n'); + + with_end = skip_over_prev(slice, &mut char_idx, is_horiz_blank); + + // refetch + let ch = slice.char(char_idx); + + if is_word(ch) { + with_end = skip_over_prev(slice, &mut char_idx, is_word); + } else if ch.is_ascii_punctuation() { + with_end = skip_over_prev(slice, &mut char_idx, |ch| ch.is_ascii_punctuation()); + } + } + + if with_end { + char_idx + } else { + char_idx + 1 + } +} |