Skip to content

The Hammerspoon Alternative

Johnny Shankman edited this page May 12, 2023 · 5 revisions

Hammerspoon is a fantastic utility for OS X users, providing a LUA interface to many OS X facilities, including the Window Manager.

It turns out that we can use Hammerspoon to implement the core of ShiftIt's functionality with a very small script. If you want to use Hammerspoon as an alternative to ShiftIt, do the following:

  1. You should probably exit ShiftIt, especially if the following key bindings will conflict with it.
  2. Install Hammerspoon. (Download the latest release and drag it to your /Applications folder)
  3. Start it up. It will add an icon to your menu bar that looks like... you guessed it... a hammer-spoon.
  4. From the menu bar icon, select Preferences...
  5. Ensure that (at least) the following are checked:
  • Launch Hammerspoon at login
  • Check for updates
  • Show menu icon
  1. If you haven't already been asked to do this by Hammerspoon itself, you'll want to also click the Enable Accessibility button in Preferences in order to give Hammerspoon the access it needs to hook the keyboard. (ShiftIt needs this level of access as well)

You're almost done. The last thing you'll want to do is to open up a terminal window (open /Applications/Utilities/Terminal.app if you don't have a favourite one already) and do the following (just copy/paste it):

mkdir -p ~/.hammerspoon
cat <<EOH > ~/.hammerspoon/init.lua
hs.window.animationDuration = 0
units = {
  right30       = { x = 0.70, y = 0.00, w = 0.30, h = 1.00 },
  right50       = { x = 0.50, y = 0.00, w = 0.50, h = 1.00 },
  right70       = { x = 0.30, y = 0.00, w = 0.70, h = 1.00 },
  left70        = { x = 0.00, y = 0.00, w = 0.70, h = 1.00 },
  left50        = { x = 0.00, y = 0.00, w = 0.50, h = 1.00 },
  left30        = { x = 0.00, y = 0.00, w = 0.30, h = 1.00 },
  top50         = { x = 0.00, y = 0.00, w = 1.00, h = 0.50 },
  bot50         = { x = 0.00, y = 0.50, w = 1.00, h = 0.50 },
  bottomright   = { x = 0.50, y = 0.50, w = 0.50, h = 0.50 },
  topright      = { x = 0.50, y = 0.00, w = 0.50, h = 0.50 },
  bottomleft    = { x = 0.00, y = 0.50, w = 0.50, h = 0.50 },
  topleft       = { x = 0.00, y = 0.00, w = 0.50, h = 0.50 },
  maximum       = { x = 0.00, y = 0.00, w = 1.00, h = 1.00 },
  centered      = { x = 0.25, y = 0.00, w = 0.50, h = 1.00 }
}

mash = { 'shift', 'ctrl', 'cmd' }

hs.hotkey.bind(mash, 'right', function() hs.window.focusedWindow():move(units.right50,    nil, true) end)
hs.hotkey.bind(mash, 'left', function() hs.window.focusedWindow():move(units.left50,     nil, true) end)
hs.hotkey.bind(mash, 'up', function() hs.window.focusedWindow():move(units.top50,      nil, true) end)
hs.hotkey.bind(mash, 'down', function() hs.window.focusedWindow():move(units.bot50,      nil, true) end)

hs.hotkey.bind(mash, '1', function() hs.window.focusedWindow():move(units.topleft,    nil, true) end)
hs.hotkey.bind(mash, '2', function() hs.window.focusedWindow():move(units.topright,     nil, true) end)
hs.hotkey.bind(mash, '3', function() hs.window.focusedWindow():move(units.bottomleft,      nil, true) end)
hs.hotkey.bind(mash, '4', function() hs.window.focusedWindow():move(units.bottomright,      nil, true) end)

hs.hotkey.bind(mash, 'c', function() hs.window.focusedWindow():move(units.centered,      nil, true) end)
hs.hotkey.bind(mash, 'm', function() hs.window.focusedWindow():move(units.maximum,    nil, true) end)
EOH

Then go to the Hammerspoon menu bar item and select Reload Config.

Alternatively, you can go to Hammerspoon and select Edit Config then add just the lua script part of the example above (the part after the cat call).

You should now have the ability to manipulate your windows in the following way:

  • SHIFT-CTRL-CMD+LEFTARROW -- Move window to the left, occupying 50% of the screen
  • SHIFT-CTRL-CMD+RIGHTARROW -- Move window to the right, occupying 50% of the screen
  • SHIFT-CTRL-CMD+UPARROW -- Move window to the top, occupying 50% of the screen
  • SHIFT-CTRL-CMD+DOWNARROW -- Move window to the bottom, occupying 50% of the screen
  • SHIFT-CTRL-CMD+1 -- Move window to the upper right, occupying 25% of the right and 25% of the top of the screen
  • SHIFT-CTRL-CMD+2 -- Move window to the lower right, occupying 25% of the right and 25% of the bottom of the screen
  • SHIFT-CTRL-CMD+3 -- Move window to the upper left, occupying 25% of the right and 25% of the top of the screen
  • SHIFT-CTRL-CMD+4 -- Move window to the lower left, occupying 25% of the right and 25% of the bottom of the screen
  • SHIFT-CTRL-CMD+m -- Move the window to fill the screen
  • SHIFT-CTRL-CMD+c -- Move the window to fill the center half of the screen

Of course, you can modify this to suit your wants and desires. Add more keystrokes, change the bindings, change the units so that you can split however.. have fun with it.

You can also check out Derek Wyatt's hammerspoon-init.lua for more inspiration if you'd like. He's got some fun hacks in there to set all of his application windows to lay out on multiple screens with one keystroke.

Clone this wiki locally