I'm a lazy programmer. I love building stuff, but I hate repeating myself. Anytime I start a new article for this site, I do the following:
- navigate to my site's directory in terminal
- open up VS Code
- create a new file
- set the title
- set the slug
- set the date
- set its published flag to false
By no means is that a lot of work, but when I have an idea for something to write, I want to start writing it immediately. So, like any self-respecting lazy programmer, I put together a process to remove as much friction as possible. And, to be honest, I used this as an example to learn more about Alfred workflows and bash scripting.
So, What's the Goal?
I use Alfred all the time, so I thought this would be the perfect interface for my new process. I wanted to simply open the Alfred
prompt and type art <some article title>
and have it perform the steps listed above.
The Implementation
Gatsby Post Manager has a posts new
command that I could use to create the actual file. The command itself looks like this:
$ gpm posts new path/to/posts "hello world"
This command automatically creates the file and assigns it the title, slug, and date, but I still need to pass it the path to the posts. This path never changes for me, so I shouldn't need to type it every time.
My first thought was to create an Alfred workflow that passes that command to terminal. That would work, but it has two downsides:
- Alfred will open a new terminal window anytime I invoke the command
- I still need to open VS Code to actually write the article, which means I need to pipe the output of
gpm
tocode
The better approach is to write a bash script that invokes gpm
and then opens VS Code.
The Bash Script
#!/bin/bash# Alfred sometimes has trouble finding Node; the below fixes thatexport PATH=$PATH:/usr/local/bin# Require a single argument for the article nameif [ $# -ne 1 ]; thenecho 1>&2 "Usage: $0 article-name"exit 3fi# Create the article file# Uses Gatsby Post Manager (gpm): https://github.com/steven-mercatante/gatsby-post-managerRESULT=`/usr/local/bin/gpm posts new /Users/steve/sites/stevemerc.com/content/posts "$1"`# Split $RESULT into an array# $RESULT normally looks like: "/path/to/posts/post.md successfully created", but we only want the filename# This is the delimiter that $RESULT will be split onIFS=' '# Creates $ARTICLE_ARR array from $RESULT stringread -ra ARTICLE_ARR <<< $RESULT# Grab just the filename from the success or error messageARTICLE=${ARTICLE_ARR[0]}# Open up VS Code on the proper project, then open up the newly created article/usr/local/bin/code /Users/steve/sites/stevemerc.com && /usr/local/bin/code $ARTICLE
Here's a link to the repo.
I've done my best to document what the script does. If you have any questions, tweet at me.
Now that we've got our script that orchestrates everything, we need to wire it up to Alfred.
Creating the Alfred Workflow
I'm using Alfred v4, so your setup may differ a bit from mine. But the gist is:
- open Alfred's preferences
- navigate to the
Workflows
section - click the
+
button near the bottom and selectTemplates > Essentials > Keyword to Script
Name your workflow whatever you want and click the Create
button. In my case, I called it "Create Article". This is used for organization purposes.
You should then see your newly created workflow and two nodes:
Double click that Keyword
node and you'll be prompted to define the command name and title.
Next, double click the Run Script
node and you'll be prompted to either write the bash script right there, or you can select External Script
(<- do that).
As soon as you enter a path to an existing bash script in the Script File:
input, its contents will appear below.
Everything should be set up now, and you can type art hello world
in the Alfred prompt to create your new article.
This is what the contents of the newly created hello-world.md
file looks like:
---title: Hello Worldpath: 'hello-world'tags: []published: falsedate: '2019-09-24'---Add your content here
Debugging
I had some trouble getting my bash script and Alfred to work together. Something to do with paths... who knows. Luckily, Alfred lets us debug our workflows.
Once you click that little bug icon, it opens a console window that'll print out the steps Alfred takes, as well as any output or errors from your bash script. Getting this process to work without the debugger would've definitely taken longer.
Wrapping Up
I don't expect many people to want to solve the same problem that I just solved, but, knowing how to wire up command line tools, bash scripts, and Alfred to orchestrate common and repetitive tasks is a valuable skill.