Hellfred or: How I Learned To Automate macOS and Become Hellishly Productive by@bradblundell

Hellfred or: How I Learned To Automate macOS and Become Hellishly Productive

Read on Terminal Reader
Open TLDR
react to story with heart
react to story with light
react to story with boat
react to story with money
Hellfred apps are built on top of Hammerspoon so you can automate tasks and boost productivity by programming shortcuts into your daily workflows.
image
Brad Blundell HackerNoon profile picture

Brad Blundell

Thing breaker : Code wrangler : Automation junkie : Digital illustrator : Aspiring musician

linkedin social icongithub social iconinstagram social icon


I wanted speed. I needed speed.


All this clicking around, all this searching, all the repetitive thinking and mental overhead was cutting into actually getting the job done.


I needed the robots to do the work for me.


I’d recently moved over to macOS after many years on Windows where I’d tinkered around with AutoHotkey.


As a relative Mac noob I started hacking around with AlfredKarabiner and quickly found solace in the form of Hammerspoon.


Ah, Hammerspoon. Yes, I had consumed the code and modules — “Spoons” — from the super-smart people coding and extending Hammerspoon and that gained me some great mileage, yet I needed more.


Then, there was Lua. I wanted to upskill in Lua.
The best way to do so?

Code something.




Enter Hellfred, a collection of 3 mini-apps built on top of Hammerspoon so you can automate tasks, boost productivity and eliminate time-suck by programming shortcuts into your daily workflows.


It’s a way to map repetitive, time-consuming tasks to key sequences, commands or searchable texts.



Hellfuzz. A fuzzy search, choice-to-behaviour mapper.

Hellfuzz. A fuzzy search, choice-to-behaviour mapper.


Hellfire. A keys-to-behaviour mapper.

Hellfire. A keys-to-behaviour mapper.


Hellprompt. A command-to-behaviour mapper.

Hellprompt. A command-to-behaviour mapper.


TL;DR

So you want quick-fire? Skip to the installation and tutorial section below or download the repo and checkout the basics branch.


git checkout basics



The Apps

Hellfire

A quick-fire, mode-based, hotkey-to-action mapping utility.

  • Supports single key triggers as well as key chord sequences as triggers.
  • Exposes virtually every key on the keyboard including modifier keys to use as triggers.
  • Modes allow the same trigger to have different behaviours under different contexts.


English, please?

When I type a character or a sequence of characters, then execute a specific function, but only if I am in a particular mode.


Ok. An example maybe?

  • When I type c then run function launchGoogleChromeApp (but only if I am in Default Mode)
  • When I type w followed by m then run function changeToWindowManagerMode (again, whilst in Default Mode)
  • When I type c then run function centerWindowOnScreen (whilst in WindowManager mode)


Hellfuzz

A fuzzy-search chooser utility with choice-to-action mapping.

  • Supports multi-level (nested) choice sets.


English, please?

When I search through a list of choices and select one, then execute a specific function. If my choice has subchoices (think: parent => children), then show me those so I can search through them.


Ok. An example maybe?

Suppose you have this structure:

image

  • When I type ‘goog’, then highlight the choice ‘Open Google’. Selecting this option will execute the function openGoogleInBrowser.
  • Alternatively, if I type ‘app’, then highlight the choice ‘Launch Apps’. Selecting this option will replace the current choices with TerminalNotes, and Calendar (the subset of choices for Launch Apps)
  • When I fuzzy search through those and select one, Hellfuzz will execute launchOrOpenApp with the selected app.


Hellprompt

A commandline-like utility with basic string matching support.


English, please?

When I type out a command and submit it, then inspect my command for any matching string patterns and execute functions related to that command.


Ok. An example maybe?

  • When I type the command ‘open notes’ and then hit enter, then execute any function with a filter (e.g. command must start with the word ‘open’) and behaviour (e.g. open app associated with ‘notes’) suitable to open the Notes app.

  • When I type ‘browse github’ and then hit enter, then execute any function with a filter (e.g. command starts with the word ‘browse’) and behaviour (open url associated with ‘github’) suitable to open the link.



