I wanted speed. I speed. needed 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 , and quickly found solace in the form of Hammerspoon. Alfred Karabiner Ah, . 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 . Hammerspoon more Then, there was Lua. I wanted to upskill in Lua. The best way to do so? Code something. Enter a collection of 3 mini-apps built on top of so you can automate tasks, boost productivity and eliminate time-suck by programming shortcuts into your daily workflows. , Hellfred Hammerspoon It’s a way to map repetitive, time-consuming tasks to key sequences, commands or searchable texts. TL;DR and the branch. So you want quick-fire? Skip to the installation and tutorial section below or download the repo checkout basics 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 then run function (but only if I am in Default Mode) c launchGoogleChromeApp When I type followed by then run function (again, whilst in Default Mode) w m changeToWindowManagerMode When I type then run function (whilst in WindowManager mode) c centerWindowOnScreen 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: ), then show me those so I can search through them. parent => children Ok. An example maybe? Suppose you have this structure: When I type ‘ ’, then highlight the choice ‘ ’. Selecting this option will execute the function . goog Open Google openGoogleInBrowser Alternatively, if I type ‘ ’, then highlight the choice ‘ ’. Selecting this option will replace the current choices with , , and (the subset of choices for ) app Launch Apps Terminal Notes Calendar Launch Apps When I fuzzy search through and select one, Hellfuzz will execute with the selected app. those launchOrOpenApp 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 ‘ ’ and then hit , then execute any function with a (e.g. command must start with the word ‘ ’) and behaviour (e.g. open app associated with ‘ ’) suitable to open the Notes app. open notes enter filter open notes When I type ‘ ’ and then hit , then execute any function with a filter (e.g. command starts with the word ‘ ’) and behaviour (open url associated with ‘ ’) suitable to open the link. browse github enter browse github Installation: Firestarter Download and install Hammerspoon Install Hellfred: Clone the repository to your ` ` directory: ~/.hammerspoon git clone https://github.com/braddevelop/hellfred.git ~/.hammerspoon Bootstrap: Light it up There is a for Hellfred with a pre-configured setup. Let’s reference it in Hammerspoon’s file. bootstrap file init.lua https://gist.github.com/braddevelop/bac92b6797c087ca42f9363aab4972e0 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 with the hotkey + + Hellfire shift ⌘ h Type the character c The repo for Hellfred will open in a browser. Try Hellfuzz Open with the hotkey + + Hellfuzz shift ⌥ h Type in the word ‘ ’ wiki This highlights the option ‘ ’ Open Hellfred wiki Hit and the wiki for Hellfred will open in a browser enter Try Hellprompt Open with the hotkey + + Hellprompt shift ^ h Type ‘ ’ open code Hit and the code repo for Hellfred will open in a browser enter What , and achieve is map a or to an or , , 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. Hellfire Hellfuzz Hellprompt trigger input action behaviour if-this-then-that 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 to solve the following scenarios so that you can get the hang of things: each app A simple app launcher A url launcher for commonly visited links You can find the final files for this walkthrough in the directory on the repository’s branch. hellfred/extend/basics basics Patterns to note Each app follows a similar set of steps. Initialise the app with a hotkey binding Configure ` ` objects (This could be done in but we will be creating separate files to keep things squeaky clean. We’ll leverage factory methods to make object creation a breeze) Subscriber hellfred-bootstrap.lua Register the subscribers with the app Hotkey to run the app Destroy time-sucking tasks Setup for Hellfire Hellfire works a little something like this: Application Launcher Initialise the app This is already done with the pre-configuration in . Feel free to change the hotkey to something else. hellfred-bootstrap.lua https://gist.github.com/braddevelop/49c7e7c7c62350d93e7798ff2bf40541 Configure Subscriber objects and are user-defined and wrapped inside simple configuration objects. These objects, act as when registered with the respective app and notified whenever something important happens inside the app. triggers callbacks subscribers Subscriber objects for Hellfire follow this structure: https://gist.github.com/braddevelop/20c9c5b97a85a9a5c4cb924b511e494a : If is not defined, Hellfire will set the mode by default, meaning the callback will fire in any mode when triggered. Note fireIfModeIs ANY Create the following directory structure if it does not exist: . hellfred/extend/basics Then create a new Lua file inside the directory called — the file naming convention has no importance. basics hellfirepack-applications.lua Add this code: https://gist.github.com/braddevelop/c12d37d64ce75b83a195666317a10aa2 Register the subscribers with the app Back in , we need to register the pack of subscribers we have just configured. hellfred-bootstrap.lua https://gist.github.com/braddevelop/2298469b805978062421f5a09d01d11a Run the app Enter Hellfire ( + + ) and type any of the new triggers: to open Finder app, to open Terminal or to open Notes app. shift ⌘ h f t n 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 called hellfred/extend/basics hellfirepack-common-links.lua Add this code: https://gist.github.com/braddevelop/7d637464f45d2d9a4641e365ad2f20a1 Register the subscribers with the app Back in , we need to register the pack of subscribers we have just configured. hellfred-bootstrap.lua https://gist.github.com/braddevelop/f0dafb518797620747044afbc20da060 Run the app Enter Hellfire ( + + ) and type any of the new triggers: , , or . shift ⌘ h t g h s Did you notice that typing the trigger launched opened the website? That’s probably not what we want to happen. Let’s take advantage of . Hang on! t Terminal as well as TechCrunch 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… ‘ ’ 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. Default Consider this flow: Create a new Lua file in called . hellfred/extend/basics hellfire-modes-extended.lua We will create a separate mode for the to fire in. common links triggers Add this code: https://gist.github.com/braddevelop/1e3f345076a8cd5c4cdf843cad785c9e We are going to require this file in so it is accessible. We will do the same with the so that we have access to Hellfire’s built-in modes in other parts of our application. hellfred-bootstrap.lua globally Hellfire Modes file Add the following code in (under the metadata section, towards the top of the file) hellfred-bootstrap.lua https://gist.github.com/braddevelop/04a4ec21aab06f50760d1082b216426f Now we need a way to change the mode to our new Common Links mode. We’ll use the key sequence of followed by . c l We also need to be able to get back to mode Default 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 called hellfred/extend/basics hellfire-mode-triggers.lua Add this code: https://gist.github.com/braddevelop/283acacb9634590208c3b29b6039dc12 Register the subscribers with the app In , register the subscribers for the new mode triggers: hellfred-bootstrap.lua https://gist.github.com/braddevelop/8afc4a576d550415f22c3c6fbf4152f1 Test switching between modes Now enter Hellfire ( + + ) and toggle between the two modes. shift ⌘ h Modes FTW! Update subscribers to work in modes Now we need to update our subscribers in so that they only fire when is active. hellfirepack-common-links.lua Common Links mode We will update the factory method and assign to instead of . _G.HELLFIRE_MODES_EXTENDED.COMMON_LINKS fireIfModeIs nil The updated method should look like this: https://gist.github.com/braddevelop/152a16f87efe55f08e7ed7139225f757 We also need to update our subscribers in so that they only fire when is active. hellfirepack-applications.lua Hellfire’s Default mode The updated method should look like this: https://gist.github.com/braddevelop/8ed8dea04397b0471299c8c89f8a9ae0 Run the app Enter Hellfire ( + + ) and toggle between the modes. The trigger now behaves differently depending on the mode that Hellfire is in. shift ⌘ h t Hell yeah! Setup for Hellprompt This is how Hellprompt functions: Application and URL Launcher Initialise the app This is already done with the pre-configuration in . Feel free to change the hotkey to something else. hellfred-bootstrap.lua https://gist.github.com/braddevelop/11e9b4871182f90c57313ab6ffa939a4 Configure Subscriber objects Subscribers for Hellprompt take a different structure to those for Hellfire. Consider this structure: https://gist.github.com/braddevelop/c247d1d1429234c96f3e8c7d8a0b48df : If is not defined then the callback will always be executed. Note filter Create a new Lua file in called hellfred/extend/basics hellpromptpack-commands.lua Add this code: https://gist.github.com/braddevelop/6b18219f83fcf69826083d5dfce5d06f Register the subscribers with the app Back in , we need to register the pack of subscribers we have just configured. hellfred-bootstrap.lua https://gist.github.com/braddevelop/f1b75646b7330fcb1c993a5737fd7d61 Enter Hellprompt ( + + ) and test out those commands. Run the app shift ^ h Inferno! Try: browse news and: open terminal Setup for Hellfuzz This is how Hellfuzz works: Application Launcher Initialise the app This is already done with the pre-configuration in . Feel free to change the hotkey to something else. hellfred-bootstrap.lua https://gist.github.com/braddevelop/b18f575ec347503628e7457217b6e187 Configure Subscriber objects Subscribers for Hellfuzz take a different structure to the other apps. Consider this structure: https://gist.github.com/braddevelop/56e9c22c6f921575637c73d60920d208 : If is defined then is ignored. Note nextChoicesFn callback To make things easier we’ll use a helper method to configure subscribers for Hellfuzz Create a new Lua file in called hellfred/extend/basics hellfuzzpack-apps-and-links.lua Add this code: https://gist.github.com/braddevelop/3564ad1ec286a30eca1abb94cfd6a69a Register the subscribers with the app In , register the pack of subscribers. hellfred-bootstrap.lua https://gist.github.com/braddevelop/a90f9d5635377d74b145a892845c8273 Run the app Enter Hellfuzz ( + + ) and type in a command. For example start typing the word , you’ll see the option to open Terminal is highlighted. Press and opens. shift ⌥ h ‘Terminal’ enter Terminal 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: Let’s try this out on our task, we’ll create the following hierarchical choice structure: Link Launcher Update the code in to the following: hellfuzzpack-apps-and-links.lua https://gist.github.com/braddevelop/384b0ae9629faca95d5d4cb519cd8e61 Now enter Hellfuzz ( + + ) and start searching for ‘ ’. You can select the ‘ ’ choice, and the sub-set of choices from will be displayed and can be fuzzy searched. Selecting any of the link options will open the respective url. shift ⌥ h Common links Common links commonLinkNextChoices Extensions: Add fuel to the fire. Look out for upcoming Hellfred experiments and extensions on the repo by checking out the branch. extend git checkout extend Now go raise hell \m/