github.com/quantumghost/awgo@v0.15.0/alfred.go (about) 1 // 2 // Copyright (c) 2018 Dean Jackson <deanishe@deanishe.net> 3 // 4 // MIT Licence. See http://opensource.org/licenses/MIT 5 // 6 // Created on 2018-02-11 7 // 8 9 package aw 10 11 import ( 12 "fmt" 13 "path/filepath" 14 15 "github.com/deanishe/awgo/util" 16 ) 17 18 /* 19 Alfred wraps Alfred's AppleScript API, allowing you to open Alfred in 20 various modes or call External Triggers. 21 22 a := NewAlfred() 23 24 // Open Alfred 25 if err := a.Search(""); err != nil { 26 // handle error 27 } 28 29 // Browse /Applications 30 if err := a.Browse("/Applications"); err != nil { 31 // handle error 32 } 33 */ 34 type Alfred struct { 35 Env 36 } 37 38 // NewAlfred creates a new Alfred from the environment. 39 // 40 // It accepts one optional Env argument. If an Env is passed, Alfred 41 // is initialised from that instead of the system environment. 42 func NewAlfred(env ...Env) *Alfred { 43 44 var e Env 45 46 if len(env) > 0 { 47 e = env[0] 48 } else { 49 e = sysEnv{} 50 } 51 52 return &Alfred{e} 53 } 54 55 // Search runs Alfred with the given query. Use an empty query to just open Alfred. 56 func (a *Alfred) Search(query string) error { 57 _, err := util.RunJS(fmt.Sprintf(scriptSearch, util.QuoteJS(query))) 58 return err 59 } 60 61 // Browse tells Alfred to open path in navigation mode. 62 func (a *Alfred) Browse(path string) error { 63 64 var err error 65 66 if path, err = filepath.Abs(path); err != nil { 67 return err 68 } 69 70 _, err = util.RunJS(fmt.Sprintf(scriptBrowse, util.QuoteJS(path))) 71 return err 72 } 73 74 // SetTheme tells Alfred to use the specified theme. 75 func (a *Alfred) SetTheme(name string) error { 76 _, err := util.RunJS(fmt.Sprintf(scriptSetTheme, util.QuoteJS(name))) 77 return err 78 } 79 80 // Action tells Alfred to show File Actions for path(s). 81 func (a *Alfred) Action(path ...string) error { 82 83 if len(path) == 0 { 84 return nil 85 } 86 87 var paths []string 88 89 for _, p := range path { 90 91 p, err := filepath.Abs(p) 92 if err != nil { 93 return fmt.Errorf("[action] couldn't make path absolute (%s): %v", p, err) 94 } 95 96 paths = append(paths, p) 97 } 98 99 _, err := util.RunJS(fmt.Sprintf(scriptAction, util.QuoteJS(paths))) 100 return err 101 } 102 103 // RunTrigger runs an External Trigger in the given workflow. Query may be empty. 104 // 105 // It accepts one optional bundleID argument, which is the bundle ID of the 106 // workflow whose trigger should be run. 107 // If not specified, it defaults to the current workflow's. 108 func (a *Alfred) RunTrigger(name, query string, bundleID ...string) error { 109 110 var bid string 111 if len(bundleID) > 0 { 112 bid = bundleID[0] 113 } else { 114 bid, _ = a.Lookup(EnvVarBundleID) 115 } 116 117 opts := map[string]interface{}{ 118 "inWorkflow": bid, 119 } 120 121 if query != "" { 122 opts["withArgument"] = query 123 } 124 125 _, err := util.RunJS(fmt.Sprintf(scriptTrigger, util.QuoteJS(name), util.QuoteJS(opts))) 126 return err 127 } 128 129 // JXA scripts to call Alfred 130 var ( 131 // Simple scripts require one or no string 132 scriptSearch = "Application('Alfred 3').search(%s)" 133 scriptAction = "Application('Alfred 3').action(%s)" 134 scriptBrowse = "Application('Alfred 3').browse(%s)" 135 scriptSetTheme = "Application('Alfred 3').setTheme(%s)" 136 // These scripts require a string and an object of options 137 scriptTrigger = "Application('Alfred 3').runTrigger(%s, %s)" 138 scriptSetConfig = "Application('Alfred 3').setConfiguration(%s, %s)" 139 scriptRmConfig = "Application('Alfred 3').removeConfiguration(%s, %s)" 140 )