64 lines
1.7 KiB
Rust
64 lines
1.7 KiB
Rust
pub fn spaces(size: u8) -> &'static str {
|
|
const SPACES: &str = " ";
|
|
&SPACES[..size as usize]
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Pos {
|
|
pub row: usize,
|
|
pub col: usize,
|
|
pub offset: usize,
|
|
}
|
|
|
|
impl Pos {
|
|
pub fn new(row: usize, col: usize, offset: usize) -> Self {
|
|
Self { row, col, offset }
|
|
}
|
|
}
|
|
|
|
#[derive(PartialEq, Eq, Clone, Copy)]
|
|
enum CharKind {
|
|
Space,
|
|
Punct,
|
|
Other,
|
|
}
|
|
|
|
impl CharKind {
|
|
fn new(c: char) -> Self {
|
|
if c.is_whitespace() {
|
|
Self::Space
|
|
} else if c.is_ascii_punctuation() {
|
|
Self::Punct
|
|
} else {
|
|
Self::Other
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn find_word_start_forward(line: &str, start_col: usize) -> Option<usize> {
|
|
let mut it = line.chars().enumerate().skip(start_col);
|
|
let mut prev = CharKind::new(it.next()?.1);
|
|
for (col, c) in it {
|
|
let cur = CharKind::new(c);
|
|
if cur != CharKind::Space && prev != cur {
|
|
return Some(col);
|
|
}
|
|
prev = cur;
|
|
}
|
|
None
|
|
}
|
|
|
|
pub fn find_word_start_backward(line: &str, start_col: usize) -> Option<usize> {
|
|
let idx = line.char_indices().nth(start_col).map(|(i, _)| i).unwrap_or(line.len());
|
|
let mut it = line[..idx].chars().rev().enumerate();
|
|
let mut cur = CharKind::new(it.next()?.1);
|
|
for (i, c) in it {
|
|
let next = CharKind::new(c);
|
|
if cur != CharKind::Space && next != cur {
|
|
return Some(start_col - i);
|
|
}
|
|
cur = next;
|
|
}
|
|
(cur != CharKind::Space).then_some(0)
|
|
}
|