PS1のANSIエスケープシーケンスにより誤った長さの計算が発生する

PS1のANSIエスケープシーケンスにより誤った長さの計算が発生する

PS1私の設定には.zshrc複数のANSIエスケープシーケンスが含まれています。同等の定義はBashではうまく機能しますが、Zsh(v5.8.1)ではシェルがプロンプト幅を誤って計算しているようです。したがって、より長いコマンドを入力すると、コマンドライン突然消える、タッチタイピング中です。場合によっては、PS1改行文字が含まれていない場合でも、カーソルはプロンプトの後ろの次の行に配置されます。

私はすでに使用しています\001…\002エスケープシーケンスreadlineはこれを使用して、各ANSIエスケープシーケンスの長さの計算を調整します。残念ながら、これはZshには十分ではないようです(以下の例ではZshがないようです)。どの効果がありましたが、実際より複雑な場合はPS1状況が改善されているようです。一部、少なくとも)。

これは問題を示す例です(コメントは角括弧で囲む必要があると思うANSIエスケープシーケンスの部分を強調します\001…\002)。

PS1=$'\001\e[38;2;1;1;1m\e[48;5;250m\002}\001\e[38;5;250m\e[48;2;1;1;1m\002} '
#     \001--------------------------\002 \001--------------------------\002

このプロンプトと80列の端末では、25文字を入力すると、プロンプトを含む完全なコマンドが消えます。バックスペースキーを使用すると、文字が再表示されず、代わりにカーソルが前の行に移動します。

これはこの行動のAsciinemaの説明です。

このデモでは、シェルの他のすべてのカスタマイズを無効にしました。

(私は実際にnf-pl-left_hard_dividerU + E0B0を使用しています。素晴らしいフォントsの代わりに使用されますが、}これは問題には影響しません。 )

私は何が間違っていましたか? Zshプロンプト定義でANSIエスケープシーケンスを使用する方法は?

答え1

では、エスケープ文字を使用してプロンプトを出すzshことができます。 ~から%{%}info zsh 'prompt expansion':

%{...%}
リテラルエスケープシーケンスとして文字列を含みます。中括弧内の文字列はカーソル位置を変更しないでください。サポートペアは入れ子にすることができます。

%と{の間の正の引数は、以下の%Gで説明されているように処理されます。

したがって、PS1='%{\e[...m%}'zshにはほとんどの視覚効果に対する独自のヒント拡張演算子があるため、エスケープシーケンスをハードコーディングする必要がないことを除いてください。

たとえば、256パレットの背景色をFRGBに設定し#010101、背景色を250に設定するには、次の手順を実行します。B

PS1='%F{#010101}%K{250}Text%f%k%# '

これを使用print -Pしてヒント拡張を実行して、対応するエスケープシーケンスが作成されていることを確認することもできます。

$ print -rP '%F{#010101}%K{250}' | sed -n l
\033[38;2;1;1;1m\033[48;5;250m$

トゥルーカラーエスケープシーケンスをサポートしていませんが、256パレットをサポートする端末の仕様にzsh/nearcolor最も近い色を提供するモジュールもあります。#RRGGBB

$ zmodload zsh/nearcolor
$ print -rP '%F{#010101}%K{250}' | sed -n l
\033[38;5;16m\033[48;5;250m$

関連情報