-
-
Notifications
You must be signed in to change notification settings - Fork 121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support setting Alfred variables with alfy.output (#43) #44
Changes from 1 commit
979febc
1084938
76de28b
7f4ac51
fecf997
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,8 +38,22 @@ alfy.alfred = { | |
|
||
alfy.input = process.argv[2]; | ||
|
||
alfy.output = arr => { | ||
console.log(JSON.stringify({items: arr}, null, '\t')); | ||
const isDefined = x => x !== null && x !== undefined; | ||
|
||
const formatItemArg = item => { | ||
if (isDefined(item) && isDefined(item.variables)) { | ||
const alfredworkflow = {arg: item.arg, variables: item.variables}; | ||
item.arg = JSON.stringify({alfredworkflow}); | ||
delete item.variables; | ||
} | ||
}; | ||
|
||
alfy.output = items => { | ||
if (isDefined(items) && items.forEach) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just check if items is an array, otherwise throw a TypeError if (!Array.isArray(items)) {
throw new TypeError(`Expected \`items\` to be of type \`Array\`, got \`${typeof items}\``);
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This would be a breaking change to the Old implementation: alfy.output('hi!'); // no problem New implementation: alfy.output('hi!'); // TypeError I'm happy to implement it, just want to confirm. P.S. - does Alfy follow SemVer? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For now, I've just changed it to this: if (Array.isArray(items)) {
items = items.map(format);
} Let me know if you'd prefer the breaking change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It was always documented as accepting an Array. Enforcing the documented behavior is not a breaking change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree. I don't think Alfred accepts anything else except an Array of items. This means that we are now just more verbose to what it accepts. |
||
items.forEach(formatItemArg); | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use items = items.map(item => format(item)); And then return the item in the |
||
console.log(JSON.stringify({items}, null, '\t')); | ||
}; | ||
|
||
alfy.matches = (input, list, item) => { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -165,7 +165,7 @@ Return output to Alfred. | |
|
||
Type: `Array` | ||
|
||
List of `Object` with any of the [supported properties](https://www.alfredapp.com/help/workflows/inputs/script-filter/json/). | ||
List of `Object` with any of the [supported properties](https://www.alfredapp.com/help/workflows/inputs/script-filter/json/). In addition, if a list item has a `variables` property, it will be used to set Alfred's [Workflow Environment Variables](https://www.alfredapp.com/help/workflows/advanced/variables/) if the user selects the item. | ||
|
||
Example: | ||
|
||
|
@@ -179,6 +179,33 @@ alfy.output([{ | |
|
||
<img src="media/screenshot-output.png" width="694"> | ||
|
||
Using the `variables` property: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should put this under it's own section so we can easily link it from the highlights and to make it more clear. Not sure where though, any ideas @sindresorhus? Maybe a new section There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A new top-level section called "Environment variables". |
||
|
||
```js | ||
alfy.output([{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Put the objects on newlines alfy.output([
{
title: 'Unicorn',
arg: '🦄',
variables: {
color: 'white'
}
},
{
//...
}
]); |
||
title: 'Unicorn', | ||
arg: '🦄', | ||
variables: {color: 'white'} | ||
}, { | ||
title: 'Rainbow', | ||
arg: '🌈', | ||
variables: {color: 'myriad'} | ||
}]); | ||
``` | ||
|
||
You can access Alfred Workflow Variables through `process.env`: | ||
|
||
```js | ||
// After a user selects "Unicorn" or "Rainbow" | ||
process.env.color | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we alias this as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that would be nice. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
//=> 'white' if they selected Unicorn | ||
//=> 'myriad' if they selected Rainbow | ||
``` | ||
|
||
Alfred Workflow Variables are also available in the workflow editor using the form `{var:varname}`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Can you add an example for the color case above? Would |
||
|
||
<img src="media/screenshot-variable.png" width="694"> | ||
|
||
#### matches(input, list, [item]) | ||
|
||
Returns an `Array` of items in `list` that case-insensitively contains `input`. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import test from 'ava'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this be |
||
import hookStd from 'hook-std'; | ||
import {alfy} from './_utils'; | ||
|
||
const m = alfy(); | ||
|
||
test.cb('.output() properly wraps item.variables', t => { | ||
const unhook = hookStd.stdout({silent: true}, output => { | ||
unhook(); | ||
const item = JSON.parse(output).items[0]; | ||
const arg = JSON.parse(item.arg); | ||
t.deepEqual(arg, { | ||
alfredworkflow: { | ||
arg: '🦄', | ||
variables: {fabulous: true} | ||
} | ||
}); | ||
t.end(); | ||
}); | ||
m.output([{ | ||
title: 'unicorn', | ||
arg: '🦄', | ||
variables: {fabulous: true} | ||
}]); | ||
}); | ||
|
||
test.cb('.output() wraps item.variables even if item.arg is not defined', t => { | ||
const unhook = hookStd.stdout({silent: true}, output => { | ||
unhook(); | ||
const item = JSON.parse(output).items[0]; | ||
const arg = JSON.parse(item.arg); | ||
t.deepEqual(arg, { | ||
alfredworkflow: { | ||
variables: {fabulous: true} | ||
} | ||
}); | ||
t.end(); | ||
}); | ||
m.output([{ | ||
title: 'unicorn', | ||
variables: {fabulous: true} | ||
}]); | ||
}); | ||
|
||
test.cb('.output() does not wrap item.arg if item.variables is not defined', t => { | ||
const unhook = hookStd.stdout({silent: true}, output => { | ||
unhook(); | ||
const item = JSON.parse(output).items[0]; | ||
t.is(item.arg, '🦄'); | ||
t.is(item.variables, undefined); | ||
t.end(); | ||
}); | ||
m.output([{ | ||
title: 'unicorn', | ||
arg: '🦄' | ||
}]); | ||
}); | ||
|
||
test('.output() accepts null and undefined items', t => { | ||
const unhook = hookStd.stdout({silent: true}, () => unhook()); | ||
t.notThrows(() => m.output([undefined, null])); | ||
}); | ||
|
||
test('.output() accepts non-arrays', t => { | ||
let done = false; | ||
const unhook = hookStd.stdout({silent: true}, () => { | ||
if (done) { | ||
unhook(); | ||
} | ||
}); | ||
t.notThrows(() => m.output({})); | ||
t.notThrows(() => m.output('unicorn')); | ||
t.notThrows(() => m.output(null)); | ||
done = true; | ||
t.notThrows(() => m.output(undefined)); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has to be expanded. It's also possible to provide variables for mods like this
If you press the alt key, it will now show the
Rainbow
instead.