C14.13 r1: query and line fold case the same way; final sigma folds to sigma
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
cd0c740ded
commit
b80bf48ccd
3 files changed
+27
-8
No files matched your search
@@ -54,22 +54,27 @@ pub struct Hit {
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
/// Where lowercase `query` starts in `line`, in characters.
|
||||
/// `ch` without case; final sigma folds as Unicode does.
|
||||
fn fold(ch: char) -> impl Iterator<Item = char> {
|
||||
ch.to_lowercase().map(|low| if low == 'ς' { 'σ' } else { low })
|
||||
}
|
||||
|
||||
/// Where folded `query` starts in `line`, in characters.
|
||||
fn column_of(line: &str, query: &str) -> Option<usize> {
|
||||
// Each lowered byte keeps its character's place.
|
||||
let (mut lowered, mut places) = (String::new(), Vec::new());
|
||||
// Each folded byte keeps its character's place.
|
||||
let (mut folded, mut places) = (String::new(), Vec::new());
|
||||
for (place, ch) in line.chars().enumerate() {
|
||||
for low in ch.to_lowercase() {
|
||||
lowered.push(low);
|
||||
for low in fold(ch) {
|
||||
folded.push(low);
|
||||
places.extend(std::iter::repeat_n(place, low.len_utf8()));
|
||||
}
|
||||
}
|
||||
lowered.find(query).map(|at| places[at])
|
||||
folded.find(query).map(|at| places[at])
|
||||
}
|
||||
|
||||
/// Lines of `text` holding `query`, any case.
|
||||
pub fn lines_with(file: &Path, text: &str, query: &str, hits: &mut Vec<Hit>) {
|
||||
let query = query.to_lowercase();
|
||||
let query: String = query.chars().flat_map(fold).collect();
|
||||
for (at, line) in text.lines().enumerate() {
|
||||
if hits.len() == MOST_HITS {
|
||||
return;
|
||||
@@ -136,4 +141,15 @@ mod tests {
|
||||
assert_eq!(super::column_of("中文 搜索", "搜索"), Some(3));
|
||||
assert_eq!(super::column_of("none", "word"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sigma_matches_in_every_form() {
|
||||
for line in ["ΟΣ", "οσ", "ος"] {
|
||||
for query in ["ΟΣ", "οσ", "ος"] {
|
||||
let mut hits = Vec::new();
|
||||
super::lines_with(Path::new("a.md"), line, query, &mut hits);
|
||||
assert_eq!(hits.len(), 1, "{query} in {line}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user