Skip to content

Instantly share code, notes, and snippets.

@RichardForrester
Last active September 26, 2018 01:06
Show Gist options
  • Save RichardForrester/fe1a6bb0fe1672ee2272bbc5d9d4eb19 to your computer and use it in GitHub Desktop.
Save RichardForrester/fe1a6bb0fe1672ee2272bbc5d9d4eb19 to your computer and use it in GitHub Desktop.
Karabiner Elements and Hammerspoon on MacOS Sierra
-- ln -s ~/repos/config/init.lua ~/.hammerspoon/init.lua
-- Global variable for the Command Mode
cMode = hs.hotkey.modal.new({}, "F17")
-- Global variable for Delete Mode
dMode = hs.hotkey.modal.new({}, 'F20')
-- Global variable for Select Mode
sMode = hs.hotkey.modal.new({}, 'F19')
-- Global variable to store last Command
lastCommand = nil
function callLast()
return lastCommand()
end
-- Command Mode bindings
cModeBindings = {
-- up
{ {}, 'i', {}, 'up' },
{ {'shift'}, 'i', {'shift'}, 'up' },
{ {'cmd'}, 'i', {'cmd'}, 'up' },
{ {'alt'}, 'i', {}, 'pageup' },
-- down
{ {}, 'k', {}, 'down' },
{ {'shift'}, 'k', {'shift'}, 'down' },
{ {'cmd'}, 'k', {'cmd'}, 'down' },
{ {'alt'}, 'k', {}, 'pagedown' },
-- left
{ {}, 'j', {}, 'left' },
{ {'shift'}, 'j', {'shift'}, 'left' },
{ {'cmd'}, 'j', {'cmd'}, 'left' },
{ {'alt'}, 'j', {'alt'}, 'left' },
-- right
{ {}, 'l', {}, 'right' },
{ {'shift'}, 'l', {'shift'}, 'right' },
{ {'cmd'}, 'l', {'cmd'}, 'right' },
{ {'alt'}, 'l', {'alt'}, 'right' },
-- delete left
{ {}, 'n', {}, 'delete' },
{ {'alt'}, 'n', {'alt'}, 'delete' },
{ {'cmd'}, 'n', {'cmd'}, 'delete' },
-- delete right
{ {}, 'm', {}, 'forwarddelete' },
{ {'alt'}, 'm', {'alt'}, 'forwarddelete' },
{ {'cmd'}, 'm', {'cmd'}, 'forwarddelete' },
}
-- Select Mode bindings
sModeBindings = {
-- up
{ {}, 'i', {'shift'}, 'up' },
{ {'cmd'}, 'i', {'cmd', 'shift'}, 'up' },
{ {'alt'}, 'i', {'shift'}, 'pageup' },
-- down
{ {}, 'k', {'shift'}, 'down' },
{ {'cmd'}, 'k', {'cmd', 'shift'}, 'down' },
{ {'alt'}, 'k', {'shift'}, 'pagedown' },
-- left
{ {}, 'j', {'shift'}, 'left' },
{ {'cmd'}, 'j', {'cmd', 'shift'}, 'left' },
{ {'alt'}, 'j', {'alt', 'shift'}, 'left' },
-- right
{ {}, 'l', {'shift'}, 'right' },
{ {'cmd'}, 'l', {'cmd', 'shift'}, 'right' },
{ {'alt'}, 'l', {'alt', 'shift'}, 'right' },
-- delete left
{ {}, 'n', {}, 'delete' },
{ {'alt'}, 'n', {'alt'}, 'delete' },
{ {'cmd'}, 'n', {'cmd'}, 'delete' },
-- delete right
{ {}, 'm', {}, 'forwarddelete' },
{ {'alt'}, 'm', {'alt'}, 'forwarddelete' },
{ {'cmd'}, 'm', {'cmd'}, 'forwarddelete' },
}
-- Bind command mode keys
for i, bnd in ipairs(cModeBindings) do
local function eb()
hs.eventtap.keyStroke(bnd[3], bnd[4])
cMode.triggered = true
end
cMode:bind(bnd[1], bnd[2], eb, nil, eb)
end
-- Command Mode: bind Delete Mode
cMode:bind({}, 'd', nil, function()
hs.eventtap.keyStroke({}, 'F20')
cMode.triggered = true
end)
-- Delete Mode: delete line
function dLine()
hs.eventtap.keyStroke({}, 'space')
hs.eventtap.keyStroke({'cmd'}, 'right')
hs.eventtap.keyStroke({'cmd'}, 'delete')
hs.eventtap.keyStroke({'cmd'}, 'forwarddelete')
lastCommand = dLine
dMode.exit()
end
-- Delete Mode: delete word
function dWordBack()
hs.eventtap.keyStroke({'alt'}, 'left')
hs.eventtap.keyStroke({'alt'}, 'forwarddelete')
hs.eventtap.keyStroke({}, 'delete')
lastCommand = dWordBack
dMode.exit()
end
-- Delete Mode: delete word forwards
function dWordForward()
hs.eventtap.keyStroke({'alt'}, 'right')
hs.eventtap.keyStroke({'alt'}, 'delete')
hs.eventtap.keyStroke({}, 'forwarddelete')
lastCommand = dWordForward
dMode.exit()
end
-- Delete Mode bindings
dModeBindings = {
{ {}, 'l', nil, dLine },
{ {}, 'b', nil, dWordBack },
{ {}, 'w', nil, dWordForward }
}
-- Bind Delete Mode bindings
for i, bnd in ipairs(dModeBindings) do
dMode:bind(bnd[1], bnd[2], nil, bnd[4])
end
-- Command Mode: bind Select Mode
cMode:bind({}, 'v', nil, function()
hs.eventtap.keyStroke({}, 'F19')
cMode.triggered = true
end)
-- Bind Select Mode bindings
for i, bnd in ipairs(sModeBindings) do
local function eb()
hs.eventtap.keyStroke(bnd[3], bnd[4])
end
sMode:bind(bnd[1], bnd[2], eb, nil, eb)
end
-- Enter Command Mode
cModePressed = function()
cMode.triggered = false
cMode:enter()
end
-- Leave Command Mode
-- Escape if no other keys are pressed
cModeReleased = function()
dMode:exit()
sMode:exit()
cMode:exit()
if not cMode.triggered then
hs.eventtap.keyStroke({}, 'ESCAPE')
end
end
-- Bind Command Mode
f18 = hs.hotkey.bind({}, 'F18', cModePressed, cModeReleased)
-- Command Mode: repeat last Command
cMode:bind({}, '.', callLast)
{
"_comment": "ln -s ~/repos/config/karabiner.json ~/.karabiner.d/configuration/karabiner.json",
"profiles": [
{
"name": "Default profile",
"selected": true,
"simple_modifications": {
"caps_lock": "f18",
"escape": "caps_lock",
"right_option": "f17"
}
}
]
}
@RichardForrester
Copy link
Author

If anyone is checking this out, make sure to use Hammerspoon v.0.9.48. There is an issue effecting timing of the repeanfn in v.0.9.49 and greater.

Hammerspoon/hammerspoon#1087

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