前置き

最近リモートの VPS とテモートの VM で同時に作業していて、どっちがどっちのプロンプトかわからなくなるということがよくあります。

そこで、Terminal.app の背景を接続先に応じて変化させられたら便利です。 この解決法については、たとえば次の記事にあります:

問題点

とはいえ、上のやり方には幾つか問題点や不満があります。

タブが最前決め打ち
tab 1 of window 1 決め打ちなので、ウインドウを切り替えたタイミングによっては違うタブの色が変わってしまう。
ダミーのコマンドを用意する必要がある
最優先のパスの所に同名のコマンドを作って置くわけで、他のプロセスが sshmosh を呼ぶときに思わぬ問題が発生する可能性があるし、気付きづらい。
パスの設定によっては機能しない
上の問題と関連して、パスが適切に通っている場所に配置しないと、優先順位の問題などで機能しなくなる可能性がある。

これらを解決しましょう。

タブの決め打ちを何とかする

まず最初の問題については、AppleScript レベルで window には ID が振られているので、呼び出された瞬間にその id を取得すれば良い。ただ、 tab には ID が割り振られていないようなので、ウィンドウの中で左から何番目かを覚えておく他に解決法はないみたい。なので、途中で同じウインドウの前のタブを閉じたりして順番が変わっていると、結局変更を辿ることができない。

上書きパスの問題

ぼくは zsh を使っているので、下記を参考に zsh hooks を使うことにしました。

上の情報を使って、preexec フックで ssh や mosh が呼び出されていたらサーバ名によってテーマを切り替えるようにすればよい。その際にシェル変数として、ウィンドウのIDとタブの位置、それから元々のテーマを覚えておいて、その変数が定義されている場合に限り precmd フックで覚えておいたタブを元のテーマに復帰させればよい。

出来上がったもの

以下の内容を ~/usr/share/ssh-mosh-bgch-hook.sh とか適当な名前で保存し、 ~/.zshrc の適当な位置に source ~/usr/share/ssh-mosh-bgch-hook.sh という行を追加しとけばいい:

autoload -Uz add-zsh-hook;

unset __WINDOWLOC;
unset __PREVSETID;

function set_bg () {
  osascript -e "tell app \"Terminal\" to set the current settings of the tab ${__WINDOWLOC[1]} of window id ${__WINDOWLOC[2]} to settings set \"$1\""
}

function ssh-mosh-observe() {
    mycmd=(${(s: :)${1}});
    case ${mycmd[1]} in
        ssh|mosh)
            HOSTNAME=${mycmd[-1]};
            __WINDOWLOC=(`osascript -e "tell app \"Terminal\" to selected tab of the window 1" | cut -d' ' -f 2,6`);
            __PREVSETID=`osascript -e "tell app \"Terminal\" to name of current settings of tab ${__WINDOWLOC[1]} of the window id ${__WINDOWLOC[2]}"`;
            case $HOSTNAME in # host name
                sakura-vps) set_bg "Sakura";;
                ubuntu-vm)  set_bg "VM";;
                *)          set_bg "Pro";;
            esac;;
    esac
}

add-zsh-hook preexec ssh-mosh-observe

function ssh-mosh-post() {
    if [ -n "${__WINDOWLOC-}" ]; then
        set_bg ${__PREVSETID};
        unset __WINDOWLOC;
        unset __PREVSETID;
    fi
}

add-zsh-hook precmd ssh-mosh-post

ここで、Sakura とか Pro とか VM とかってのは、ターミナル環境設定の「プロファイル」一覧に上がっているテーマの名前。サーバ毎に適当に色とか背景画像とかを作れば良いだけの話。

デモ

以下のように、非常にシームレスにテーマが入れ替わるのがわかると思う:

デモを御覧頂けないのが残念です

また、次のように ssh が終了した時に背面にあっても、(タブさえ動いていなければ)元のテーマに復帰するようになっている:

Gyazo

不満点

  • タブの位置が決め打ち。こればかりは tabid みたいのがないから仕方ない。
  • サーバ名が ssh / mosh コマンドのラストに来ると決め打ちしている。これは真面目にパーザ書けばいいだろうけど、ダルいしまあ実用上はそんなに問題ないだろう。

Comments