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() | |
This comment has been minimized.
This comment has been minimized.
Thanks for this, now to get my |
This comment has been minimized.
This comment has been minimized.
@arbelt I think it would be more clear if you change line control_tap = hs.eventtap.new({ hs.eventtap.event.types.flagsChanged }, control_handler) Without logging out |
This comment has been minimized.
This comment has been minimized.
Also, it doesn't appear to be breaking the logic since the priming on line send_escape = true, |
This comment has been minimized.
This comment has been minimized.
I'm finding this solution doesn't work with my tmux prefix chord unfortunately. I'll hack on it a bit and report back. If anyone else is in the same boat, let me know, and let me know what you've tried. To get ready to play with it, I did some cleanup and simplification refactoring (original logic is still in tact, but with fewer variables). Feel free to have a look if you're using it as a jumping off point as well: https://gist.github.com/rjhilgefort/07ce5cdd3832083d7e94113d54372b1c |
This comment has been minimized.
This comment has been minimized.
I have expanded on this script to avoid sending Escape when other keys are tapped while Control is held down. I’ve been running this for a few weeks now. Works great. https://github.com/jasoncodes/dotfiles/blob/master/hammerspoon/control_escape.lua |
This comment has been minimized.
This comment has been minimized.
Thank you arbelt and jasoncodes! This saved me from a lot of pain! |
This comment has been minimized.
This comment has been minimized.
Instead of using 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
last_mods = new_mods
send_escape = true
control_key_timer:start()
else
last_mods = new_mods
control_key_timer:stop()
if send_escape then
return true, {
hs.eventtap.event.newKeyEvent({}, 'escape', true),
hs.eventtap.event.newKeyEvent({}, 'escape', false),
}
end
end
return false
end
Seems much faster! |
This comment has been minimized.
This comment has been minimized.
@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. |
This comment has been minimized.
This comment has been minimized.
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! |
This comment has been minimized.
This comment has been minimized.
Hi everyone, |
This comment has been minimized.
This comment has been minimized.
@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. |
This comment has been minimized.
This comment has been minimized.
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 But the tip by @wezzynl in their comment above got me thinking and it actually does work much faster and more reliable. |
This comment has been minimized.
Thanks so much for this! Works like a charm to get CAPSLOCK mapped to ESC and CTRL on Sierra!