.zshrcでPROMPTを変更した後、Zshタブを完成させると、コマンドは右に数行移動します。

.zshrcでPROMPTを変更した後、Zshタブを完成させると、コマンドは右に数行移動します。

私は最近、素晴らしいプロンプトを印刷する関数を書いて、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または変数に割り当てられた文字列です。これには、文字列を目に見えるプロンプトに動的に拡張する方法をシェルに伝えるさまざまなエスケープ文字とコードを含めることができます。PROMPTPS1

print -rP -- $PROMPTプロンプト文字列を直接使用または拡張できますprint -rP -- $PS1

PROMPTただし、拡張文字列に文字列を割り当てると、print -Pエスケープコードはプロンプト文字列のどの部分が表示され、プロンプト文字列のどの部分が色を変更する端末コードにのみ使用されるかをシェルに伝えます。シェルヒントのサイズを長期間追跡することはできません。これにより、説明する問題の種類が発生します。もう一つの一般的な問題は、長い命令の改行がめちゃくちゃになることです。

print -Pしたがって、後で割り当てる文字列を生成するのではなく、「生」を出力するために使用してくださいPROMPTprint -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、 。

おすすめ記事