Skip to content

Instantly share code, notes, and snippets.

@ttscoff
Last active Sep 21, 2022
Embed
What would you like to do?
Hammerspoon config examples for hyper key
-- A global variable for the Hyper Mode
k = hs.hotkey.modal.new({}, "F17")
-- Trigger existing hyper key shortcuts
k:bind({}, 'm', nil, function() hs.eventtap.keyStroke({"cmd","alt","shift","ctrl"}, 'm') end)
-- OR build your own
launch = function(appname)
hs.application.launchOrFocus(appname)
k.triggered = true
end
-- Single keybinding for app launch
singleapps = {
{'q', 'MailMate'},
{'w', 'OmniFocus'},
{'e', 'Sublime Text'},
{'r', 'Google Chrome'}
}
for i, app in ipairs(singleapps) do
k:bind({}, app[1], function() launch(app[2]); k:exit(); end)
end
-- Sequential keybindings, e.g. Hyper-a,f for Finder
a = hs.hotkey.modal.new({}, "F16")
apps = {
{'d', 'Twitter'},
{'f', 'Finder'},
{'s', 'Skype'},
}
for i, app in ipairs(apps) do
a:bind({}, app[1], function() launch(app[2]); a:exit(); end)
end
pressedA = function() a:enter() end
releasedA = function() end
k:bind({}, 'a', nil, pressedA, releasedA)
-- Shortcut to reload config
ofun = function()
hs.reload()
hs.alert.show("Config loaded")
k.triggered = true
end
k:bind({}, 'o', nil, ofun)
-- Enter Hyper Mode when F18 (Hyper/Capslock) is pressed
pressedF18 = function()
k.triggered = false
k:enter()
end
-- Leave Hyper Mode when F18 (Hyper/Capslock) is pressed,
-- send ESCAPE if no other keys are pressed.
releasedF18 = function()
k:exit()
if not k.triggered then
hs.eventtap.keyStroke({}, 'ESCAPE')
end
end
-- Bind the Hyper key
f18 = hs.hotkey.bind({}, 'F18', pressedF18, releasedF18)
-- Cursor locator
local mouseCircle = nil
local mouseCircleTimer = nil
function mouseHighlight()
size = 150
-- Delete an existing highlight if it exists
if mouseCircle then
mouseCircle:delete()
mouseCircle2:delete()
if mouseCircleTimer then
mouseCircleTimer:stop()
end
end
-- Get the current co-ordinates of the mouse pointer
mousepoint = hs.mouse.getAbsolutePosition()
-- Prepare a big red circle around the mouse pointer
mouseCircle = hs.drawing.circle(hs.geometry.rect(mousepoint.x-(size/2), mousepoint.y-(size/2), size, size))
mouseCircle2 = hs.drawing.circle(hs.geometry.rect(mousepoint.x-(size/4), mousepoint.y-(size/4), size/2, size/2))
mouseCircle:setStrokeColor({["red"]=1,["blue"]=0,["green"]=0,["alpha"]=1})
mouseCircle2:setStrokeColor({["red"]=1,["blue"]=0,["green"]=0,["alpha"]=1})
mouseCircle:setFill(false)
mouseCircle2:setFill(false)
mouseCircle:setStrokeWidth(3)
mouseCircle2:setStrokeWidth(5)
mouseCircle:show()
mouseCircle2:show()
-- Set a timer to delete the circle after 3 seconds
mouseCircleTimer = hs.timer.doAfter(1, function() mouseCircle:delete() mouseCircle2:delete() end)
end
hs.hotkey.bind({"cmd","alt","shift"}, "D", mouseHighlight)
-- HYPER+L: Open news.google.com in the default browser
-- lfun = function()
-- news = "app = Application.currentApplication(); app.includeStandardAdditions = true; app.doShellScript('open http://news.google.com')"
-- hs.osascript.javascript(news)
-- k.triggered = true
-- end
-- k:bind('', 'l', nil, lfun)
@whiterock
Copy link

whiterock commented Jun 2, 2021

Thanks for this, very helpful. One comment: maybe it's just me, but I found the use of F17 on k (and the F16 on a) confusing as a new user. I was puzzling over what these new F keys were for, and wondering why they were necessary since we bound Caps lock to F18. After playing around with it, it seems you can just create the modal object without any associated keybinding:

k = hs.hotkey.modal.new()

and then, as you do later on, bind F18 to enter/exit the modal on key down/up.

If anyone is interested in looking over a very simple version (that also doesn't involve the Escape key), check out my config.

thanks! <3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment