fix: merge issues

Carlos Alexandro Becker created

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

Change summary

internal/tui/exp/list/filterable_group.go | 60 +++++++++++++++++++++++++
internal/tui/exp/list/list.go             | 11 ++--
2 files changed, 65 insertions(+), 6 deletions(-)

Detailed changes

internal/tui/exp/list/filterable_group.go 🔗

@@ -193,6 +193,66 @@ func (f *filterableGroupList[T]) clearItemState() []tea.Cmd {
 	return cmds
 }
 
+func (f *filterableGroupList[T]) getGroupName(g Group[T]) string {
+	if section, ok := g.Section.(*itemSectionModel); ok {
+		return strings.ToLower(section.title)
+	}
+	return strings.ToLower(g.Section.ID())
+}
+
+func (f *filterableGroupList[T]) setMatchIndexes(item T, indexes []int) {
+	if i, ok := any(item).(HasMatchIndexes); ok {
+		i.MatchIndexes(indexes)
+	}
+}
+
+func (f *filterableGroupList[T]) filterItemsInGroup(group Group[T], query string) []T {
+	if query == "" {
+		// No query, return all items with cleared match indexes
+		var items []T
+		for _, item := range group.Items {
+			f.setMatchIndexes(item, make([]int, 0))
+			items = append(items, item)
+		}
+		return items
+	}
+
+	name := f.getGroupName(group) + " "
+
+	names := make([]string, len(group.Items))
+	for i, item := range group.Items {
+		names[i] = strings.ToLower(name + item.FilterValue())
+	}
+
+	matches := fuzzy.Find(query, names)
+	sort.SliceStable(matches, func(i, j int) bool {
+		return matches[i].Score > matches[j].Score
+	})
+
+	if len(matches) > 0 {
+		var matchedItems []T
+		for _, match := range matches {
+			item := group.Items[match.Index]
+			var idxs []int
+			for _, idx := range match.MatchedIndexes {
+				// adjusts removing group name highlights
+				if idx < len(name) {
+					continue
+				}
+				idxs = append(idxs, idx-len(name))
+			}
+			f.setMatchIndexes(item, idxs)
+			matchedItems = append(matchedItems, item)
+		}
+		return matchedItems
+	}
+
+	return []T{}
+}
+
+func (f *filterableGroupList[T]) Filter(query string) tea.Cmd {
+	cmds := f.clearItemState()
+
 	if query == "" {
 		return f.groupedList.SetGroups(f.groups)
 	}

internal/tui/exp/list/list.go 🔗

@@ -15,7 +15,6 @@ import (
 	"github.com/charmbracelet/lipgloss/v2"
 	uv "github.com/charmbracelet/ultraviolet"
 	"github.com/charmbracelet/x/ansi"
-	"github.com/charmbracelet/x/exp/ordered"
 	"github.com/rivo/uniseg"
 )
 
@@ -556,7 +555,7 @@ func (l *list[T]) viewPosition() (int, int) {
 		// Ensure offset doesn't exceed the maximum valid offset
 		maxOffset := max(0, l.virtualHeight-l.height)
 		actualOffset := min(l.offset, maxOffset)
-		
+
 		start = actualOffset
 		if l.virtualHeight > 0 {
 			end = min(actualOffset+l.height-1, l.virtualHeight-1)
@@ -569,7 +568,7 @@ func (l *list[T]) viewPosition() (int, int) {
 			// Ensure offset doesn't exceed the maximum valid offset
 			maxOffset := max(0, l.virtualHeight-l.height)
 			actualOffset := min(l.offset, maxOffset)
-			
+
 			end = l.virtualHeight - actualOffset - 1
 			start = max(0, end-l.height+1)
 		} else {
@@ -1031,10 +1030,10 @@ func (l *list[T]) renderVirtualScrolling() string {
 		linesAdded := 0
 		maxLinesToAdd := len(itemLines) - startLine
 		for i := 0; i < maxLinesToAdd && len(lines) < l.height; i++ {
-			lines = append(lines, itemLines[startLine + i])
+			lines = append(lines, itemLines[startLine+i])
 			linesAdded++
 		}
-		
+
 		// Update currentLine to track our position in virtual space
 		if vis.pos.start < viewStart {
 			// Item started before viewport, we're now at viewStart + linesAdded
@@ -1047,7 +1046,7 @@ func (l *list[T]) renderVirtualScrolling() string {
 
 	// For content that fits entirely in viewport, don't pad with empty lines
 	// Only pad if we have scrolled or if content is larger than viewport
-	
+
 	if l.virtualHeight > l.height || l.offset > 0 {
 		// Fill remaining viewport with empty lines if needed
 		initialLen := len(lines)