macOS: Support initials matching in command palette search

Extend String.matchedIndices(for:) to fall back to initials
matching when no substring match is found. Typing the first letter
of each word now matches commands, e.g. "tbo" matches "Toggle
Background Opacity", with each matched initial highlighted.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Lukas
2026-04-13 11:44:18 +02:00
parent 2bdc6bb1f7
commit 2e169c42e8

View File

@@ -460,15 +460,31 @@ private struct ShortcutSymbolsView: View {
}
extension String {
/// Returns the character indices that match `query`
/// Returns the character indices that match `query`, trying a substring match first,
/// then falling back to initials matching (first letter of each word).
/// - Returns: `nil` if neither matches.
func matchedIndices(for query: String) -> [String.Index]? {
guard !query.isEmpty else { return nil }
// Prefer substring match.
if let range = self.range(of: query, options: .caseInsensitive) {
return Array(self[range].indices)
}
return nil
// Fall back to initials match.
let words = self.split(whereSeparator: \.isWhitespace)
var queryIndex = query.startIndex
var matched: [String.Index] = []
for word in words {
guard queryIndex < query.endIndex else { break }
if word.first?.lowercased() == query[queryIndex].lowercased() {
matched.append(word.startIndex)
queryIndex = query.index(after: queryIndex)
}
}
return queryIndex == query.endIndex ? matched : nil
}
}