ウィンドウタイトルにコマンド名やホスト名等を表示させる

xterm等では、エスケープシーケンス(\033]0;ウィンドウタイトル\a) を使うことでウィンドウタイトルを変更できる。
zshの特殊関数 precmd (プロンプトの表示前に実行される) や preexec (コマンドの実行前に実行される)で、これを出力するようにすれば、ウィンドウタイトルに実行中のコマンド名やホスト名等を表示させることができる。
複数ウィンドウを開いて作業する際にはとっても便利だ。

http://wiki.fdiary.net/zsh/?FAQ%40zsh%A5%B9%A5%EC#l14
あたりを参考に設定していたのだが、 \a といった文字列を含むコマンドを実行したり、日本語のディレクトリに入ったりすると、そこでエスケープシーケンスは完了と解釈されるらしく、ゴミが表示されてしまう。それじゃ困るので、置換で対策してみた。プロンプトが出るたびにPIDが増えていくのが気持ち悪かったので、外部コマンドを利用しないようにしている。

if [ "$TERM" = xterm -o "$TERM" = xterm-color -o "$TERM" = kterm ]; then
        print_esc() { print -nr ${1//[^\ -~]/_} }  #unprintableな文字を_に置換
        precmd() { print -n "\e]0;"; print_esc "[${PWD/~HOME/~}:$HOST]"; print -n "\a" }
        preexec() { print -n "\e]0;"; print_esc "$1 [${PWD/~HOME/~}:$HOST]"; print -n "\a" }
fi

${PWD/~HOME/~} なんてのがちょっと苦し紛れ。`print -nP "%~"` 相当のことがしたかったんだけど、forkしないように`〜`を避けたためこうなった。