mirror of
https://github.com/astral-sh/ruff
synced 2026-01-22 14:00:51 -05:00
# Summary We need to support CR line endings (as opposed to LF and CRLF line endings, which are already supported). They're rare, but they do appear in Python code, and we tend to panic on any file that uses them. Our `Locator` abstraction now supports CR line endings. However, Rust's `str#lines` implementation does _not_. This PR adds a `UniversalNewlineIterator` implementation that respects all of CR, LF, and CRLF line endings, and plugs it into most of the `.lines()` call sites. As an alternative design, it could be nice if we could leverage `Locator` for this. We've already computed all of the line endings, so we could probably iterate much more efficiently? # Test Plan Largely relying on automated testing, however, also ran over some known failure cases, like #3404.
40 lines
1.2 KiB
Rust
40 lines
1.2 KiB
Rust
use rustpython_parser::ast::{Located, Location};
|
|
|
|
use crate::source_code::Locator;
|
|
use crate::types::Range;
|
|
|
|
/// Extract the leading indentation from a line.
|
|
pub fn indentation<'a, T>(locator: &'a Locator, located: &'a Located<T>) -> Option<&'a str> {
|
|
let range = Range::from(located);
|
|
let indentation = locator.slice(Range::new(
|
|
Location::new(range.location.row(), 0),
|
|
Location::new(range.location.row(), range.location.column()),
|
|
));
|
|
if indentation.chars().all(char::is_whitespace) {
|
|
Some(indentation)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
/// Extract the leading words from a line of text.
|
|
pub fn leading_words(line: &str) -> &str {
|
|
let line = line.trim();
|
|
line.find(|char: char| !char.is_alphanumeric() && !char.is_whitespace())
|
|
.map_or(line, |index| &line[..index])
|
|
}
|
|
|
|
/// Extract the leading whitespace from a line of text.
|
|
pub fn leading_space(line: &str) -> &str {
|
|
line.find(|char: char| !char.is_whitespace())
|
|
.map_or(line, |index| &line[..index])
|
|
}
|
|
|
|
/// Replace any non-whitespace characters from an indentation string.
|
|
pub fn clean(indentation: &str) -> String {
|
|
indentation
|
|
.chars()
|
|
.map(|char| if char.is_whitespace() { char } else { ' ' })
|
|
.collect()
|
|
}
|