Created
July 14, 2020 19:53
-
-
Save ajsharp/044d9585e85eeff195d8f8683d57bbc2 to your computer and use it in GitHub Desktop.
hammerspoon config
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- hs.hotkey.bind({'cmd', 'shift'}, 'q', function() | |
-- hs.eventtap.keyStroke({}, "`", 0) | |
-- -- hs.alert.show('hi') | |
-- end) | |
-- four item tuples: | |
-- fromMod, fromKey, toMod, toKey | |
KEYMAP = { | |
{{'cmd', 'shift'}, 'q', {}, '`'}, -- backtick shortcut | |
{{'cmd'}, 'escape', {'cmd'}, '`'}, -- cycle windows via cmd+esc | |
{{'alt'}, 'v', {'cmd'}, 'v'}, -- remap pasting until karabiner is fixed | |
{{"ctrl", "shift"}, "j", {'alt'}, 'left'}, -- jump left | |
{{"ctrl", "shift"}, "k", {'alt'}, 'right'}, -- jump right | |
{{'ctrl', 'shift'}, 'i', {'cmd'}, 'up'}, -- jump to beginning of file | |
{{'ctrl', 'shift'}, 'n', {'cmd'}, 'down'}, -- jump to end of file | |
{{'ctrl', 'cmd'}, 'j', {'cmd'}, 'left'}, -- jump beginning of line | |
{{'ctrl', 'cmd'}, 'k', {'cmd'}, 'right'}, -- end of line | |
{{'ctrl', 'shift'}, 'p', {}, 'delete'}, | |
{{'cmd', 'shift'}, 'l', {'cmd', 'shift'}, 'right'}, -- select to the end of the line | |
{{'cmd', 'shift'}, 'j', {'cmd', 'shift'}, 'left'} | |
} | |
for _, hotkeyVals in ipairs(KEYMAP) do | |
local fromMods, fromKey, toMods, toKey = table.unpack(hotkeyVals) | |
local toKeyStroke = function() | |
hs.eventtap.keyStroke(toMods, toKey, 0) | |
end | |
hs.hotkey.bind(fromMods, fromKey, toKeyStroke, nil, toKeyStroke) | |
end | |
-- make double-tap control be esc | |
local timer = require("hs.timer") | |
local eventtap = require("hs.eventtap") | |
local events = eventtap.event.types | |
local module = {} | |
-- ho quickly must the two single ctrl taps occur? | |
module.timeFrame = 0.2 | |
-- wht to do when the double tap of ctrl occurs | |
module.action = function() | |
hs.eventtap.keyStroke({}, 'escape', 0) | |
end | |
local timeFirstControl, firstDown, secondDown = 0, false, false | |
-- verify that no keyboard flags are being pressed | |
local noFlags = function(ev) | |
local result = true | |
for k,v in pairs(ev:getFlags()) do | |
if v then | |
result = false | |
break | |
end | |
end | |
return result | |
end | |
-- verify that *only* the ctrl key flag is being pressed | |
local onlyCtrl = function(ev) | |
local result = ev:getFlags().ctrl | |
for k,v in pairs(ev:getFlags()) do | |
if k ~= "ctrl" and v then | |
result = false | |
break | |
end | |
end | |
return result | |
end | |
-- the actual workhorse | |
module.eventWatcher = eventtap.new({events.flagsChanged, events.keyDown}, function(ev) | |
-- if it's been too long; previous state doesn't matter | |
if (timer.secondsSinceEpoch() - timeFirstControl) > module.timeFrame then | |
timeFirstControl, firstDown, secondDown = 0, false, false | |
end | |
if ev:getType() == events.flagsChanged then | |
if noFlags(ev) and firstDown and secondDown then -- ctrl up and we've seen two, so do action | |
if module.action then module.action() end | |
timeFirstControl, firstDown, secondDown = 0, false, false | |
elseif onlyCtrl(ev) and not firstDown then -- ctrl down and it's a first | |
firstDown = true | |
timeFirstControl = timer.secondsSinceEpoch() | |
elseif onlyCtrl(ev) and firstDown then -- ctrl down and it's the second | |
secondDown = true | |
elseif not noFlags(ev) then -- otherwise reset and start over | |
timeFirstControl, firstDown, secondDown = 0, false, false | |
end | |
else -- it was a key press, so not a lone ctrl char -- we don't care about it | |
timeFirstControl, firstDown, secondDown = 0, false, false | |
end | |
return false | |
end):start() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment