mirror of https://github.com/helix-editor/helix
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
66 lines
1.9 KiB
Rust
66 lines
1.9 KiB
Rust
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
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn different_prev_word_boundary() {
|
|
use ropey::Rope;
|
|
let t = |x, y| {
|
|
let text = Rope::from(x);
|
|
let out = nth_prev_word_boundary(text.slice(..), text.len_chars() - 1, 1);
|
|
assert_eq!(text.slice(..out), y, r#"from "{}""#, x);
|
|
};
|
|
t("abcd\nefg\nwrs", "abcd\nefg\n");
|
|
t("abcd\nefg\n", "abcd\n");
|
|
t("abcd\n", "");
|
|
t("hello, world!", "hello, world");
|
|
t("hello, world", "hello, ");
|
|
t("hello, ", "hello");
|
|
t("hello", "");
|
|
t("こんにちは、世界!", "こんにちは、世界!"); // TODO: punctuation
|
|
t("こんにちは、世界", "こんにちは、");
|
|
t("こんにちは、", "こんにちは、"); // what?
|
|
t("こんにちは", "");
|
|
t("この世界。", "この世界。"); // what?
|
|
t("この世界", "");
|
|
t("お前はもう死んでいる", "");
|
|
t("その300円です", ""); // TODO: should stop at 300
|
|
t("唱k", ""); // TODO: should stop at 唱
|
|
t("1 + 1 = 2", "1 + 1 = ");
|
|
t("1 + 1 =", "1 + 1 ");
|
|
t("1 + 1", "1 + ");
|
|
t("1 + ", "1 ");
|
|
t("1 ", "");
|
|
t("1+1=2", "1+1=");
|
|
}
|