34

カスタム bash プロンプトを使用して git ブランチを表示しています。

すべてが入ってい/etc/bash/bashrcます:

function formattedGitBranch {
    _branch="$(git branch 2>/dev/null | sed -e "/^\s/d" -e "s/^\*\s//")"
    # tried these:
    echo -e "\e[0;91m ($_branch)"                       
    echo -e "\e[0;91m ($_branch) \e[m"                  
    echo -e $'\e[0;91m'"($_branch)"
    echo "($_branch)"                                   
    echo "$(tput setaf 2) ($_branch) $(tput setaf 9)"
    printf "\e[0;91m ($_branch)"
}

# color is set before function call
PS1='\[\033[01;34m\] \[\033[0;91m\]$(formattedGitBranch) \$\[\033[00m\] '
# color is set inside function
PS1='\[\033[01;34m\] $(formattedGitBranch) \$\[\033[00m\] '

問題は、関数で色を設定$_branchすると、EOL に達したときにプロンプ​​トが上書きされることです。

mmmmmmmmmmmmp/rainyday.js (マスター) $ mmmmmmmm

可能なすべてのバリアントtputprintf$''表記法を試しました。

でのみ色を設定することで問題を解決しましたPS1

ad@gentoo /tmp/rainyday.js (マスター) $ mmmmmm

しかし..

  1. プロンプトが上書きされる理由を知りたい
  2. 関数が使用されている場合にこの問題を修正する方法

Gentoo Linux を使用しています。GNU bash, verze 4.2.37(1)-release (i686-pc-linux-gnu)

4

3 に答える 3

55

1) プロンプトが上書きされる理由を知りたい

すべての印刷不可能な文字はエスケープする必要が\[あり、\]そうしないとreadlineはカーソル位置を正しく追跡できないためです。

プロンプトには、非表示のエスケープ シーケンスを配置する必要が\[あります。 bash がないと、カラー コードのエスケープ シーケンスを構成するバイトが実際に画面上のスペースを占めると考えられるため、bash はカーソルが実際にどこにあるかを知ることができません。\]
\[ \]

\[ 非印刷文字のシーケンスを開始します。(色のエスケープ シーケンスのような)。これにより、bash はワード ラッピングを正しく計算できます。

\] 非印刷文字のシーケンスを終了します。-- BashFAQ

...印刷されない文字のエスケープに注意してください。これにより、readline がカーソル位置を正しく追跡できるようになります。--ss64.com _

2) をfunction使用した場合のこの問題の解決方法

function出力が で使用される内に色を設定するPS場合は、2 つのオプションがあります。

  • 関数呼び出し全体をエスケープします。

    PS1='\[ $(formattedGitBranch) \] '

  • または、 内の印刷されないエスケープシーケンスを置き換えechoます。つまり、次のように置き換えます。

    \[そして\]_\001 \002

    (ユーザーのおかげで!)

  • echo -e はbashを認識していないため、これらを& ASCII 制御コード\[ \]に置き換えて、印刷できない文字を印刷可能な文字から区切る 必要があります。\001\002

    function formattedGitBranch { echo -e "\001\e[0;91m\002 ($_branch)"; } PS1='$(formattedGitBranch) '

于 2013-10-21T18:01:03.240 に答える
14

のような文字\e[0;91m列は、bash がその長さを計算できないようにするために、追加の引用符が必要です。

formattedGitBranchこれらの文字列をin \[& \]as で囲みます。\[\e[0;91m\]

あなたは他の場所でそれを正しく行いました。フォーマットされたGitBranchでそれを逃しただけです。

于 2013-09-30T11:01:42.913 に答える