This repository has been archived by the owner on Feb 13, 2020. It is now read-only.
/
menu.go
114 lines (91 loc) · 1.95 KB
/
menu.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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Copyright 2016 Albert Nigmatzianov. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package ui
import (
"bytes"
"sort"
"strconv"
"strings"
"github.com/fatih/color"
)
var (
output bytes.Buffer
newlineItem = MenuItem{
Desc: "",
}
quitItem = MenuItem{
Index: "q",
Desc: color.RedString("Quit"),
Run: func() { Quit() },
}
)
type Menu struct {
items []MenuItem
}
func (m *Menu) AddItems(mis ...MenuItem) {
m.items = append(m.items, mis...)
}
func (m *Menu) AddNewline() {
m.AddItems(newlineItem)
}
func (m *Menu) Clear() {
m.items = m.items[:0]
}
func (m Menu) Show() {
var choices = make(map[string]func())
m.AddItems(quitItem)
output.Reset()
for _, item := range m.items {
output.WriteString(item.String() + "\n")
if item.IsRunnable() {
choices[item.Index] = item.Run
}
}
Say(output.String())
choose(choices)
}
func choose(choices map[string]func()) {
var index = Ask("Enter option:")
var chosen = choices[index]
Newline()
for {
if chosen != nil {
chosen()
break
} else {
var keys []string
for k := range choices {
keys = append(keys, k)
}
keys = sortKeys(keys)
index = Ask("You must choose one of [" + strings.Join(keys, ", ") + "] :")
chosen = choices[index]
}
}
}
func sortKeys(keys []string) []string {
// find numeric keys
var numKeys []int
var stringKeys []string
for _, v := range keys {
vNum, err := strconv.Atoi(v)
if err != nil {
stringKeys = append(stringKeys, v)
continue
}
numKeys = append(numKeys, vNum)
}
// sort keys
sort.IntSlice(numKeys).Sort()
sort.StringSlice(stringKeys).Sort()
// convert numeric keys to string
sNumKeys := make([]string, 0, len(numKeys))
for _, n := range numKeys {
sNumKeys = append(sNumKeys, strconv.Itoa(n))
}
sorted := make([]string, 0, len(keys))
sorted = append(sorted, sNumKeys...)
sorted = append(sorted, stringKeys...)
return sorted
}