matchCommandPaletteItems function

List<CommandPaletteMatch> matchCommandPaletteItems(
  1. List<CommandPaletteItem> items,
  2. String query
)

Filters and ranks items using the established palette matching contract.

Implementation

List<CommandPaletteMatch> matchCommandPaletteItems(
  List<CommandPaletteItem> items,
  String query,
) {
  final normalizedQuery = query.trim().toLowerCase();
  final matches = <CommandPaletteMatch>[];
  for (var index = 0; index < items.length; index++) {
    final item = items[index];
    if (!item.enabled) continue;
    final evidence = <String, double>{};
    final label = item.label.toLowerCase();
    final description = item.description?.toLowerCase();
    final group = item.group?.toLowerCase();
    double score = 0;
    if (normalizedQuery.isEmpty) {
      evidence['query:empty'] = 1;
    } else {
      if (label == normalizedQuery) {
        score += 10000;
        evidence['label:exact'] = 10000;
      }
      if (label.startsWith(normalizedQuery)) {
        score += 6000;
        evidence['label:prefix'] = 6000;
      }
      if (label.contains(normalizedQuery)) {
        score += 4000;
        evidence['label:contains'] = 4000;
      }
      if (description?.contains(normalizedQuery) ?? false) {
        score += 1800;
        evidence['description:contains'] = 1800;
      }
      if (group?.contains(normalizedQuery) ?? false) {
        score += 1200;
        evidence['group:contains'] = 1200;
      }
      for (final tag in item.tags) {
        final normalizedTag = tag.toLowerCase();
        if (normalizedTag == normalizedQuery) {
          score += 2200;
          evidence['tag:exact'] = 2200;
          break;
        }
        if (normalizedTag.contains(normalizedQuery)) {
          score += 1500;
          evidence['tag:contains'] = 1500;
          break;
        }
      }
      final subsequence = _subsequenceScore(normalizedQuery, label);
      if (subsequence > 0) {
        score += subsequence;
        evidence['label:subsequence'] = subsequence;
      }
      final typo = _typoScore(normalizedQuery, label);
      if (typo > 0) {
        score += typo;
        evidence['label:typo'] = typo;
      }
    }
    if (normalizedQuery.isEmpty || score > 0) {
      matches.add(
        CommandPaletteMatch(
          item: item,
          score: score,
          evidence: Map<String, double>.unmodifiable(evidence),
          originalIndex: index,
        ),
      );
    }
  }
  matches.sort((left, right) {
    if (normalizedQuery.isEmpty) {
      return left.originalIndex.compareTo(right.originalIndex);
    }
    final score = right.score.compareTo(left.score);
    if (score != 0) return score;
    final label = left.item.label.compareTo(right.item.label);
    return label != 0
        ? label
        : left.originalIndex.compareTo(right.originalIndex);
  });
  return List<CommandPaletteMatch>.unmodifiable(matches);
}