From 924e84b0deeebfb31384f221abbafa35cc0bc93b Mon Sep 17 00:00:00 2001 From: Roderik van der Veer Date: Sat, 30 Aug 2025 16:44:27 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20change=20command=20selection=20to=20pref?= =?UTF-8?q?er=20exact=20matches=20over=20fuzzy=20sear=E2=80=A6=20(#2314)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/tui/internal/completions/commands.go | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/packages/tui/internal/completions/commands.go b/packages/tui/internal/completions/commands.go index 2ffe3ea9..72e261f8 100644 --- a/packages/tui/internal/completions/commands.go +++ b/packages/tui/internal/completions/commands.go @@ -92,7 +92,41 @@ func (c *CommandCompletionProvider) GetChildEntries( } matches := fuzzy.RankFindFold(query, commandNames) - sort.Sort(matches) + + // Custom sort to prioritize exact matches + sort.Slice(matches, func(i, j int) bool { + // Check for exact match (case-insensitive) + iExact := strings.EqualFold(matches[i].Target, query) + jExact := strings.EqualFold(matches[j].Target, query) + + // Exact matches come first + if iExact && !jExact { + return true + } + if !iExact && jExact { + return false + } + + // Check for prefix match (case-insensitive) + iPrefix := strings.HasPrefix(strings.ToLower(matches[i].Target), strings.ToLower(query)) + jPrefix := strings.HasPrefix(strings.ToLower(matches[j].Target), strings.ToLower(query)) + + // Prefix matches come before fuzzy matches + if iPrefix && !jPrefix { + return true + } + if !iPrefix && jPrefix { + return false + } + + // Otherwise, sort by fuzzy match score (lower distance is better) + if matches[i].Distance != matches[j].Distance { + return matches[i].Distance < matches[j].Distance + } + + // If distances are equal, sort by original index (stable sort) + return matches[i].OriginalIndex < matches[j].OriginalIndex + }) // Convert matches to completion items, deduplicating by command name items := []CompletionSuggestion{}