やりたいこと
zshで以下2つに当てはまると、2行目にRPROMPT(プロンプトの右側)が来てしまいます。
-
.zshrcでPROMPT末尾に改行コードを入れて、コマンドを新しい行から入力するようにしている -
RPROMPTを有効にしている
これで困るのが、ターミナルの内容をSlackなどにコピペして共有しようとしたとき、RPROMPTまでコピーされてしまい、それを消す手間ができてしまうということです。
なんでユーザーがコマンドを入力する行と同じ行にRPROMPTを出す仕様なんだろう。。
それをなんとかしたいというニッチな投稿です。
ちなみに何らかの設定で、シンプルにこれを解消する方法は思いつきませんでした。
(RPROMPTは改行コード効きません。ZLE_RPROMPT_INDENTを負の整数にしたりしても無視されます。)
解決方法の案
案1: RPROMPT使うのやめて、ANSIエスケープシーケンスで無理やり制御して描画する
ちょっとこんなやり方しかわからないです。
.zshrcを以下のようにします。
# 出したい情報をCUSTOM_RPROMPTに格納しておく
print_to_rprompt() {
col=$(( COLUMNS - 8 ))
print -Pn "\e7\e[1A\e[${col}G${CUSTOM_RPROMPT}\e8"
}
TMOUT=1
TRAPALRM() {
print_to_rprompt
}
COLUMNSはウィンドウ幅が入っているzshの環境変数です。
右に出す文字を、先頭に半角スペースを挿入することで、全て8文字に統一した上で上記のように実装しました。
制御コードによる操作の説明をします。
- ESC7: 現在のカーソル位置などを保存する
- ESC[1A: カーソル位置を1行上に移動
- ESC[{NUM}G: カーソルを左端からNUMだけ右に移動
- ESC8: 保存していたカーソル位置などの復帰
そして、TRAPALRMでこれを1秒毎に実行します。
つまり、毎秒printで出したい情報を出し続けるということになります。
私は、gitのstatusと時刻をRPROMPTに出したいのですが、この方法だとプロンプトの右側の情報は保持されずに常に書き換えられるため、時刻はPROMPTにうつしてgitのstatusだけ表示するようにしました。
以下のような感じになります。
毎秒更新するあたり、本来のRPROMPTとは機能が異なってしまっていますが、gitのstatusをリアルタイムで更新して表示してくれるのでむしろ気に入りました。
案2: PROMPTに必要なだけのスペースを計算して挿入する
これでもできそうです。こちらのほうが本来やりたかったことに近いかも。
ただ今回は案1にしました。
案3: tmuxを使う
tmuxでstatus-position topで出来るらしいです。
tmuxにしようかな。。
まとめ
試行錯誤してるうちに、以下のようなプロンプトができました。
- 複数行プロンプトの場合も、1行目の右側に情報を表示
- 毎秒更新(エディタでいじればそのステータスが反映される)
なにか他にいい方法があれば、ぜひ教えていただきたいです。。

