screen のウィンドウタイトルをカレントディレクトリにする方法

最小限の環境に自分をあわせるタイプと、自分用の環境をフルカスタマイズするタイプの人がいるというような話題が昨日でたのですが、私は圧倒的に後者です、というのは私を少しでも知る人には周知の事実でしょう。思い起こせば、高校時代使っていたラケットに端を発するとか、まぁそれはいいとして。

そういうわけで、私の超絶賛するツールを人に勧めても、白い目で見られることが多々*1。でも、screen はマイナーとはいわせないぞ。screen を使っていて不満なのは、ウィンドウの数が 10 こ位になるとどこで作業していたのか忘れてしまうので、今実行しているコマンドなりカレントディレクトリを表示して欲しいなぁとずっと思っていたら、実装済みですよということを今日になって知りました。なんと。

死ぬほど man が長いのですが、下の方の「タイトル (ウィンドウの命名)」という章に書いてあります。

実行しているコマンド名をウィンドウ名にする方法

これには、現在実行しているシェルのプロンプトを screen が認識してやる必要があります。つまり、プロンプトの次にあなたがタイプした文字列が、今実行しているコマンドになるからです。あなたのシェルのプロンプトが "$ " で終わるとします。ここで、.screenrc に以下を追加。

shelltitle '$ |shell:'
より左がプロンプトの最後の文字列です(この文字列を検索します)。 の右がウィンドウ名になりますが、: を最後につけておくと、: の後ろに実行中のコマンド名が追加されます。で、これで終わりではないです。シェルのプロンプトに "k\" の文字列を追加する必要があります。screen はこの文字列を含んで、かつ "$ " で終わるとき、そのあとに入力された文字列がユーザーのタイプしたコマンドと認識して、ウィンドウのタイトルをかえます。

.zshrc ならこんなかんじ。 は \033 です。\ は \134 で書いています。

if [ "$TERM" = "screen" ]; then
  PROMPT=$'\033k\033\134'$PROMPT
fi

カレントディレクトリを表示する方法

上の説明は man に書いてあったまんまで、めでたしめでたしだったのですが、人間欲深いモノでカレントディレクトリを表示させたい衝動にかられます。というか、プログラムを実行していないときの方が多い。実はこれはもっと簡単で、screen は任意のプログラムが "khogehoge\" という文字列を吐くと、そのウィンドウのタイトルを hogehoge にかえるという機能が備わっています(このとき ... は画面出力されません)。なので、hogehoge の代わりに現在のディレクトリを表示させればよいのです。ここでは、プロンプトに細工をしてやります。プロンプト中に、上記文字列を埋め込んでやればいいのですね。以下に、.zshrc を。

if [ "$TERM" = "screen" ]; then
  PROMPT=$'\033k%(4~,%-1~/.../%2~,%~)\033\134'$PROMPT
fi

簡単にやるなら $'\033k%~\033\134'$PROMPT ですね。パスが全部表示されるとイヤなので、省略しています。この辺は、いやなブログを参考にさせていただきました。

ちなみに、これをやると上記の実行中コマンドを表示させることができなくなります*2。とりあえず、よく使う emacs だけ alias をはりました。

  alias emacs="echo $'\033kemacs\033\134' ;emacs"

enter 押したら自動で echo するようにすればいいのかなぁ。

さらに実行中のプログラム名をウィンドウ名に設定する方法

サーベイ不足で、reject ものである。上記サイトに全部かかれていました。なんか、ボクの 100 倍くらいフルカスタマイズしていてステキすぎる。

preexec はコマンドを実行する直前に呼ばれる関数みたいですね。ここにやりたいことを書いておけと。結局、見よう見まねでこうなりました。本当の使い方はちゃんと理解していない。というか、疲れた。

if [ "$TERM" = "screen" ]; then
  PROMPT=$'\033k%(4~,%-1~/.../%2~,%~)\033\134'$PROMPT

  preexec() {
    local -a cmd; cmd=(${(z)1})
    echo -n $'\033k'$cmd[1]$'\033\134'
  }
fi

結局、.screenrc には全く手を入れず。

*1:そもそも昨日の話もこの類ではないか疑惑があるのですが。皆さん世の中に満足していらっしゃる?

*2:両方できるようにする方法をご存じの方教えてください