Created
June 22, 2017 14:56
-
-
Save jesseleite/fe4996fee6de1c865b76d9aae0734012 to your computer and use it in GitHub Desktop.
vi mode hammerspoon script
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
-- The following is a script to bring back VI mode in Sierra. | |
-- See: https://gist.github.com/juanmiret/81a21a5ae8d6b6061b0a4e72a8be61b2 | |
local module = {} | |
module.debugging = false -- whether to print status updates | |
local eventtap = require "hs.eventtap" | |
local event = eventtap.event | |
local inspect = require "hs.inspect" | |
local keyHandler = function(e) | |
local watchFor = { | |
h = "left", | |
j = "down", | |
k = "up", | |
l = "right", | |
u = "delete", | |
i = "forwarddelete" | |
} | |
local actualKey = e:getCharacters(true) | |
local replacement = watchFor[actualKey:lower()] | |
if replacement then | |
local isDown = e:getType() == event.types.keyDown | |
local flags = {} | |
for k, v in pairs(e:getFlags()) do | |
if v and k ~= "fn" then -- fn will be down because that's our "wrapper", so ignore it | |
table.insert(flags, k) | |
end | |
end | |
if module.debugging then print("viKeys: " .. replacement, inspect(flags), isDown) end | |
local replacementEvent = event.newKeyEvent(flags, replacement, isDown) | |
if isDown then | |
-- allow for auto-repeat | |
replacementEvent:setProperty(event.properties.keyboardEventAutorepeat, e:getProperty(event.properties.keyboardEventAutorepeat)) | |
end | |
return true, { replacementEvent } | |
else | |
return false -- do nothing to the event, just pass it along | |
end | |
end | |
local modifierHandler = function(e) | |
local flags = e:getFlags() | |
local onlyControlPressed = false | |
for k, v in pairs(flags) do | |
onlyControlPressed = v and k == "fn" | |
if not onlyControlPressed then break end | |
end | |
-- you must tap and hold fn by itself to turn this on | |
if onlyControlPressed and not module.keyListener then | |
if module.debugging then print("viKeys: keyhandler on") end | |
module.keyListener = eventtap.new({ event.types.keyDown, event.types.keyUp }, keyHandler):start() | |
-- however, adding additional modifiers afterwards is ok... its only when fn isn't down that we switch back off | |
elseif not flags.fn and module.keyListener then | |
if module.debugging then print("viKeys: keyhandler off") end | |
module.keyListener:stop() | |
module.keyListener = nil | |
end | |
return false | |
end | |
module.modifierListener = eventtap.new({ event.types.flagsChanged }, modifierHandler) | |
module.start = function() | |
module.modifierListener:start() | |
end | |
module.stop = function() | |
if module.keyListener then | |
module.keyListener:stop() | |
module.keyListener = nil | |
end | |
module.modifierListener:stop() | |
end | |
module.start() -- autostart | |
return module |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment