139 lines
3.0 KiB
Go
139 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"os"
|
|
"sort"
|
|
"strings"
|
|
"sync"
|
|
"github.com/charmbracelet/bubbles/list"
|
|
)
|
|
|
|
type Ranking struct {
|
|
items []string
|
|
indexes []int
|
|
scores []float64
|
|
}
|
|
|
|
func (r Ranking) Len() int { return len(r.items) }
|
|
func (r Ranking) Swap(i, j int) {
|
|
r.indexes[i], r.indexes[j] = r.indexes[j], r.indexes[i]
|
|
}
|
|
func (r Ranking) Less(i, j int) bool {
|
|
return r.scores[r.indexes[i]] > r.scores[r.indexes[j]]
|
|
}
|
|
|
|
// Function to compute the score for a given string
|
|
func computeScore(term string, s string) float64 {
|
|
term = strings.ToLower(term)
|
|
a := strings.ToLower(s)
|
|
splits := strings.Split(a, "/")
|
|
term_splits := strings.Split(term, "/")
|
|
|
|
score := 1.0 / float64(len(splits))
|
|
for _, term := range term_splits {
|
|
for i, c := range splits {
|
|
if len(term) == 0 {
|
|
continue
|
|
}
|
|
if strings.Contains(c, term) {
|
|
score += 1.0/float64(i)
|
|
splits = splits[i:]
|
|
break
|
|
}
|
|
}
|
|
}
|
|
return score
|
|
}
|
|
|
|
func rank(term string, targets []string) []int {
|
|
scores := make([]float64, len(targets))
|
|
|
|
var wg sync.WaitGroup
|
|
scoreChan := make(chan struct {
|
|
index int
|
|
score float64
|
|
}, len(targets))
|
|
|
|
// Start a goroutine for each string to compute its score
|
|
for i, s := range targets {
|
|
wg.Add(1)
|
|
go func(i int, s string) {
|
|
defer wg.Done()
|
|
score := computeScore(term, s)
|
|
scoreChan <- struct {
|
|
index int
|
|
score float64
|
|
}{index: i, score: score}
|
|
}(i, s)
|
|
}
|
|
|
|
// Close the channel once all goroutines are done
|
|
go func() {
|
|
wg.Wait()
|
|
close(scoreChan)
|
|
}()
|
|
|
|
// Collect scores from the channel
|
|
for result := range scoreChan {
|
|
scores[result.index] = result.score
|
|
}
|
|
|
|
indexes := make([]int, len(targets))
|
|
for i := range targets {
|
|
indexes[i] = i
|
|
}
|
|
|
|
sort.Stable(Ranking{targets, indexes, scores})
|
|
return indexes
|
|
}
|
|
|
|
func Filter(term string, targets []string) []list.Rank {
|
|
indexes := rank(term, targets)
|
|
result := make([]list.Rank, len(targets))
|
|
for i := range targets {
|
|
result[i] = list.Rank{
|
|
Index: indexes[i],
|
|
MatchedIndexes: []int{},
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
func getPaths() []string {
|
|
paths := []string{}
|
|
|
|
file, err := os.Open("/home/user/.cache/fzy_paths_d")
|
|
if err != nil {
|
|
fmt.Fprintln(os.Stderr, "Error opening file:", err)
|
|
return paths
|
|
}
|
|
defer file.Close() // Ensure the file is closed when we're done
|
|
|
|
// Create a scanner to read the file line by line
|
|
scanner := bufio.NewScanner(file)
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
if len(line) == 0 {
|
|
continue
|
|
}
|
|
paths = append(paths, line)
|
|
}
|
|
|
|
// Check for errors during scanning
|
|
if err := scanner.Err(); err != nil {
|
|
fmt.Fprintln(os.Stderr, "Error reading file:", err)
|
|
}
|
|
return paths
|
|
}
|
|
|
|
func getListItems() []list.Item {
|
|
items := []list.Item{}
|
|
paths := getPaths()
|
|
for _, path := range paths {
|
|
items = append(items, item{path})
|
|
}
|
|
return items
|
|
}
|