Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(list): allow custom filter functions #103

Merged
merged 4 commits into from
Mar 30, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 33 additions & 4 deletions list/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down