summaryrefslogtreecommitdiffstats
path: root/pkg/gui/context/filtered_list.go
blob: bffd0eddbe9e9fcc5eb46f1c39086346e4c92f03 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package context

import (
	"github.com/jesseduffield/lazygit/pkg/utils"
)

type FilteredList[T any] struct {
	filteredIndices []int // if nil, we are not filtering

	getList         func() []T
	getFilterFields func(T) []string
	filter          string
}

func NewFilteredList[T any](getList func() []T, getFilterFields func(T) []string) *FilteredList[T] {
	return &FilteredList[T]{
		getList:         getList,
		getFilterFields: getFilterFields,
	}
}

func (self *FilteredList[T]) GetFilter() string {
	return self.filter
}

func (self *FilteredList[T]) SetFilter(filter string) {
	self.filter = filter

	self.applyFilter()
}

func (self *FilteredList[T]) ClearFilter() {
	self.SetFilter("")
}

func (self *FilteredList[T]) IsFiltering() bool {
	return self.filter != ""
}

func (self *FilteredList[T]) GetFilteredList() []T {
	if self.filteredIndices == nil {
		return self.getList()
	}
	return utils.ValuesAtIndices(self.getList(), self.filteredIndices)
}

// TODO: update to just 'Len'
func (self *FilteredList[T]) UnfilteredLen() int {
	return len(self.getList())
}

func (self *FilteredList[T]) applyFilter() {
	if self.filter == "" {
		self.filteredIndices = nil
	} else {
		self.filteredIndices = []int{}
		for i, item := range self.getList() {
			for _, field := range self.getFilterFields(item) {
				if self.match(field, self.filter) {
					self.filteredIndices = append(self.filteredIndices, i)
					break
				}
			}
		}
	}
}

func (self *FilteredList[T]) match(haystack string, needle string) bool {
	return utils.CaseInsensitiveContains(haystack, needle)
}

func (self *FilteredList[T]) UnfilteredIndex(index int) int {
	if self.filteredIndices == nil {
		return index
	}

	// we use -1 when there are no items
	if index == -1 {
		return -1
	}

	// TODO: mutex
	return self.filteredIndices[index]
}