Skip to content

Instantly share code, notes, and snippets.

@RichardForrester
Last active September 26, 2018 01:06
Show Gist options
  • Select an option

  • Save RichardForrester/fe1a6bb0fe1672ee2272bbc5d9d4eb19 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown
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