fuzzyMatch function

RankResult? fuzzyMatch(
  1. String text,
  2. String pattern
)

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);
}