Last active
September 4, 2022 08:33
-
-
Save rizumita/00a177578dbd23f65904af5e4810af5b to your computer and use it in GitHub Desktop.
Hammerspoon DvorakJP config
This file contains hidden or 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
local function Split (inputstr, sep) | |
if sep == nil then | |
sep = "%s" | |
end | |
local t={} | |
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do | |
table.insert(t, str) | |
end | |
return t | |
end | |
local function Contains(table, val) | |
for i=1,#table do | |
if table[i] == val then | |
return true | |
end | |
end | |
return false | |
end | |
-- local log = hs.logger.new("my_logger","debug") | |
local log = hs.logger.new("my_logger","error") | |
local map = hs.keycodes.map | |
local vowels = Split("a,i,u,e,o", ",") | |
local consonants = Split("b,c,d,f,g,h,j,k,l,m,n,p,q,r,s,t,v,w,x,y,z", ",") | |
local y1Combs = Split("p,r,l,n,s,q,j,x,w,v,z", ",") | |
local y2Combs = Split("f,g,k,d,h,t,b,m", ",") | |
local y1Key = "h" | |
local y2Key = "n" | |
local doubleVowelsSyllabicNasalKeys = {"'", ",", ".", ";", "q", "j", "k", "x"} | |
local onC2K = false | |
local onY1Comb = false | |
local onY2Comb = false | |
local isDoubleVowelsSyllabicNasalPotential = false | |
local replacedCount = 0 | |
local cancelTimer = nil | |
local fastKeyStroke = function(character) | |
local event = require("hs.eventtap").event | |
event.newKeyEvent({}, character, true):post() | |
event.newKeyEvent({}, character, false):post() | |
replacedCount = replacedCount + 1 | |
end | |
local function reset() | |
onC2K = false | |
onY1Comb = false | |
onY2Comb = false | |
end | |
local function startCancelTimer() | |
if cancelTimer then | |
cancelTimer:stop() | |
cancelTimer = nil | |
end | |
cancelTimer = hs.timer.doAfter(1.0, function() | |
log.i("cancel states") | |
reset() | |
end) | |
end | |
local function doubleVowelsSyllabicNasal(key) | |
if key == "'" then | |
fastKeyStroke("a") | |
fastKeyStroke("i") | |
elseif key == "," then | |
fastKeyStroke("o") | |
fastKeyStroke("u") | |
elseif key == "." then | |
fastKeyStroke("e") | |
fastKeyStroke("i") | |
elseif key == ";" then | |
fastKeyStroke("a") | |
fastKeyStroke("n") | |
fastKeyStroke("n") | |
elseif key == "q" then | |
fastKeyStroke("o") | |
fastKeyStroke("n") | |
fastKeyStroke("n") | |
elseif key == "j" then | |
fastKeyStroke("e") | |
fastKeyStroke("n") | |
fastKeyStroke("n") | |
elseif key == "k" then | |
fastKeyStroke("u") | |
fastKeyStroke("n") | |
fastKeyStroke("n") | |
elseif key == "x" then | |
fastKeyStroke("i") | |
fastKeyStroke("n") | |
fastKeyStroke("n") | |
end | |
isDoubleVowelsSyllabicNasalPotential = false | |
end | |
local function dobuleVowelsSyllabicNasalIfNeeded(key) | |
if Contains(doubleVowelsSyllabicNasalKeys, key) then | |
doubleVowelsSyllabicNasal(key) | |
return true | |
else | |
return false | |
end | |
end | |
local function y2CombIfNeeded(key) | |
if onY2Comb and key == y2Key then | |
fastkeyStroke("y") | |
return true | |
else | |
return false | |
end | |
end | |
local function dvorakJPEvent(event) | |
if hs.keycodes.currentMethod() == "Hiragana" then | |
if replacedCount > 0 then | |
replacedCount = replacedCount - 1 | |
return false | |
end | |
local flags = event:getFlags() | |
if next(flags) == nil then -- no flags | |
startCancelTimer() | |
local code = event:getKeyCode() | |
local key = map[code] | |
log.i("key: " .. key) | |
-- 出力 | |
if onC2K then | |
fastKeyStroke("k") | |
end | |
if onY1Comb and key == y1Key then | |
fastKeyStroke("y") | |
reset() | |
return true | |
elseif onY2Comb and key == y2Key then | |
fastKeyStroke("y") | |
reset() | |
return true | |
elseif Contains(vowels, key) then | |
fastKeyStroke(key) | |
isDoubleVowelsSyllabicNasalPotential = false | |
reset() | |
return true | |
elseif isDoubleVowelsSyllabicNasalPotential and Contains(doubleVowelsSyllabicNasalKeys, key) then | |
doubleVowelsSyllabicNasal(key) | |
return true | |
else | |
isDoubleVowelsSyllabicNasalPotential = false | |
end | |
-- 状態遷移 | |
isDoubleVowelsSyllabicNasalPotential = Contains(consonants, key) | |
if key == "c" then -- Start C to K | |
onC2K = true | |
onY1Comb = false | |
onY2Comb = true | |
return true | |
elseif Contains(y1Combs, key) then -- Start Y1 combination | |
onY1Comb = true | |
onY2Comb = false | |
elseif Contains(y2Combs, key) then -- Start Y2 combination | |
onY1Comb = false | |
onY2Comb = true | |
else | |
reset() | |
end | |
else -- Reset | |
replacedCount = 0 | |
reset() | |
end | |
end | |
end | |
dvorakJP = hs.eventtap.new({hs.eventtap.event.types.keyDown}, dvorakJPEvent) | |
dvorakJP:start() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment