Slateを入れてみた

Macで起動中のアプリを切り替えるのに、⌘+Tabだけだとたくさん起動しているときに選択するために連打するのが面倒だし頻繁に使うものは一発で切り替わるようにしたい、というのがあって、
今までずっとそれをQuicksilverのHotKey機能を利用して

  • ⌘+Ctrl+Q でiTerm2
  • ⌘+Ctrl+W でEmacs
  • ⌘+Ctrl+E でChrome

みたいに左手の操作だけで切り替えられるようにしていた。

ところで最近「Slateというのが面白い」という話を某所で聞いたので試しに入れてみた。
GitHub - jigish/slate: A window management application (replacement for Divvy/SizeUp/ShiftIt)
DivvySizeUpといったウィンドウ操作系ツールとして使えるもののようだけど(両方つかったことないから知らない)、
~/.slateに設定ファイルを書くことで様々な操作を規定してキーバインド設定できたりして良い。さらに~/.slate.jsJavaScriptコードで設定を書くこともできる、というのが面白い。slateもしくはSUnderscore.jsがglobal objectとして使うことができて、それらを使って色々できる。
JavaScript Configs · jigish/slate Wiki · GitHub

S.bind('q:ctrl,cmd', function (win) {
    win.doOperation(S.operation('focus', { app: 'iTerm' }));
});

と書くことで⌘+Ctrl+QでiTermにfocusさせる、といったことが出来る。
これくらいならJSで書く必要もないのだけど、これは起動していないときに何も起こらないので、もし指定したappが立ち上がっていない場合はshellコマンド経由で/usr/bin/openを使って起動させた上でfocusさせるようにする。条件分岐はプログラミング言語で書きやすいので嬉しい。

S.bind('q:ctrl,cmd', function (win) {
    var apps = [];
    S.eachApp(function (app) { apps.push(app.name()); });
    if (! _.find(apps, function (name) { return name === 'iTerm'; })) {
        win.doOperation(
            S.operation('shell', {
                command: '/usr/bin/open -a iTerm',
                waithFoeExit: true
            })
        );
    }
    win.doOperation(S.operation('focus', { app: 'iTerm' }));
});

S.eachApp()で起動中のappを列挙できるので、その中にfocusしたいappの名前があるか否かを調べて見つからなかったらopen。
あとは共通で同じようなことができるように関数を定義してやって、

var launch_and_focus = function (target) {
    return function (win) {
        var apps = [];
        S.eachApp(function (app) { apps.push(app.name()); });
        if (! _.find(apps, function (name) { return name === target; })) {
            win.doOperation(
                S.operation('shell', {
                    command: "/usr/bin/open -a " + target,
                    waithFoeExit: true
                })
            );
        }
        win.doOperation(S.operation('focus', { app: target }));
    };
};
S.bind('q:ctrl,cmd', launch_and_focus('iTerm'));
S.bind('w:ctrl,cmd', launch_and_focus('Emacs'));
S.bind('e:ctrl,cmd', launch_and_focus('Google Chrome'));
S.bind('r:ctrl,cmd', launch_and_focus('Safari'));
S.bind('t:ctrl,cmd', launch_and_focus('Twitter'));

という感じでたくさんHotKeyでの切り替えを定義していける。

…というようなことが下記記事に書いてありまして大変参考になりました。
Slateでアプリ切り替えをする設定 - ミントフレーバー緑茶

でもこれ、"Google Chrome"のときにopenコマンドが動かない。無条件でスペースで区切ってコマンドに引数として渡されてしまうらしく、クォートしてもダメ。のようだったので一応pull req送ってみた。。


なんかたまに変なエラーが出ておかしくなるけど、ほぼ問題なく快適に使えている。のでQuicksilverは卒業してlauncherとしてはAlfredを使うようにしてみた。
Slate自体はウィンドウの移動とかサイズ変更とか柔軟に色々できるはずなのでもう少し色々設定して試してみたい。オヌヌメ設定とかあれば教えてください…