【Mac】alt 二回押しでターミナル

インターネットを経巡っていて、Visor という懐しい名前を目にした。Visor はエル・キャピタンくらいまで使えたかっこいいターミナルだ。
 option キーを二回叩くと、しゅっとばかりに、上から横幅いっぱいのターミナルが、まさにサンバイザーみたいに出てくる。いまは TotalTerminal と名前を変えている。残念ながら開発はストップしているらしい。

しかし option 二回でターミナルを呼び出すというのは、便利だった気がする。かっこ良くなくてもいいから実現したいと思った。

Hammerspoon

やり方を考えた時、まっさきに思いついたのが Hammerspoon だ。
 Hammerspoon は下記のサイトからダウンロードできる。

🔗 Hammerspoon

Hammerspoon は、Lua スクリプトで Mac を自動化するツールである。インストールすると、~/.hammerspoon/ というフォルダが作成され、そのなかに init.lua というファイルが作られる。この init.lua にスクリプトを書きこんで、さまざまな操作を仕掛ける。ウィンドウを動かしたりもできるらしい。
 ドキュメントは以下のリンクにある。Google Chrome でアクセスすると、比較的わかりやすく翻訳してくれる。

🔗 入門
 🔗 ハンマースプーンのドキュメント

最初はなにがなにやら、という感じだったが、hammerspoon で検索していろいろなひとのスクリプトを勉強させてもらい、最近ちょっとだけわかってきた。
 今回はこんなふうに書いた。

init.lua

Hammerspoon を起動し、セキュリティの許可を与えると、かなづちのステータスメニューが出てくる。このメニューのなかに「open config」という項目がある。
 init.lua はこれで開ける。

🔨 init.lua
firstAlt = false
secondAlt = false

local function cancelAlt()
    firstAlt = false
    secondAlt = false
end

local function changeTerminal(event)
    local c = event:getKeyCode()
    local f = event:getFlags()
    if event:getType() == hs.eventtap.event.types.flagsChanged then
        if f['alt'] then
            if c == 58 or c == 61 then
                if firstAlt then
                    secondAlt = true
                end
                firstAlt = true
                hs.timer.doAfter(0.5, function()
                    cancelAlt()
                end)
                if firstAlt and secondAlt then
                    cancelAlt()
                    hs.application.launchOrFocusByBundleID('com.apple.Terminal')
                end
            else
            	cancelAlt()
            end
        end
    end
end
opop = hs.eventtap.new({hs.eventtap.event.types.flagsChanged}, changeTerminal)
opop:start()

一番下のほうで、changeTerminal という新しい eventtap を作成している。
hs.eventtap.event というのは、キーボードやマウスなどから入力があると type という定数を返してくれる。
 今回使うのは、types.flagsChangedというもの。flagsChanged はコマンドやオプションのようなモディファイキーが押されましたよ、と教えてくれる。

スクリプト冒頭で、firstAlt という変数を設定している。この変数は、alt キーが押されると、ただちに true になる。ただしその寿命は短く、0.5 秒後には false へと戻ってしまう。これを指示するのが hs.timer.doAfter という部分だ。
 firstAlt が true の間に、もう一度 alt キーが押されると secondAlt という変数が true になる。
if firstAlt then というのは、if firstAlt == true then という意味だ。
 firstAlt、secondAlt がともに true になった時だけ、ターミナルを呼び出す命令に移る。
hs.application.launchOrFocusByBundleID(ヒント) というのはアプリケーションを起動する命令だ。アプリケーションがすでに起動している時は最前面に持ってきてくれる。
 ヒント、の部分にはアプリケーションのバンドル ID を記入する。
 バンドル ID はターミナルで簡単に調べられる。調べたいアプリケーションを起動してから、以下のコマンドを実行する。

$ lsappinfo info -only bundleid ターミナル
"CFBundleIdentifier"="com.apple.Terminal"

c == 58c == 61 という if があるが、これはキーコードだ。58 が左の alt、61 が右の alt をあらわしている。
 また、入力をキャンセルために、cancelAlt という関数を設置している。

init.lua を保存して Hammerspoon ステータスメニューの「reload config」を実行してみると、想定通りに動作してくれた。
 やっていることはほとんど、簡単な変数の操作にすぎない。それでも、どうにかこうにか動いてくれるのが Hammerspoon のいいところだと思う。