🐚

zshでOSC 133に対応する

2022/08/02に公開

OSC 133という仕様があります。
これはシェルやREPLでプロンプトと実行結果の出力を一まとまり単位として扱うためのマークを決まったエスケープシーケンスで行うことで、ターミナルエミュレーターが解釈できるようにしようという提案です。

最近のモダンなターミナルエミュレーターはこれをサポートしていて、例えば次のような有名なターミナルエミュレーターで対応しています。

自分は最近WezTermに移行したわけですが、WezTermではScrollToPromptという機能があって、キーバインディングでビューポートの先頭を常に直前のプロンプトにするという便利なことができます。(例えば、出力結果が長いコマンドを実行したときに便利)

これをぜひ使いたいということで、設定を確認したところ、先の仕様提案にzshでの設定方法の例が書いてありました。

_prompt_executing=""
function __prompt_precmd() {
    local ret="$?"
    if test "$_prompt_executing" != "0"
    then
      _PROMPT_SAVE_PS1="$PS1"
      _PROMPT_SAVE_PS2="$PS2"
      PS1=$'%{\e]133;P;k=i\a%}'$PS1$'%{\e]133;B\a\e]122;> \a%}'
      PS2=$'%{\e]133;P;k=s\a%}'$PS2$'%{\e]133;B\a%}'
    fi
    if test "$_prompt_executing" != ""
    then
       printf "\033]133;D;%s;aid=%s\007" "$ret" "$$"
    fi
    printf "\033]133;A;cl=m;aid=%s\007" "$$"
    _prompt_executing=0
}
function __prompt_preexec() {
    PS1="$_PROMPT_SAVE_PS1"
    PS2="$_PROMPT_SAVE_PS2"
    printf "\033]133;C;\007"
    _prompt_executing=1
}
preexec_functions+=(__prompt_preexec)
precmd_functions+=(__prompt_precmd)

これを .zshrc に記述してみたところ、無事にOSC 133のエスケープシーケンスが出力されるようになって快適この上ないです!

Discussion