11package main
22
33import (
4- "encoding/json"
5- "fmt"
64 "os"
5+ "path"
76 "strings"
8- "sync"
97
10- model "github.com/pddg/alfred-models "
8+ aw "github.com/deanishe/awgo "
119 "github.com/urfave/cli"
1210)
1311
14- func main () {
12+ const (
13+ appName = "ghq-alfred"
14+ appDesc = "Search your local repos"
15+ appVersion = "0.4.0"
16+ )
17+
18+ var (
19+ wf * aw.Workflow
20+ gitHubIcon = & aw.Icon {Value : path .Join ("github-logo.png" )}
21+ bitBucketIcon = & aw.Icon {Value : path .Join ("bitbucket-logo.png" )}
22+ gitIcon = & aw.Icon {Value : path .Join ("git-logo.png" )}
23+ modKeys = []aw.ModKey {
24+ aw .ModCmd ,
25+ aw .ModOpt ,
26+ aw .ModFn ,
27+ aw .ModCtrl ,
28+ aw .ModShift ,
29+ }
30+ )
31+
32+ func init () {
33+ wf = aw .New ()
34+ }
35+
36+ func run () {
1537 app := cli .NewApp ()
16- app .Name = "ghq-alfred"
17- app .Usage = "Search your local repos"
18- app .Version = "0.3.1"
38+ app .Name = appName
39+ app .Usage = appDesc
40+ app .Version = appVersion
1941 app .Action = func (c * cli.Context ) error {
20- resp := model .NewResponse ()
2142 query := strings .Trim (c .Args ()[0 ], " \n " )
2243 repos := c .Args ()[1 :c .NArg ()]
23- ch := make (chan * model.Item )
24- wg := & sync.WaitGroup {}
25- for index , repo := range repos {
26- wg .Add (1 )
27- go worker (index , repo , query , wg , ch )
28- }
29- go waitForWorker (wg , ch )
30- for item := range ch {
31- resp .Items = append (resp .Items , * item )
32- }
33- if resp .Items == nil {
34- // When any item is not found.
35- item := createNoResultItem ()
36- resp .Items = append (resp .Items , * item )
44+ for _ , repo := range repos {
45+ addNewItem (repo )
3746 }
38- j , err := json .Marshal (resp )
39- if err != nil {
40- // Json error
41- fmt .Println ("{'items': [{'title': 'Json object is invalid.', 'subtitle': 'Please contact to developper.', 'valid': false}]" )
42- } else {
43- fmt .Println (string (j ))
47+ if len (query ) > 0 {
48+ wf .Filter (query )
4449 }
50+ wf .WarnEmpty ("No matching repository" , "Try different query?" )
51+ wf .SendFeedback ()
4552 return nil
4653 }
4754 app .Run (os .Args )
4855}
4956
50- func waitForWorker (wg * sync.WaitGroup , ch chan * model.Item ) {
51- wg .Wait ()
52- close (ch )
53- }
54-
55- func worker (index int , repo string , query string , wg * sync.WaitGroup , ch chan * model.Item ) {
56- defer wg .Done ()
57- path := strings .Split (repo , "/" )
58- if matchRepo (path , query ) {
59- // Create normal item
60- item := createNewItem (index , repo , path )
61- ch <- item
62- }
63- }
64-
65- func createNewItem (index int , repo string , repo_path []string ) * model.Item {
66- item := model .NewItem ()
67- item .Uid = string (index )
68- item .Title = excludeDomain (repo_path , true )
69- item .Subtitle = getDomainName (repo_path )
70- item .Arg = repo
71- item .Icon .Type = ""
72- item .Icon .Path = getIconPath (repo_path )
73- createModItems (repo_path , repo , & item .Mods )
74- return item
75- }
76-
77- func createNoResultItem () * model.Item {
78- item := model .NewItem ()
79- item .Title = "No result found."
80- item .Subtitle = "Please input again."
81- item .Valid = false
82- return item
57+ func main () {
58+ wf .Run (run )
8359}
8460
85- func matchRepo (repo_path []string , query string ) bool {
86- repo_path_lower , query_lower := strings .ToLower (excludeDomain (repo_path , true )), strings .ToLower (query )
87- if strings .Index (repo_path_lower , query_lower ) != - 1 {
88- return true
61+ func addNewItem (repo string ) {
62+ repoPath := strings .Split (repo , "/" )
63+ it := wf .NewItem (repo ).
64+ Title (excludeDomain (repoPath , true )).
65+ UID (repo ).
66+ Arg (repo ).
67+ Subtitle (getDomainName (repoPath )).
68+ Icon (getIcon (repoPath )).
69+ Valid (true )
70+ for _ , modKey := range modKeys {
71+ mod := createModItem (repoPath , repo , modKey )
72+ it .SetModifier (mod )
8973 }
90- return false
9174}
9275
9376func excludeDomain (repo []string , domain bool ) string {
@@ -109,45 +92,43 @@ func getDomainName(repo_path []string) string {
10992 return repo_path [len (repo_path )- 3 ]
11093}
11194
112- func createModItems (repo []string , path string , mods * map [string ]model.Mod ) {
113- for _ , key := range model .Modifiers {
114- var (
115- arg string
116- sub string
117- )
118- switch key {
119- case model .Cmd :
120- arg = path
121- sub = "Open '" + path + "' in Finder."
122- case model .Shift :
123- arg = "https://" + excludeDomain (repo , false ) + "/"
124- sub = "Open '" + arg + "' in browser."
125- case model .Ctrl :
126- arg = path
127- sub = "Open '" + path + "' in editor."
128- case model .Fn :
129- arg = path
130- sub = "Open '" + path + "' in terminal app."
131- case model .Alt :
132- arg = excludeDomain (repo , true )
133- sub = "Search '" + arg + "' with google."
134- }
135- mod := model .NewMod (arg , sub )
136- (* mods )[key ] = * mod
95+ func createModItem (repo []string , path string , modKey aw.ModKey ) * aw.Modifier {
96+ var (
97+ arg string
98+ sub string
99+ )
100+ switch modKey {
101+ case aw .ModCmd :
102+ arg = path
103+ sub = "Open in Finder."
104+ case aw .ModShift :
105+ arg = "https://" + excludeDomain (repo , false ) + "/"
106+ sub = "Open '" + arg + "' in browser."
107+ case aw .ModCtrl :
108+ arg = path
109+ sub = "Open in editor."
110+ case aw .ModFn :
111+ arg = path
112+ sub = "Open in terminal app."
113+ case aw .ModOpt :
114+ arg = excludeDomain (repo , true )
115+ sub = "Search '" + arg + "' with google."
137116 }
117+ mod := & aw.Modifier {Key : modKey }
118+ return mod .
119+ Arg (arg ).
120+ Subtitle (sub ).
121+ Valid (true )
138122}
139123
140- func getIconPath (repo_path []string ) string {
141- var icon_path string
142- domain := getDomainName (repo_path )
143- prefix := "./resources"
124+ func getIcon (repoPath []string ) * aw.Icon {
125+ domain := getDomainName (repoPath )
144126 switch {
145127 case strings .Contains (domain , "github" ):
146- icon_path = prefix + "/github-logo.png"
128+ return gitHubIcon
147129 case strings .Contains (domain , "bitbucket" ):
148- icon_path = prefix + "/bitbucket-logo.png"
130+ return bitBucketIcon
149131 default :
150- icon_path = prefix + "/git-logo.png"
132+ return gitIcon
151133 }
152- return icon_path
153134}
0 commit comments