diff --git a/list/list.go b/list/list.go index 156c54a9..4e2ec2d2 100644 --- a/list/list.go +++ b/list/list.go @@ -71,6 +71,34 @@ func (f filteredItems) items() []Item { // message should be routed to Update for processing. type FilterMatchesMsg []filteredItem +// FilterFunc takes a term and a list of strings to search through +// (defined by Item#FilterValue). +// It should return a sorted list of ranks. +type FilterFunc func(string, []string) []Rank + +// Rank defines a rank for a given item. +type Rank struct { + // The index of the item in the original input. + Index int + // Indices of the actual word that were matched against the filter term. + MatchedIndexes []int +} + +// DefaultFilter uses the sahilm/fuzzy to filter through the list. +// This is set by default. +func DefaultFilter(term string, targets []string) []Rank { + var ranks fuzzy.Matches = fuzzy.Find(term, targets) + sort.Stable(ranks) + result := make([]Rank, len(ranks)) + for i, r := range ranks { + result[i] = Rank{ + Index: r.Index, + MatchedIndexes: r.MatchedIndexes, + } + } + return result +} + type statusMessageTimeoutMsg struct{} // FilterState describes the current filtering state on the model. @@ -107,6 +135,9 @@ type Model struct { // Key mappings for navigating the list. KeyMap KeyMap + // Filter is used to filter the list. + Filter FilterFunc + disableQuitKeybindings bool // Additional key mappings for the short and full help views. This allows @@ -173,6 +204,7 @@ func New(items []Item, delegate ItemDelegate, width, height int) Model { showHelp: true, filteringEnabled: true, KeyMap: DefaultKeyMap(), + Filter: DefaultFilter, Styles: styles, Title: "List", FilterInput: filterInput, @@ -1133,11 +1165,8 @@ func filterItems(m Model) tea.Cmd { targets = append(targets, t.FilterValue()) } - var ranks fuzzy.Matches = fuzzy.Find(m.FilterInput.Value(), targets) - sort.Stable(ranks) - filterMatches := []filteredItem{} - for _, r := range ranks { + for _, r := range m.Filter(m.FilterInput.Value(), targets) { filterMatches = append(filterMatches, filteredItem{ item: items[r.Index], matches: r.MatchedIndexes,