Let's create a Alfred workflow to search for memes in a folder(our collection) and put that image in the clipboard so we can user it wherever we need it. Yes, it sounds useless but it was fun to made.
First we need to cover some things to understand how an Alfred workflow works. There are many types of elements to build a workflow, this time we're going to use 2 specific elements:
script filter
: prepare a list of options that can be filtered along as we typerun script
: run a command to send the selected option in the previous step into the system clipboard
Create a workflow
Let's go to Alfred settings/Workflows/+/Blank workflow
Name our new workflow, you can use whatever name you want, let's put "Meme fuzzy finder"
Create a new element of type script filter
Now we need to make some adjustments over the defaults values:
keyword
if the word that will be used by Alfred to trigger this workflow, we're going to usememe
so we can typememe something
and it will return all the matches withsomething
.- Use
/bin/zsh
instead of/bin/bash
as language, there will be a bug if we usebash
, more details later. - Select
with input as {query}
instead ofwith input as argv
, this allow us to read a injected value instead of readingargv
. - Now we need a script that makes the magic happens.
script filter
can execute a script and it should return results in a json format like the following example:
{
"items": [
{
"title": "it's alive.gif",
"icon": {
"path": "/Users/erick/Documents/memes/it's alive.gif"
},
"arg": "/Users/erick/Documents/memes/it's alive.gif"
},
{
"title": "elmo on fire.gif",
"icon": {
"path": "/Users/erick/Documents/memes/elmo on fire.gif"
},
"arg": "/Users/erick/Documents/memes/elmo on fire.gif"
}
]
}
Every element of an item
has a meaning:
title
will be shown while we typeicon/path
will render a preview of the selectionarg
will be passed to the next step
To produce this output we're going to use two tools:
We're going to combine these tools in the following script:
# replace this with your collection folder
dir='/Users/erick/Documents/memes/'
# prepare a list of json elements using jq templating system
items=$(ls $dir | fzf -f {query} | jq --arg dir $dir -Rn '
def build_item($filename): {
"title": $filename,
"icon": {"path": "\($dir)\($filename)"},
"arg": "\($dir)\($filename)"
};
[
inputs
| select(length>0)
| build_item(.)
]')
# prepare the resulting json using the previous items and building a new json value
jq -n --argjson items $items '{items: $items}'
# this will send the result to ~stdout~, Alfred can read them from there
Some notes about the script:
{query}
will be injected by Alfred when the workflow is active, we changed this after we create the workflow- Replace
dir
value with your collection folder, make sure directory ends with a/
, this is required because we concatenate that value with filename - Replace calls to
fzf
andjq
using an absolute path, Alfred doesn't load our/.zshrc
so it won't know where to find those programs, we can get full path usingwhich
e.gwhich jq
will return/opt/homebrew/bin/jq
in my case
Now we have the script we need to copy it inside script filter
, the result should be like this:
We can check it's working using the debug tool in Aflred and typing the keyword and a query term, for example: meme elmo
:
Copy chosen image to clipboard
Now we need to define a second element, a run script action
:
This time we just need to change one thing, language to AppleScript
and now we can paste the following code to take the selected choice and send it to clipboard:
on run args
set the clipboard to POSIX file (first item of args)
end
The result should be:
After that we should have a workflow with two components:
Demo
And now when we type meme elmo
Alfred will show the result and when we hit enter that image will be copied to clipboard.
Enjoy :)