use crate::syntax::SyntaxKind;
use rowan::GreenNodeBuilder;
pub(crate) fn emit_line_tokens(builder: &mut GreenNodeBuilder<'static>, line: &str) {
if let Some(text) = line.strip_suffix("\r\n") {
builder.token(SyntaxKind::TEXT.into(), text);
builder.token(SyntaxKind::NEWLINE.into(), "\r\n");
} else if let Some(text) = line.strip_suffix('\n') {
builder.token(SyntaxKind::TEXT.into(), text);
builder.token(SyntaxKind::NEWLINE.into(), "\n");
} else {
builder.token(SyntaxKind::TEXT.into(), line);
}
}
pub(crate) fn strip_leading_spaces_n(line: &str, max_spaces: usize) -> &str {
let spaces_to_strip = line
.chars()
.take(max_spaces)
.take_while(|&c| c == ' ')
.count();
&line[spaces_to_strip..]
}
pub(crate) fn strip_leading_spaces(line: &str) -> &str {
strip_leading_spaces_n(line, 3)
}
pub(crate) fn strip_newline(line: &str) -> (&str, &str) {
if let Some(content) = line.strip_suffix("\r\n") {
(content, "\r\n")
} else if let Some(content) = line.strip_suffix('\n') {
(content, "\n")
} else {
(line, "")
}
}
pub(crate) fn split_lines_inclusive(input: &str) -> Vec<&str> {
if input.is_empty() {
return vec![];
}
let mut lines = Vec::new();
let mut start = 0;
let bytes = input.as_bytes();
let len = bytes.len();
let mut i = 0;
while i < len {
if bytes[i] == b'\n' {
lines.push(&input[start..=i]);
start = i + 1;
i += 1;
} else if bytes[i] == b'\r' && i + 1 < len && bytes[i + 1] == b'\n' {
lines.push(&input[start..=i + 1]);
start = i + 2;
i += 2;
} else {
i += 1;
}
}
if start < len {
lines.push(&input[start..]);
}
lines
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_strip_leading_spaces_n() {
assert_eq!(strip_leading_spaces_n(" text", 3), "text");
assert_eq!(strip_leading_spaces_n(" text", 3), "text");
assert_eq!(strip_leading_spaces_n(" text", 3), "text");
assert_eq!(strip_leading_spaces_n("text", 3), "text");
assert_eq!(strip_leading_spaces_n(" text", 3), " text");
}
#[test]
fn test_strip_newline() {
assert_eq!(strip_newline("text\n"), ("text", "\n"));
assert_eq!(strip_newline("text\r\n"), ("text", "\r\n"));
assert_eq!(strip_newline("text"), ("text", ""));
}
}