Last active
February 2, 2017 07:19
-
-
Save tanakahisateru/ea015d3e5ee5e088898411c2643f1123 to your computer and use it in GitHub Desktop.
Perfect backslash(\) for Mac JIS keyboard users
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
--- Perfect backslash(\) for Mac JIS keybord users | |
-- The problem: | |
-- On Mac, Japanese IME setting to replace Yen-backslash is ignored by | |
-- IntelliJ, jEdit or such as because JVM uses another keymap traditionally. | |
-- Solution: | |
-- Use Hammerspoon (http://www.hammerspoon.org/) instead of Japanese IME | |
-- setting. Paste below to your ~/.hammerspoon/init.lua file. | |
-- @author Hisateru Tanaka (tanakahisateru@gmail.com) | |
local VK_1 = 0x12 | |
local VK_ESC = 0x35 | |
-- Secret key codes not included in hs.keycodes.map | |
local VK_JIS_YEN = 0x5d | |
local VK_JIS_UNDERSCORE = 0x5e | |
--local log = hs.logger.new('keyhook','debug') | |
function flagsMatches(flags, modifiers) | |
local set = {} | |
for _, k in ipairs(modifiers) do set[string.lower(k)] = true end | |
for _, k in ipairs({'fn', 'cmd', 'ctrl', 'alt', 'shift'}) do | |
if set[k] ~= flags[k] then return false end | |
end | |
return true | |
end | |
-- NEVER define as local variable! | |
jisKeyboardFilter = hs.eventtap.new({ | |
hs.eventtap.event.types.keyDown, | |
hs.eventtap.event.types.keyUp | |
}, function(event) | |
local c = event:getKeyCode() | |
local f = event:getFlags() | |
-- log.d(...) | |
if c == VK_JIS_YEN then | |
-- To input \ even if JVM, toggle Option key status when Yen key. | |
if flagsMatches(f, {'alt'}) then | |
event:setFlags({}) | |
elseif flagsMatches(f, {}) then | |
event:setFlags({alt=true}) | |
end | |
-- Hint: Never replace key code to backslash itself because JIS | |
-- keyboard does'nt have phisical backslash and assignes it to close | |
-- bracket (]) key. | |
elseif c == VK_JIS_UNDERSCORE then | |
-- Also map single undetscore (_) key to backslash (\). | |
if flagsMatches(f, {}) then | |
event:setKeyCode(VK_JIS_YEN) | |
event:setFlags({alt=true}) | |
end | |
elseif c == VK_1 then | |
-- Customization example: Option+1 => ESC | |
if flagsMatches(f, {'alt'}) then | |
event:setKeyCode(VK_ESC) | |
event:setFlags({}) | |
end | |
end | |
end) | |
jisKeyboardFilter:start() |
Fixed a bug where event moniterling stops randomly.
Try collectgarbage('collect')
in Hammerspoon debug console. If an object created by hs.eventtap.new()
is not in global variable table, it would be removed from Hammerspoon while garbage collection running. I guess :start()
method does not hold a reference to event object itself unlike such JavaScript's setTimeout()
.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
See Hammerspoon/hammerspoon#1103