@@ -180,11 +180,6 @@ func (f *filterableGroupList[T]) inputHeight() int {
180180 return lipgloss.Height(f.inputStyle.Render(f.input.View()))
181181}
182182
183−type groupMatch[T FilterableItem] struct {
184− group Group[T]
185− score int
186−}
187−
188183func (f *filterableGroupList[T]) clearItemState() []tea.Cmd {
189184 var cmds []tea.Cmd
190185 for _, item := range slices.Collect(f.items.Seq()) {
@@ -211,25 +206,6 @@ func (f *filterableGroupList[T]) setMatchIndexes(item T, indexes []int) {
211206 }
212207}
213208
214−func (f *filterableGroupList[T]) findMatchingGroups(firstWord string) []groupMatch[T] {
215− var matchedGroups []groupMatch[T]
216− for _, g := range f.groups {
217− groupName := f.getGroupName(g)
218− matches := fuzzy.Find(firstWord, []string{groupName})
219− if len(matches) > 0 && matches[0].Score > 0 {
220− matchedGroups = append(matchedGroups, groupMatch[T]{
221− group: g,
222− score: matches[0].Score,
223− })
224− }
225− }
226− // Sort by score (higher scores first - exact matches will have higher scores)
227− sort.SliceStable(matchedGroups, func(i, j int) bool {
228− return matchedGroups[i].score > matchedGroups[j].score
229− })
230− return matchedGroups
231−}
232−
233209func (f *filterableGroupList[T]) filterItemsInGroup(group Group[T], query string) []T {
234210 if query == "" {
235211 // No query, return all items with cleared match indexes
@@ -241,24 +217,31 @@ func (f *filterableGroupList[T]) filterItemsInGroup(group Group[T], query string
241217 return items
242218 }
243219
244− // Build search words
245− words := make([]string, len(group.Items))
220+ name := f.getGroupName(group) + " "
221+
222+ names := make([]string, len(group.Items))
246223 for i, item := range group.Items {
247− words[i] = strings.ToLower(item.FilterValue())
224+ names[i] = strings.ToLower(name + item.FilterValue())
248225 }
249226
250− // Perform fuzzy search
251− matches := fuzzy.Find(query, words)
227+ matches := fuzzy.Find(query, names)
252228 sort.SliceStable(matches, func(i, j int) bool {
253229 return matches[i].Score > matches[j].Score
254230 })
255231
256232 if len(matches) > 0 {
257− // Found matches, return only those with highlights
258233 var matchedItems []T
259234 for _, match := range matches {
260235 item := group.Items[match.Index]
261− f.setMatchIndexes(item, match.MatchedIndexes)
236+ var idxs []int
237+ for _, idx := range match.MatchedIndexes {
238+ // adjusts removing group name highlights
239+ if idx < len(name) {
240+ continue
241+ }
242+ idxs = append(idxs, idx-len(name))
243+ }
244+ f.setMatchIndexes(item, idxs)
262245 matchedItems = append(matchedItems, item)
263246 }
264247 return matchedItems
@@ -267,20 +250,6 @@ func (f *filterableGroupList[T]) filterItemsInGroup(group Group[T], query string
267250 return []T{}
268251}
269252
270−func (f *filterableGroupList[T]) searchAllGroups(query string) []Group[T] {
271− var newGroups []Group[T]
272− for _, g := range f.groups {
273− matchedItems := f.filterItemsInGroup(g, query)
274− if len(matchedItems) > 0 {
275− newGroups = append(newGroups, Group[T]{
276− Section: g.Section,
277− Items: matchedItems,
278− })
279− }
280− }
281− return newGroups
282−}
283−
284253func (f *filterableGroupList[T]) Filter(query string) tea.Cmd {
285254 cmds := f.clearItemState()
286255 f.selectedItem = ""
@@ -289,51 +258,24 @@ func (f *filterableGroupList[T]) Filter(query string) tea.Cmd {
289258 return f.groupedList.SetGroups(f.groups)
290259 }
291260
292− lowerQuery := strings.ToLower(query)
293− queryWords := strings.Fields(lowerQuery)
294− firstWord := queryWords[0]
261+ query = strings.ToLower(strings.ReplaceAll(query, " ", ""))
295262
296− // Find groups that match the first word
297− matchedGroups := f.findMatchingGroups(firstWord)
298−
299− var newGroups []Group[T]
300− if len(matchedGroups) > 0 {
301− // Filter within matched groups using remaining words
302− remainingQuery := ""
303− if len(queryWords) > 1 {
304− remainingQuery = strings.Join(queryWords[1:], " ")
305− }
306−
307− for _, matchedGroup := range matchedGroups {
308− matchedItems := f.filterItemsInGroup(matchedGroup.group, remainingQuery)
309− if len(matchedItems) > 0 {
310− newGroups = append(newGroups, Group[T]{
311− Section: matchedGroup.group.Section,
312− Items: matchedItems,
313− })
314− }
263+ var result []Group[T]
264+ for _, g := range f.groups {
265+ if matches := fuzzy.Find(query, []string{f.getGroupName(g)}); len(matches) > 0 && matches[0].Score > 0 {
266+ result = append(result, g)
267+ continue
315268 }
316−
317− // add any matching items from other groups
318− allGroups := f.searchAllGroups(lowerQuery)
319− for _, g := range allGroups {
320− exists := false
321− for _, existing := range newGroups {
322− if existing.Section.ID() == g.Section.ID() {
323− exists = true
324− break
325− }
326− }
327− if !exists {
328− newGroups = append(newGroups, g)
329− }
269+ matchedItems := f.filterItemsInGroup(g, query)
270+ if len(matchedItems) > 0 {
271+ result = append(result, Group[T]{
272+ Section: g.Section,
273+ Items: matchedItems,
274+ })
330275 }
331− } else {
332− // No group matches, search all groups
333− newGroups = f.searchAllGroups(lowerQuery)
334276 }
335277
336− cmds = append(cmds, f.groupedList.SetGroups(newGroups))
278+ cmds = append(cmds, f.groupedList.SetGroups(result))
337279 return tea.Batch(cmds...)
338280}
339281