fuzzyMatch function
Standard fuzzy matcher with scoring.
Returns null if pattern doesn't match, otherwise returns score and indices.
Implementation
RankResult? fuzzyMatch(String text, String pattern) {
if (pattern.isEmpty) return const RankResult(0, []);
final t = text.toLowerCase();
final p = pattern.toLowerCase();
int ti = 0;
final matched = <int>[];
for (var pi = 0; pi < p.length; pi++) {
final ch = p[pi];
final found = t.indexOf(ch, ti);
if (found == -1) return null;
matched.add(found);
ti = found + 1;
}
if (matched.isEmpty) return null;
// Scoring: prefer contiguous, early, word-boundary and case-exact matches
int score = 0;
// Base: more compact span is better
final span = matched.last - matched.first + 1;
score += (100000 - span * 300).clamp(0, 100000);
// Contiguity bonus
for (var i = 1; i < matched.length; i++) {
if (matched[i] == matched[i - 1] + 1) score += 1200;
}
// Early start bonus
score += (8000 - matched.first * 200).clamp(0, 8000);
// Word boundary bonus
final before = matched.first > 0 ? text[matched.first - 1] : ' ';
if (before == ' ' ||
before == '-' ||
before == '_' ||
before == '/' ||
before == '.') {
score += 2500;
}
// Exact case bonus
for (var i = 0; i < matched.length; i++) {
if (i < pattern.length && matched[i] < text.length) {
if (text[matched[i]] == pattern[i]) score += 150;
}
}
return RankResult(score, matched);
}