Skip to content

Commit 62c0116

Browse files
committed
[new] tip when input
1 parent e61df9e commit 62c0116

7 files changed

Lines changed: 164 additions & 20 deletions

File tree

IntegrationTesting.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env bash
2+
set -ev
3+
go build
4+
./goto add test "http://example.com"
5+
./goto add test test test "http://baidu.com"
6+
./goto get test test test
7+
./goto get test
8+
./goto list tes

alfred/const.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,7 @@ type Mod struct {
3232
Icon *Icon `json:"icon,omitempty"` //From Alfred 3.4.1
3333
Variables map[string]string `json:"variables,omitempty"` //From Alfred 3.4.1
3434
}
35+
36+
type Output struct {
37+
Items []*Item `json:"items"`
38+
}

alfred/output.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
package alfred
22

3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"log"
7+
)
8+
39
func NewSimpleItem(title, subTitle, arg, autoComplete string) *Item {
410
return &Item{
511
Title: title,
@@ -8,3 +14,24 @@ func NewSimpleItem(title, subTitle, arg, autoComplete string) *Item {
814
Autocomplete: autoComplete,
915
}
1016
}
17+
18+
func NewOutput() *Output {
19+
return &Output{}
20+
}
21+
22+
func (o *Output) AddSimpleTip(title, subTitle, arg, autoComplete string) {
23+
o.AddTip(NewSimpleItem(title, subTitle, arg, autoComplete))
24+
}
25+
26+
func (o *Output) AddTip(item *Item) {
27+
o.Items = append(o.Items, item)
28+
}
29+
30+
func (o *Output) Show() {
31+
text, err := json.Marshal(o)
32+
if err != nil {
33+
log.Fatalf("json marshal err:%s raw:%+v ", err.Error(), o)
34+
return
35+
}
36+
fmt.Println(string(text))
37+
}

config/config.go

Lines changed: 73 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package config
33
import (
44
"gopkg.in/yaml.v2"
55
"io/ioutil"
6+
"log"
67
"os"
78
"reflect"
89
"strings"
@@ -11,8 +12,9 @@ import (
1112
type ModelType int
1213

1314
const (
14-
configName = "config.yaml"
15-
LoopBackKey = "@"
15+
configName = "config.yaml"
16+
LoopBackKey = "@"
17+
TipSeparator = ", "
1618

1719
TypeUnknown ModelType = iota
1820
TypeVector
@@ -58,13 +60,61 @@ func (n *Nest) AddScalar(paths []string, url string) {
5860
addScalar(n.Data, paths, url)
5961
}
6062

63+
//alfred
64+
func (n *Nest) ListWithPre(paths []string) map[string]string {
65+
switch len(paths) {
66+
case 0:
67+
return findMapPrefix(n.Data, "")
68+
case 1:
69+
return findMapPrefix(n.Data, paths[0])
70+
default:
71+
out, ok := getByPath(paths[:len(paths)-1], n.Data)
72+
if !ok {
73+
return nil
74+
}
75+
m, ok := out.(map[string]interface{})
76+
if !ok {
77+
return nil
78+
}
79+
return findMapPrefix(m, paths[len(paths)-1])
80+
81+
}
82+
83+
return nil
84+
}
85+
86+
func findMapPrefix(m map[string]interface{}, pre string) map[string]string {
87+
found := make(map[string]string)
88+
for k, v := range m {
89+
if strings.HasPrefix(k, pre) {
90+
switch typeOf(v) {
91+
case TypeVector:
92+
found[k] = extractKeys(v.(map[string]interface{}))
93+
case TypeScalar:
94+
found[k] = v.(string)
95+
}
96+
}
97+
}
98+
return found
99+
}
100+
101+
func extractKeys(m map[string]interface{}) string {
102+
out := ""
103+
for k, _ := range m {
104+
out += k + TipSeparator
105+
}
106+
out = strings.TrimSuffix(out, TipSeparator)
107+
return out
108+
}
109+
61110
func typeOf(i interface{}) ModelType {
62111
switch reflect.TypeOf(i).Kind() {
63112
case reflect.Map:
64113
return TypeVector
65114
case reflect.String:
66115
return TypeScalar
67116
default:
117+
log.Print("WARNNIG unknown type" + reflect.TypeOf(i).Kind().String())
68118
return TypeUnknown
69119
}
70120
}
@@ -131,31 +181,39 @@ func addScalar(m map[string]interface{}, paths []string, url string) map[string]
131181

132182
//get the specified URL
133183
func getScalar(paths []string, m map[string]interface{}) (scalar string, ok bool) {
134-
if len(paths) == 0 {
184+
if len(paths) == 0 || len(m) == 0 {
135185
return
136186
}
137-
value, got := m[paths[0]]
138-
if !got {
187+
v, ok := getByPath(paths, m)
188+
if !ok {
139189
return
140190
}
141-
switch typeOf(value) {
191+
switch typeOf(v) {
142192
case TypeScalar:
143-
return value.(string), true
193+
return v.(string), true
144194
case TypeVector:
145-
if len(paths) == 1 {
146-
v, ok := value.(map[string]interface{})[LoopBackKey]
147-
if ok {
148-
return v.(string), true
149-
} else {
150-
return "", false
151-
}
195+
v, ok := v.(map[string]interface{})[LoopBackKey]
196+
if ok {
197+
return v.(string), true
198+
} else {
199+
return "", false
152200
}
153-
return getScalar(paths[1:], value.(map[string]interface{}))
154201
default:
155202
return
156203
}
157204
}
158205

206+
func getByPath(paths []string, m map[string]interface{}) (out interface{}, ok bool) {
207+
if len(paths) == 0 || len(m) == 0 {
208+
return
209+
}
210+
out, ok = m[paths[0]]
211+
if !ok || len(paths) == 1 {
212+
return
213+
}
214+
return getByPath(paths[1:], out.(map[string]interface{}))
215+
}
216+
159217
//convert map[interface{}]intreface{} to map[string]interface{}
160218
func toMapStringInterface(m map[interface{}]interface{}) map[string]interface{} {
161219
nm := make(map[string]interface{})

config/config_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,31 @@ import (
55
"testing"
66
)
77

8+
var testNest = Nest{
9+
Data: map[string]interface{}{
10+
"keyA": "123",
11+
"keyB": "123",
12+
"keyC": "123",
13+
"keyD": map[string]interface{}{
14+
"keyA": "123",
15+
"keyB": "123",
16+
},
17+
"keyE": map[string]interface{}{
18+
"keyA": "123",
19+
"keyB": "123",
20+
"keyC": map[string]interface{}{
21+
"keyA": "123",
22+
"keyB": "123",
23+
},
24+
},
25+
},
26+
}
27+
28+
func TestNest_ListWithPre(t *testing.T) {
29+
out := testNest.ListWithPre([]string{"keyE", "keyA"})
30+
println(out)
31+
}
32+
833
func Test_typeOf(t *testing.T) {
934
type args struct {
1035
i interface{}

handler/common.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
package handler
22

33
const (
4-
add = "add"
5-
get = "get"
4+
add = "add"
5+
get = "get"
6+
list = "list"
7+
show = "show"
68
)
79

810
var handlers = map[string]func(args []string){
9-
add: Add,
10-
get: Get,
11+
add: Add,
12+
get: Get,
13+
list: List,
14+
show: Show,
1115
}
1216

1317
func GetHandler(name string) func(args []string) {

handler/list.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
package handler
22

3-
func List(args []string) {
3+
import (
4+
"github.com/Huweicai/goto/alfred"
5+
"github.com/Huweicai/goto/config"
6+
"log"
7+
"strings"
8+
)
49

10+
func List(args []string) {
11+
nest, err := config.NewNest(config.GetConfigPath())
12+
if err != nil {
13+
log.Fatalf(err.Error())
14+
return
15+
}
16+
outKV := nest.ListWithPre(args)
17+
output := alfred.NewOutput()
18+
for k, v := range outKV {
19+
arg := strings.Join(append(args[:len(args)-1], k), " ")
20+
output.AddSimpleTip(k, v, arg, arg)
21+
}
22+
output.Show()
523
}

0 commit comments

Comments
 (0)