Hammerspoon で未熟 SandS

 Lua という言語で、Mac を操る Hammerspoon というソフトウェア。
 ホットキーを設定したり、キーリマップしたり、キーボードでウィンドウを動かしたりもできるらしい。
 macOS Sierra で、Karabiner というキーリマップアプリが使えなくなってしまったので、にわかに注目を浴びている、という印象。
 Hammerspoon は Lua というプログラミング言語でさまざまな設定をする。
 Lua というのは比較的学習が容易なのだそうで、おれも、SandS を Hammerspoon で実現すべく、がんばってみた。


スポンサード リンク

 SandS というのは、スペースにシフトキーの機能を持たせるキーコンビネーションのひとつである。単独でスペースキーを押した時は通常どおり、空白が入力される。スペースキーと別のキーを一緒に押した時だけ、シフトキーのように振る舞うのだ。
 日本語入力のひとつに SKK ってのがあるけど、それを使うとき、この SandS は便利なんである。
 

未熟 SandS に出来ないこと。

 というわけでどうにか作ったんだけど、おれはただの群馬の中年おじさんなので、かなり不細工なコードになってると思う。最終学歴は偏差値 40 を下回る高校だしさ。今朝も水道が止まってて、トイレでうんこが流れなくてあたふたしたよ。その程度のやつが作ったもんだから、出来ないことがたくさんある。
 

  • スペースキーを押しっぱなしにすると、普通は連続で空白が入力されるが、この未熟 SandS を適用すると、それが利かなくなる。利くけど、不安定。
  • 正確にシフトの機能を再現できてない。シフトキーを押し続けながら「fbi」とキーを押せば、「FBI」と入力されると思う。この未熟 SandS だと、「Fbi」となってしまう。一応できるようになった。
  • 時々動作が変。Mac の AquaSKK で使えりゃいいや、程度の話だったはずなのに、AquaSKK で使っていて時々、変換モードに入れないことがある。
  • safari で、例えば Gmail でメールを書いている時など、「このページから移動してもよろしいですか?」というダイヤログが頻出する。これはサイトのショートカットキーとかぶっているのかもしれない。

 あと、時々まったく効かなくなることがある。どうにかなったかも。
 そういう場合は、Hammerspoon のメニューバーアイコンから、「Reload Config」を実行するといいみたいだ。
 

init.lua

 以下はコード。
 


local spaceOn = false
local shiftOn = false

local function flagCheck(flag)
    local mods = {'fn', 'cmd', 'ctrl', 'alt', 'shift'}
    local modifier = false
    for i, value in ipairs(mods) do
        if flag[value] then modifier = true end
    end
    return modifier
end

local function insertSpace()
    hs.eventtap.keyStroke({}, "space", 5000)
end

local function sandsEvent(event)
    local c = event:getKeyCode()
    local f = event:getFlags()
    if event:getType() == hs.eventtap.event.types.keyDown then
        if c == 49 then
            if flagCheck(f) == false then
                if spaceOn == false and shiftOn == false then
                    spaceOn = true
                    event:setKeyCode(-1)
                else
                    spaceOn = false
                    shiftOn = false
                end
            end
        elseif spaceOn and c ~= 49
            if flagCheck(f) == false then
                shiftOn = true
                event:setFlags({shift=true})
            end
        end
    elseif event:getType() == hs.eventtap.event.types.keyUp then
        if c == 49 and flagCheck(f) == false then
            if spaceOn and shiftOn == false then
                insertSpace()
            else
                spaceOn = false
                shiftOn = false
            end
        end
    end
end
eventtap = hs.eventtap.new({hs.eventtap.event.types.keyDown, hs.eventtap.event.types.keyUp}, sandsEvent)
eventtap:start()

(※ ctrl + space とか、cmd + space の時、動作がおかしかったので修正 17-02-03)
(※ だんだんわかってきて、少しまともな形にした 17-02-06)
(※ また少し修正 17-02-08)
(※ 関数をグローバル変数に入れてから実行するといいらしいので修正 17-02-9)

 冒頭に出てくる flagMatches という名前の関数は、スペースにシフトの機能をくっつける肝なんだと思うんだけど、下のページの成果物を大いに参考にさせていただいた。というか、パクった。すみません。
 以下のページを大変、参考にさせていただきました。
 
 IntelliJとかJVMのIDE使いでもKarabinerなしでバックスラッシュを片手入力したい – Qiita
 
 また途中、キーコードを -1 にセットする。という一文がある。
 event:setKeyCode(-1)
 これ多分、不正なやり方だと思う。
 スペースキーを押すと、当然スペースが入力される。SandS の場合、一時的にそれを抑制する必要があると思うんだけど、やり方がわからなかった。
 なので、やり口として怪しいけどキーコードを -1 にしちゃえば、なんも入力されねーだろ、というおじさんの創意工夫なんである。
 nil というのを覚えました。
 nil を引数に入れると怒られることに気づきましたので、元に戻します。右往左往っぷりが我ながらひどい。
 
 最後のほうにある doAfter(0.05, stopSands) ってのは、0.05 秒後に stopSands という命令を実行しろっていう文なんだけど、どうして遅延実行しなくちゃいけないのかよくわからない。
 とにかく 0.05 秒たってからやるとうまくいくのだ。
 このへん、すごくピーキーというか頼りない感じなんだけど、ひとまずはこれしか方法がわからない。

 なんでこんなことしてたんだろ……。よくわからない。
 
 という、ちょっと背伸びして難しいことしているおじさんの作なので、質問とか、動かないとか、そういうのには答えられないです。ごみん。
 
 だれか賢いひとがやれば、SandS はもっと冴えた方法で出来ると思う。だれか、やるよってひとがいたら、やって欲しい。おれは毎日のようにググって探すから。以上よろしくお願いいたします。

追記

 と、思ったら karabiner-element で SandS が出来るようになったみたい。

macOS Sierra で キーバインドをカスタマイズ – Qiita

 ありがてーよー。
 ありがてーよー。
 

スポンサードリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です