プロンプトに表示するパスを簡略化する


/home/username/foo/barは長い

fishみたいに~/f/barでプロンプトに表示させたい

fishのソースを見る

prompt_pwdのソースだと

 string replace -ar '(\.?[^/]{'"$fish_prompt_pwd_dir_length"'})[^/]*/' '$1/' $tmp

となっている。

string replaceはfishの関数なのでbashでこれを再現する。

function abbr_pwd() {
    local p=$(echo $PWD | sed "s@$HOME@~@")
    local directories=(${p//\// })
    local _n_d=${#directories[@]}
    local _last=${directories[_n_d - 1]}
    local _abbr_pwd=""
    if [ ${directories[0]} != "~" ]; then
        _abbr_pwd=$_abbr_pwd/
    fi
    # 本当はif [[ $p =~ (.?[^\/]{1})[^\/]*\/ ]]で処理したい
    for d in "${directories[@]:0:_n_d-1}"; do
        _abbr_pwd=$_abbr_pwd${d:0:1}/
    done
    echo $_abbr_pwd$_last
}

fishのコードのように正規表現で処理をしたいが、if [[ $p =~ (.?[^\/]{1})[^\/]*\/ ]]; then; echo ${BASH_REMATCH[@]};fiでは最初のマッチ~のみしか得られなかった。(ちゃんと調べればやりようはありそう)

ディレクトリのパス/home/username/foo/bar~/foo/barにするためsedで置換をし、
"/"で文字列を分解、最後の以外の部分を先頭文字だけ残して"/"で結合、最後にbarを足すことで~/f/barを得た。

$HOMEより根のパスでは/usr/share/theme -> /u/s/themeのように/が先頭に来るようにした。

ただし、自ユーザ以外のホームディレクトリ下($HOMEで置換ができない)だと/h/o(otherUser)/f/barみたいに冗長になる。

PROMPTに表示する

PS1='[\u@\h] $(abbr_pwd $PWD) \$ '

みたいに適宜いじってください。