From f5415908291cbb713943aa5f42b3f9e54a5cfa1c Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Mon, 5 Jan 2026 16:09:41 -0500 Subject: [PATCH] feat(ui): models dialog: filter by provider and model name --- internal/ui/dialog/models_list.go | 44 +++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/internal/ui/dialog/models_list.go b/internal/ui/dialog/models_list.go index 4cba59d0f8d33b6f7affa98603bfeed1de29cfa2..e7a7303536e701424d29aa049af91cf977e8318a 100644 --- a/internal/ui/dialog/models_list.go +++ b/internal/ui/dialog/models_list.go @@ -1,7 +1,10 @@ package dialog import ( + "fmt" "slices" + "sort" + "strings" "github.com/charmbracelet/crush/internal/ui/list" "github.com/charmbracelet/crush/internal/ui/styles" @@ -186,16 +189,21 @@ func (f *ModelsList) VisibleItems() []list.Item { } } - matches := fuzzy.FindFrom(f.query, list.FilterableItemsSource(filterableItems)) - for _, match := range matches { - item := filterableItems[match.Index] - if ms, ok := item.(list.MatchSettable); ok { - ms.SetMatch(match) - item = ms.(list.FilterableItem) - } - filterableItems = append(filterableItems, item) + filterValue := func(itm *ModelItem) string { + return strings.ToLower(fmt.Sprintf("%s %s", itm.prov.Name, itm.model.Name)) + } + + names := make([]string, len(filterableItems)) + for i, item := range filterableItems { + ms := item.(*ModelItem) + names[i] = filterValue(ms) } + matches := fuzzy.Find(f.query, names) + sort.SliceStable(matches, func(i, j int) bool { + return matches[i].Score > matches[j].Score + }) + items := []list.Item{} visitedGroups := map[int]bool{} @@ -203,19 +211,27 @@ func (f *ModelsList) VisibleItems() []list.Item { // Find which group this item belongs to for gi, g := range f.groups { addedCount := 0 + name := g.Title + " " for _, match := range matches { - item := filterableItems[match.Index] - if slices.Contains(g.Items, item.(*ModelItem)) { + item := filterableItems[match.Index].(*ModelItem) + idxs := []int{} + for _, idx := range match.MatchedIndexes { + // Adjusts removing provider name highlights + if idx < len(name) { + continue + } + idxs = append(idxs, idx-len(name)) + } + + match.MatchedIndexes = idxs + if slices.Contains(g.Items, item) { if !visitedGroups[gi] { // Add section header items = append(items, &g) visitedGroups[gi] = true } // Add the matched item - if ms, ok := item.(list.MatchSettable); ok { - ms.SetMatch(match) - item = ms.(list.FilterableItem) - } + item.SetMatch(match) items = append(items, item) addedCount++ }