Prodtyping

The process on turning ideas into reality

January 19th 2019

Give your keyboard superpowers with a Hyperkey and Hammerspoon

space-cadet keyboard

The concept of a hyperkey originated from the space-cadet keyboard. This keyboard was designed by Tom Knight, was used on MIT LISP machines, and was equipped with seven modifier keys. A modifier key is a special key (or a combination of keys) on a keyboard that temporarily changes the action of another key when pressed together. By themselves, modifier keys generally do not trigger an action from the computer. 

Some common modifier keys

Hyperkey is a special key reserved for global shortcuts

This means that these shortcuts should (almost) always work no matter what application is being used. The functionality of a hyperkey can be mimicked on a modern keyboard. A popular key to use is the Caps Lock since the same result can be achieved by holding down the shift + the letter key of your choice. 

To create a hyperkey we are going to remap our Caps Lock to CMD + CTRL + OPTION + SHIFT. This combination is very awkward to do on a keyboard so its safe to say that most applications will not utilize it. 

In order to do this, we are going to use a keyboard customizer called Karabiner and an automation tool called Hammerspoon. Karabiner will do the custom mapping that we want and Hammerspoon will allow us to write some code in Lua to make custom shortcuts for applications.

Some examples of what I use are: 

  • Hyper + C to open Chrome 
  • Hyper + A to open Atom 
  • Hyper + I to open iTerm2 

Instructions 

  • Make sure you have Homebrew installed if you don't check out my tutorial

  • Open up your terminal and type 

brew cask install karabiner-elements hammerspoon

  • Open up Hammerspoon and enable accessibility. 

  • Open up the file ~/.config/karabiner/karabiner.json in your text editor. My personal favorite is Atom. 

  • Paste the following code inside this file. This config file only includes Hyperkey functionality. JSON files are a bit picky so make sure there are not any tabs it will cause Karabiner to fail. 
{
  "global": {
    "check_for_updates_on_startup": true,
    "show_in_menu_bar": true,
    "show_profile_name_in_menu_bar": false
  },
  "profiles": [{
    "complex_modifications": {
      "rules": [{
        "manipulators": [{
          "description": "Change caps_lock to command+control+option+shift. Escape if no other key used.",
          "from": {
            "key_code": "caps_lock",
            "modifiers": {
              "optional": [
                "any"
              ]
            }
          },
          "to": [{
            "key_code": "left_shift",
            "modifiers": [
              "left_command",
              "left_control",
              "left_option"
            ]
          }],
          "to_if_alone": [{
            "key_code": "escape",
            "modifiers": {
              "optional": [
                "any"
              ]
            }
          }],
          "type": "basic"
        }]
      }]
    }
  }]
}

Next, we're going to add Hammerspoon configuration. Save the last file and open up ~/.hammerspoon/init.lua in your text editor 

Paste the following code inside this file and then save it. 

-- global
local hyper = {"cmd", "alt", "ctrl","shift"}
local log = hs.logger.new('hammerspoon','debug')

-- open hide app
function openApp(name)
  local app = hs.application.get(name)

  log.i("open App")
  log.i(name)
  log.i(app)

  if app then
    if app:isFrontmost() then
      log.i("app hiding")
      app:hide()
    else
      log.i("app focusing ")
      app:mainWindow():focus()
    end
  else
    log.i("app launch ")
    hs.application.launchOrFocus(name)
  end
end

-- ATOM
function atom()
  openApp("Atom")
end
hs.hotkey.bind(hyper, 'a', atom)
  • To create other hotkeys follow this format: 

-- function () openApp("") end hs.hotkey.bind(hyper, '', )

  • Important: The name of the application inside the parentheses is case sensitive so make sure it is capitalized correctly if applicable. I typically keep the case on the function name and reference (the bolded text) in all lowercase but make sure those match as well.

  • Also, note that the is referring to choosing a single character to use in conjunction with the hyper key. 

  • Click on the Reload config to update Hammerspoon to your changes and that's it!