私は最近、素晴らしいプロンプトを印刷する関数を書いて、zuperPrompt
.zshrcにPROMPT変数を設定して、次のように関数を呼び出しました。
setopt PROMPT_SUBST
PROMPT='$(zuperPrompt)'
同じ問題を発見しましたここしかし、問題はawkコマンドで使用される改行エスケープ文字にあると思います。改行なしでフルプロンプトを試しましたが、同じ結果が得られました。
機能は次のとおりです。
zuperPrompt() {
# count chars in directory name
num_chars=1
if [ ! $(dirs) = '~' ]; then
let "num_chars=$(basename "`pwd`" | wc -m) - 1"
fi
# draw line
line="\n╭──"
for i in {1..$num_chars}; do
line+="─"
done
line+="──╯"
directory="%F{8}%K{8}%B%F{blue}%1~%k%F{8}"
arrows="%B%F{magenta}❯%B%F{yellow}❯%F{cyan}❯ "
row1="\n%B%F{green}◆ "$directory"─╮"
row2=$line
row3="\n╰─ "$arrows
print -P $row1$row2$row3
}
入力後、Tab キーを押した結果です。python3
ここで何が起こっているのか分かりません。誰でも助けてくれたら、よろしくお願いします!
修正する 私のWebブラウザでこの構文の強調表示を見た後、$ row3が他の色と異なることがわかりました。 $row1$row2 を使用してコードを実行しましたが、正常に動作し、カーソルが移動しません。そこで何が起こっているのか知っている人はいますか?
アップデート2 最後のprint文から-Pオプションを削除しましたが、3行すべてで動作しました。
ベストアンサー1
シェルのデフォルトのプロンプト文字列は、zsh
または変数に割り当てられた文字列です。これには、文字列を目に見えるプロンプトに動的に拡張する方法をシェルに伝えるさまざまなエスケープ文字とコードを含めることができます。PROMPT
PS1
print -rP -- $PROMPT
プロンプト文字列を直接使用または拡張できますprint -rP -- $PS1
。
PROMPT
ただし、拡張文字列に文字列を割り当てると、print -P
エスケープコードはプロンプト文字列のどの部分が表示され、プロンプト文字列のどの部分が色を変更する端末コードにのみ使用されるかをシェルに伝えます。シェルヒントのサイズを長期間追跡することはできません。これにより、説明する問題の種類が発生します。もう一つの一般的な問題は、長い命令の改行がめちゃくちゃになることです。
print -P
したがって、後で割り当てる文字列を生成するのではなく、「生」を出力するために使用してくださいPROMPT
。print -r
これは説明したのと同じ問題です。zshプロンプトが正しくエスケープされていません。しかし、わずかに異なる理由があります(印刷されない文字に関する情報を追加せずに、プロンプト文字列から印刷されない文字に関する有用な情報を削除します)。
少し恥ずかしいコード
num_chars=1
if [ ! $(dirs) = '~' ]; then
let "num_chars=$(basename "`pwd`" | wc -m) - 1"
fi
一行で作成可能
num_chars=$( print -n -P '%1~' | wc -m )
(%1~
は現在のディレクトリ名のプロンプトコードで、後で実際にプロンプトに文字列を含めるために使用します。)
ループもあります。
line="\n╭──"
for i in {1..$num_chars}; do
line+="─"
done
line+="──╯"
次のように書くことができます
printf -v line '\n╭──%*s──╯' $num_chars ''
line=${line// /─}
ただし、これを次のように組み合わせることができます。
print -v wd -n -P '%1~'
printf -v line '\n╭──%*s──╯' $#wd ''
line=${line// /─}
これは醜いコマンド置換を削除しwc
、 。