-
Notifications
You must be signed in to change notification settings - Fork 8
/
prompt.go
88 lines (78 loc) · 2.55 KB
/
prompt.go
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
85
86
87
88
package main
import (
"fmt"
"github.com/agnivade/levenshtein"
"github.com/manifoldco/promptui"
"sort"
"strings"
)
const FinishedAddress = "Finished"
func prompt(sources map[Resource]bool, destinations map[Resource]bool) (Resource, Resource, error) {
srcTempl := &promptui.SelectTemplates{
Label: "{{ . }}",
Active: "\U0000261E {{ .Address | cyan | underline }} ({{ .Type | red }})",
Inactive: " {{ .Address | cyan }} ({{ .Type | red }})",
Selected: "{{ .Address }}",
}
srcs := append(toSlice(sources), Resource{FinishedAddress, "no more resources to move"})
srcSearcher := func(input string, index int) bool {
if index >= len(srcs) {
return false
}
resource := srcs[index]
return strings.Contains(resource.Address, input)
}
prompt := promptui.Select{Label: "Select Source", Items: srcs, Templates: srcTempl, Searcher: srcSearcher, StartInSearchMode: true}
i, _, err := prompt.Run()
var empty Resource
if err != nil {
return empty, empty, err
}
if i == len(srcs)-1 {
return empty, empty, nil
}
src := srcs[i]
dests := toSlice(destinations)
var compatDests []Resource
for _, r := range dests {
if r.Type == src.Type {
compatDests = append(compatDests, r)
}
}
destSearcher := func(input string, index int) bool {
resource := compatDests[index]
return strings.Contains(resource.Address, input)
}
sortByLevenshteinDistance(compatDests, src)
fmt.Println(strings.Repeat(" ", len(src.Address)), "↘")
spaces := strings.Repeat(" ", len(src.Address)+3)
destTempl := &promptui.SelectTemplates{
Label: spaces + "{{ . }}",
Active: spaces + "\U0000261E {{ .Address | cyan | underline }} ({{ .Type | red }})",
Inactive: spaces + " {{ .Address | cyan }} ({{ .Type | red }})",
Selected: spaces + "{{ .Address }}",
}
prompt = promptui.Select{Label: "Select Destination", Items: compatDests, Templates: destTempl, Searcher: destSearcher, StartInSearchMode: true}
j, _, err := prompt.Run()
if err != nil {
return Resource{}, Resource{}, err
}
return src, compatDests[j], nil
}
func sortByLevenshteinDistance(dests []Resource, src Resource) {
sort.Slice(dests, func(i, j int) bool {
distanceToItemI := levenshtein.ComputeDistance(src.Address, dests[i].Address)
distanceToItemJ := levenshtein.ComputeDistance(src.Address, dests[j].Address)
if distanceToItemI != distanceToItemJ {
return distanceToItemI < distanceToItemJ
}
return dests[i].Address < dests[j].Address
})
}
func toSlice(set map[Resource]bool) []Resource {
result := []Resource{}
for elem := range set {
result = append(result, elem)
}
return result
}