Installation: Firestarter

  1. Download and install Hammerspoon
  2. Install Hellfred: Clone the repository to your `~/.hammerspoon ` directory:


git clone https://github.com/braddevelop/hellfred.git ~/.hammerspoon

Bootstrap: Light it up

There is a bootstrap file for Hellfred with a pre-configured setup. Let’s reference it in Hammerspoon’s init.lua file.

Save the file and reload the configuration (or save yourself some time and use fancy reload)


What’s in the box? Try out the pre-configuration

Out-the-box the 3 Hellfred apps are ready to use and are pre-configured with a quick-start example. Let’s test it out to make sure everything is wiring and firing.

Try Hellfire

  • Open Hellfire with the hotkey shift + + h
  • Type the character c
  • The repo for Hellfred will open in a browser.

Try Hellfuzz

  • Open Hellfuzz with the hotkey shift + + h
  • Type in the word ‘wiki
  • This highlights the option ‘Open Hellfred wiki
  • Hit enter and the wiki for Hellfred will open in a browser

Try Hellprompt

  • Open Hellprompt with the hotkey shift + ^ + h
  • Type ‘open code
  • Hit enter and the code repo for Hellfred will open in a browser



What HellfireHellfuzz and Hellprompt achieve is map a trigger or input to an action or behaviourif-this-then-that, and whilst we have just demonstrated using each app to achieve the same outcome, you will find each app more suited to certain use cases than others.



Tutorial: A basic setup

What we will be programming

Now let’s turn up the heat and configure something a little more useful. We are going to program each app to solve the following scenarios so that you can get the hang of things:

  1. A simple app launcher
  2. A url launcher for commonly visited links


You can find the final files for this walkthrough in the hellfred/extend/basics directory on the repository’s basics branch.


Patterns to note

Each app follows a similar set of steps.

  1. Initialise the app with a hotkey binding
  2. Configure `Subscriber` objects (This could be done in hellfred-bootstrap.lua but we will be creating separate files to keep things squeaky clean. We’ll leverage factory methods to make object creation a breeze)
  3. Register the subscribers with the app
  4. Hotkey to run the app
  5. Destroy time-sucking tasks


Setup for Hellfire

Hellfire works a little something like this:

image

Application Launcher

Initialise the app

This is already done with the pre-configuration in hellfred-bootstrap.lua. Feel free to change the hotkey to something else.


Configure Subscriber objects

triggers and callbacks are user-defined and wrapped inside simple configuration objects. These objects, act as subscribers when registered with the respective app and notified whenever something important happens inside the app.


Subscriber objects for Hellfire follow this structure:

Note: If fireIfModeIs is not defined, Hellfire will set the ANY mode by default, meaning the callback will fire in any mode when triggered.


Create the following directory structure if it does not exist: hellfred/extend/basics.

Then create a new Lua file inside the basics directory called hellfirepack-applications.lua— the file naming convention has no importance.


Add this code:


Register the subscribers with the app

Back in hellfred-bootstrap.lua, we need to register the pack of subscribers we have just configured.


Run the app

Enter Hellfire (shift + + h) and type any of the new triggers:
f to open Finder app, t to open Terminal or n to open Notes app.


Link Launcher (using Hellfire Modes)

Configure Subscriber objects

Alright now let’s configure the subscribers for our Common Links url launcher. Create a new Lua file in hellfred/extend/basics called hellfirepack-common-links.lua


Add this code:


Register the subscribers with the app

Back in hellfred-bootstrap.lua, we need to register the pack of subscribers we have just configured.


Run the app

Enter Hellfire (shift + + h) and type any of the new triggers: tgh or s.


Hang on! Did you notice that typing the trigger t launched Terminal as well as opened the TechCrunch website? That’s probably not what we want to happen. Let’s take advantage of Hellfire’s Mode feature.


Modes offer a way to have the same trigger behave differently under different contexts.


By default, Hellfire initialises in a mode called…you guessed it… ‘Default’ mode.
We can configure some custom modes to use with Hellfire so that triggers can behave differently under different modes — or ‘namespaces’ if you like.


