pub(crate) fn start_of_line(buf: &str, pos: usize) -> usize {
buf[..pos].rfind('\n').map_or(0, |i| i + 1)
}
pub(crate) fn end_of_line(buf: &str, pos: usize) -> usize {
match buf[pos..].find('\n') {
None => buf.len(),
Some(i) => {
let newline = pos + i;
if newline > 0 && buf.as_bytes()[newline - 1] == b'\r' {
newline - 1
} else {
newline
}
}
}
}
#[cfg(feature = "helix")]
pub(crate) fn first_non_blank(buf: &str, pos: usize) -> Option<usize> {
let start = start_of_line(buf, pos);
buf[start..end_of_line(buf, pos)]
.find(|c: char| !c.is_whitespace())
.map(|offset| start + offset)
}
pub(crate) fn start_of_next_line(buf: &str, pos: usize) -> Option<usize> {
buf[pos..].find('\n').map(|i| pos + i + 1)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn start_of_line_finds_current_line() {
assert_eq!(start_of_line("ab\ncd\nef", 0), 0);
assert_eq!(start_of_line("ab\ncd\nef", 2), 0); assert_eq!(start_of_line("ab\ncd\nef", 4), 3);
assert_eq!(start_of_line("ab\ncd\nef", 8), 6);
}
#[test]
fn end_of_line_stops_at_newline_or_buffer_end() {
assert_eq!(end_of_line("ab\ncd\nef", 0), 2);
assert_eq!(end_of_line("ab\ncd\nef", 4), 5);
assert_eq!(end_of_line("ab\ncd\nef", 7), 8); }
#[test]
fn end_of_line_backs_over_carriage_return() {
assert_eq!(end_of_line("ab\r\ncd", 0), 2);
assert_eq!(end_of_line("ab\r\ncd", 5), 6);
}
#[cfg(feature = "helix")]
#[test]
fn first_non_blank_finds_the_indent_end() {
assert_eq!(first_non_blank(" foo", 0), Some(4));
assert_eq!(first_non_blank("foo", 0), Some(0)); assert_eq!(first_non_blank("\t\tfoo", 0), Some(2)); assert_eq!(first_non_blank(" foo", 6), Some(4)); }
#[cfg(feature = "helix")]
#[test]
fn first_non_blank_reports_into_the_buffer_not_the_line() {
assert_eq!(first_non_blank("ab\n cd", 3), Some(5));
assert_eq!(first_non_blank("ab\n cd", 6), Some(5));
}
#[cfg(feature = "helix")]
#[test]
fn first_non_blank_is_none_on_a_blank_line() {
assert_eq!(first_non_blank(" \nfoo", 0), None);
assert_eq!(first_non_blank("", 0), None);
assert_eq!(first_non_blank(" ", 1), None); assert_eq!(first_non_blank("foo\n\nbar", 4), None); }
#[cfg(feature = "helix")]
#[test]
fn first_non_blank_ignores_a_carriage_return() {
assert_eq!(first_non_blank(" \r\nfoo", 0), None);
assert_eq!(first_non_blank(" ab\r\ncd", 0), Some(2));
}
#[test]
fn start_of_next_line_is_none_on_last_line() {
assert_eq!(start_of_next_line("ab\ncd", 0), Some(3));
assert_eq!(start_of_next_line("ab\ncd", 4), None);
assert_eq!(start_of_next_line("ab\r\ncd", 0), Some(4));
}
}