Hammerspoon : Workspace automation

Deep Mistry
2 min readOct 25, 2020

Hammer and spoon, Not the items we’ll be using together a lot but when it comes to automating things in macOS, Hammerspoon can do almost everything that we possibly want.

Hammerspoon

So what really is Hammerspoon? Well it’s an automation tool for macOS. Hammerspoon act as a bridge between the operating system and a Lua scripting engine. What can Hammerspoon do for you?

  • Talk to other applications
  • Add things to menu bar
  • Attach keybinding to specific functions
  • Display notifications
  • Move windows

Checkout documentation for more.

Being a software engineer, Productivity is much important factor. When I was looking to increase my productivity, I found Hammerspoon. For adding any new automation, all you need to do is write script in init.lua using available APIs and Reload Hammerspoon Configs. At First I tried to automate launch of an application(iTerm) with Key bindings.

hs.hotkey.bind ({‘ctrl’, ‘alt’, ‘cmd’}, ‘K’, 
function () hs.application.launchOrFocus(“iTerm”) end)

After that I wanted to keep copy history and use previously copied text, so I added following to the script which will update copy history while copying content using cmd + 0.

hs.hotkey.bind({"cmd"}, "0", function()
hs.eventtap.keyStroke({"cmd"}, "c")
copy = hs.pasteboard.getContents()
for index = 8, 0, -1 do
paste = hs.pasteboard.readAllData(tostring(index))
if paste["public.utf8-plain-text"] == nil then
hs.pasteboard.writeObjects("", tostring(index + 1))
else
hs.pasteboard.writeObjects(paste["public.utf8-plain-text"], tostring(index + 1))
end
end
hs.pasteboard.writeObjects(copy, "0")
hs.pasteboard.setContents(copy)
end)

After that to display copy history and use previously copied text, I added following to the script.

local choices = {}local function focusLastFocused()
local wf = hs.window.filter
local lastFocused = wf.defaultCurrentSpace:getWindows(wf.sortByFocusedLast)
if #lastFocused > 0 then lastFocused[1]:focus() end
end
local chooser = hs.chooser.new(function(choice)
if not choice then focusLastFocused(); return end
hs.pasteboard.setContents(choice["text"])
focusLastFocused()
hs.eventtap.keyStrokes(hs.pasteboard.getContents())
end)
function get_content(index)
paste = hs.pasteboard.readAllData(tostring(index));
return paste["public.utf8-plain-text"];
end
function update_choices()
choices = {}
for i = 1, 9, 1 do
table.insert(choices,{["text"] = get_content(i)})
end
chooser:choices(choices)
end
hs.hotkey.bind({"cmd", "alt"}, "E", function() update_choices() chooser:show() end)

Use : Whenever you want to see copy history you need to press cmd + alt + E, It will create chooser window and you can copy the previously copied texts by going to particular index and press return.

These are the two automation I did with Hammerspoon, If you want to explore more, please visit Hammerspoon. Thank you !

--

--