fzf/src/item.go

111 lines
2.0 KiB
Go
Raw Normal View History

2015-01-01 14:49:30 -05:00
package fzf
2015-01-11 13:01:24 -05:00
// Offset holds two 32-bit integers denoting the offsets of a matched substring
2015-01-08 12:37:08 -05:00
type Offset [2]int32
2015-01-01 14:49:30 -05:00
2015-01-11 13:01:24 -05:00
// Item represents each input line
2015-01-01 14:49:30 -05:00
type Item struct {
text *string
origText *string
transformed *Transformed
index uint32
2015-01-01 14:49:30 -05:00
offsets []Offset
rank Rank
}
2015-01-11 13:01:24 -05:00
// Rank is used to sort the search result
2015-01-08 12:37:08 -05:00
type Rank struct {
matchlen uint16
strlen uint16
index uint32
}
2015-01-01 14:49:30 -05:00
2015-01-11 13:01:24 -05:00
// Rank calculates rank of the Item
func (i *Item) Rank(cache bool) Rank {
if cache && (i.rank.matchlen > 0 || i.rank.strlen > 0) {
2015-01-01 14:49:30 -05:00
return i.rank
}
matchlen := 0
prevEnd := 0
for _, offset := range i.offsets {
2015-01-08 12:37:08 -05:00
begin := int(offset[0])
end := int(offset[1])
2015-01-01 14:49:30 -05:00
if prevEnd > begin {
begin = prevEnd
}
if end > prevEnd {
prevEnd = end
}
if end > begin {
matchlen += end - begin
}
}
rank := Rank{uint16(matchlen), uint16(len(*i.text)), i.index}
if cache {
i.rank = rank
}
return rank
2015-01-01 14:49:30 -05:00
}
2015-01-11 13:01:24 -05:00
// AsString returns the original string
func (i *Item) AsString() string {
2015-01-01 14:49:30 -05:00
if i.origText != nil {
2015-01-11 13:01:24 -05:00
return *i.origText
2015-01-01 14:49:30 -05:00
}
2015-01-11 13:01:24 -05:00
return *i.text
2015-01-01 14:49:30 -05:00
}
2015-01-11 13:01:24 -05:00
// ByOrder is for sorting substring offsets
2015-01-01 14:49:30 -05:00
type ByOrder []Offset
func (a ByOrder) Len() int {
return len(a)
}
func (a ByOrder) Swap(i, j int) {
a[i], a[j] = a[j], a[i]
}
func (a ByOrder) Less(i, j int) bool {
ioff := a[i]
joff := a[j]
return (ioff[0] < joff[0]) || (ioff[0] == joff[0]) && (ioff[1] <= joff[1])
}
2015-01-11 13:01:24 -05:00
// ByRelevance is for sorting Items
2015-01-01 14:49:30 -05:00
type ByRelevance []*Item
func (a ByRelevance) Len() int {
return len(a)
}
func (a ByRelevance) Swap(i, j int) {
a[i], a[j] = a[j], a[i]
}
func (a ByRelevance) Less(i, j int) bool {
irank := a[i].Rank(true)
jrank := a[j].Rank(true)
2015-01-01 14:49:30 -05:00
return compareRanks(irank, jrank)
}
func compareRanks(irank Rank, jrank Rank) bool {
2015-01-08 12:37:08 -05:00
if irank.matchlen < jrank.matchlen {
return true
} else if irank.matchlen > jrank.matchlen {
return false
}
if irank.strlen < jrank.strlen {
return true
} else if irank.strlen > jrank.strlen {
return false
}
if irank.index <= jrank.index {
return true
2015-01-01 14:49:30 -05:00
}
2015-01-08 12:37:08 -05:00
return false
2015-01-01 14:49:30 -05:00
}