やりたいこと
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行目の右側に情報を表示
- 毎秒更新(エディタでいじればそのステータスが反映される)
なにか他にいい方法があれば、ぜひ教えていただきたいです。。