Consider this flow:

image

Create a new Lua file in hellfred/extend/basics called hellfire-modes-extended.lua.

We will create a separate mode for the common links triggers to fire in.


Add this code:


We are going to require this file in hellfred-bootstrap.lua so it is globally accessible. We will do the same with the Hellfire Modes file so that we have access to Hellfire’s built-in modes in other parts of our application.


Add the following code in hellfred-bootstrap.lua (under the metadata section, towards the top of the file)


Now we need a way to change the mode to our new Common Links mode.

We’ll use the key sequence ofc followed by l.

We also need to be able to get back to Default mode

We’ll use the semi-colon; as a trigger.


That’s next…


Configure Subscriber objects that trigger mode changes

Create a new Lua file in hellfred/extend/basics called hellfire-mode-triggers.lua


Add this code:


Register the subscribers with the app

In hellfred-bootstrap.lua, register the subscribers for the new mode triggers:


Test switching between modes

Now enter Hellfire (shift + + h) and toggle between the two modes. Modes FTW!


Update subscribers to work in modes

Now we need to update our subscribers in hellfirepack-common-links.lua so that they only fire when Common Links mode is active.

We will update the factory method and assign _G.HELLFIRE_MODES_EXTENDED.COMMON_LINKS to fireIfModeIs instead of nil.


The updated method should look like this:


We also need to update our subscribers in hellfirepack-applications.lua so that they only fire when Hellfire’s Default mode is active.


The updated method should look like this:


Run the app

Enter Hellfire (shift + + h) and toggle between the modes. The trigger t now behaves differently depending on the mode that Hellfire is in. Hell yeah!


Setup for Hellprompt

This is how Hellprompt functions:

image

Application and URL Launcher

Initialise the app

This is already done with the pre-configuration in hellfred-bootstrap.lua. Feel free to change the hotkey to something else.


Configure Subscriber objects

Subscribers for Hellprompt take a different structure to those for Hellfire.

Consider this structure:

Note: If filter is not defined then the callback will always be executed.


Create a new Lua file in hellfred/extend/basics called hellpromptpack-commands.lua

Add this code:


Register the subscribers with the app

Back in hellfred-bootstrap.lua, we need to register the pack of subscribers we have just configured.


Run the app
Enter Hellprompt (shift + ^ + h) and test out those commands. Inferno!

Try:

browse news

and:

open terminal


Setup for Hellfuzz

This is how Hellfuzz works:

image

Application Launcher

Initialise the app

This is already done with the pre-configuration in hellfred-bootstrap.lua. Feel free to change the hotkey to something else.


Configure Subscriber objects

Subscribers for Hellfuzz take a different structure to the other apps.

Consider this structure:

Note: If nextChoicesFn is defined then callback is ignored.


To make things easier we’ll use a helper method to configure subscribers for Hellfuzz


Create a new Lua file in hellfred/extend/basics called hellfuzzpack-apps-and-links.lua


Add this code:


Register the subscribers with the app

In hellfred-bootstrap.lua, register the pack of subscribers.


Run the app

Enter Hellfuzz (shift + + h) and type in a command. For example start typing the word ‘Terminal’, you’ll see the option to open Terminal is highlighted. Press enter and Terminal opens. Smoking hot!


Link Launcher (using nested choice sets)

A handy feature of Hellfuzz is the ability to nest sets of choices.

Consider this updated flow:

image


Let’s try this out on our Link Launcher task, we’ll create the following hierarchical choice structure:

image

Update the code in hellfuzzpack-apps-and-links.lua to the following:


Now enter Hellfuzz (shift + + h) and start searching for ‘Common links’. You can select the ‘Common links’ choice, and the sub-set of choices from commonLinkNextChoices will be displayed and can be fuzzy searched. Selecting any of the link options will open the respective url.



Extensions: Add fuel to the fire.

Look out for upcoming Hellfred experiments and extensions on the repo by checking out the extend branch.

git checkout extend




Now go raise hell \m/


react to story with heart
react to story with light
react to story with boat
react to story with money

Related Stories

L O A D I N G
. . . comments & more!