Skip to content

Instantly share code, notes, and snippets.

@arbelt
Created October 2, 2016 20:55
Show Gist options
  • Star 33 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save arbelt/b91e1f38a0880afb316dd5b5732759f1 to your computer and use it in GitHub Desktop.
Save arbelt/b91e1f38a0880afb316dd5b5732759f1 to your computer and use it in GitHub Desktop.
Hammerspoon config to send escape on short ctrl press
ctrl_table = {
sends_escape = true,
last_mods = {}
}
control_key_timer = hs.timer.delayed.new(0.15, function()
ctrl_table["send_escape"] = false
-- log.i("timer fired")
-- control_key_timer:stop()
end
)
last_mods = {}
control_handler = function(evt)
local new_mods = evt:getFlags()
if last_mods["ctrl"] == new_mods["ctrl"] then
return false
end
if not last_mods["ctrl"] then
-- log.i("control pressed")
last_mods = new_mods
ctrl_table["send_escape"] = true
-- log.i("starting timer")
control_key_timer:start()
else
-- log.i("contrtol released")
-- log.i(ctrl_table["send_escape"])
if ctrl_table["send_escape"] then
-- log.i("send escape key...")
hs.eventtap.keyStroke({}, "ESCAPE")
end
last_mods = new_mods
control_key_timer:stop()
end
return false
end
control_tap = hs.eventtap.new({12}, control_handler)
control_tap:start()
@CestDiego
Copy link

@wezzynl Thank you for that comment. I also felt it a little unbearable sometimes to wait a fraction of a second for it to work. Also for some reason the escape key event would not be sent to emacs until I tried your solution.

@zcmarine
Copy link

zcmarine commented Mar 28, 2017

In case anyone else comes upon this and finds the above code confusing or, like me, keeps getting a bug where you end up having to hit escape multiple times, I rewrote the above and added comments, clearer variable names, and fixed that bug. Gist located here: https://gist.github.com/zcmarine/f65182fe26b029900792fa0b59f09d7f

Definitely wouldn't have gotten that done without the above as an initial starting point though, so thanks a ton to arbelt and jasoncodes!

@safecancel
Copy link

Hi everyone,
Is there a way to not have this run when a specific app is in focus? (for example: remote desktop, vmware, teamviewer etc.)
Many thanks!

@dguo
Copy link

dguo commented Feb 24, 2020

@safecancel you can grab the current active application and use that to determine if the logic should run.

Thanks everyone. I've been using Karabiner-Elements only to remap caps lock to escape on tap and control on hold. With your solutions, I can use Hammerspoon instead (after changing caps lock to control in System Preferences) and drop Karabiner as a dependency.

@chrisspiegl
Copy link

chrisspiegl commented Mar 19, 2021

This is a great and very helpful gist. I used it to get my application to more reliably trigger the ESCAPE key. Since sending it with the hs.eventtap.sendKey does not seem to reliably do so (especially in applications like Alfred, 1Password, and such.

But the tip by @wezzynl in their comment above got me thinking and it actually does work much faster and more reliable.

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