無限人がやってるPowerLineのあのパンくずリスト型の表示が格好いいアレです。
最近は色々なshがあるしプラグイン的な形でサクッと導入できる中、わざわざbashでひいこらやる必要も無いと思うけど、他のshを導入するのは面倒くさいし、それはともかく自分用にカスタマイズしたいなと思ったので頑張りました。
作ってる途中で色々知見を得たので、備忘録的な。
格好いい画像
筆者環境
WindowsTerminal (fontには@tawara_氏のHackGenNerd35 Consoleを利用)
WSL2 (Ubuntu 18.04.5)
bash 4.4.20
これと完全一致じゃなくても別にどうにかなるとは思います
とにかくソースコード
#!/bin/bashset-euC# bash option# 色分け用のエスケープ文字ESC=$(printf'\033')declare-lDSPCOLOR="none"# 次の項目を作る関数
C(){if["$DSPCOLOR"="none"];then
echo-n""else
echo-n" "fi# > background colorcase"$1"in"red")echo-e-n"${ESC}[41m";;"green")echo-e-n"${ESC}[42m";;"yellow")echo-e-n"${ESC}[43m";;"blue")echo-e-n"${ESC}[44m";;"purple")echo-e-n"${ESC}[45m";;"cyan")echo-e-n"${ESC}[46m";;"gray")echo-e-n"${ESC}[47m";;*)echo-e-n"${ESC}[49m";;esacif["$DSPCOLOR"="none"];then
echo-n" "fi# > colorlocal isUsed=true
case"$DSPCOLOR"in"red")echo-e-n"${ESC}[31m";;"green")echo-e-n"${ESC}[32m";;"yellow")echo-e-n"${ESC}[33m";;"blue")echo-e-n"${ESC}[34m";;"purple")echo-e-n"${ESC}[35m";;"cyan")echo-e-n"${ESC}[36m";;"gray")echo-e-n"${ESC}[37m";;*)isUsed=false;;esac# >if"${isUsed}";then
echo-n" "# \ue0b0 nf-pl-left_hard_divider パンくずの肝echo-e-n"${ESC}[30m"fi# 文字色case"$1"in"red")echo-e-n"${ESC}[37m";;"green")echo-e-n"${ESC}[37m";;"yellow")echo-e-n"${ESC}[30m";;"blue")echo-e-n"${ESC}[37m";;"purple")echo-e-n"${ESC}[37m";;"cyan")echo-e-n"${ESC}[30m";;"gray")echo-e-n"${ESC}[30m";;*)echo-e-n"${ESC}[0m";;esacDSPCOLOR="$1"}export VIRTUAL_ENV_DISABLE_PROMPT=1 # pythonのvenv仮想環境でPS1を書き換えさせない
nerdPS1(){local userName="$1"# if userName yourname, use short name# [TODO] Change YOUR-USER-NAMEif[[$userName=="YOUR-USER-NAME"]];then
userName="🥦"# terminalによってはカラーフォント絵文字も使える。自分っぽいものに置き換えようfi
local hostName="$2"# if hostName ..# [TODO] Change YOUR-HOST-NAMEif[[$hostName=="YOUR-HOST-NAME"]];then
hostName=""# \uf878 nf-mdi-monitor 一番ホストっぽかったfi
local pwdInfo="$3"# chroot# とりあえず書き足しておいたけどvenvと関係なかった。ここのは動作検証してないので……if[[-v debian_chroot ]];then
C "purple"echo-e-n"\uf306 $debian_chroot"# nf-linux-debian fi# (optional) python venvif[[-v VIRTUAL_ENV ]];then
local PYTHON_VER="$(python -V)"local PYTHON_ENVNAME="$(basename$VIRTUAL_ENV)"
C "cyan"# for remove uniquename (pipenv hoge-{uniquename})echo-e-n"\ue235 ${PYTHON_VER#Python }${PYTHON_ENVNAME%-*}"# nf-fae-python 一番見やすいPythonロゴfi# host
C "blue"echo-n"$userName@$hostName"# pwd
C "gray"echo-e-n"\ue5ff $pwdInfo"# nf-custom-folder フォルダアイコン# (optional) git# [TODO] `source git-prompt.sh` (you have to download or find)if git status --ignore-submodules&>/dev/null;then# You Use Gitlocal gitps1="$(__git_ps1)"if[[$gitps1=~ [*+?%] ]];then
C "yellow"else
C "green"fi
echo-e-n"\ue725 $gitps1"# nf-dev-git_branch 一番見やすかったGitぽいアイコンfi
C "reset"# 忘れずに}# 右端に時刻を表示# コピペ https://orebibou.com/ja/home/201810/20181002_001/
__command_rprompt(){local rprompt=$(date"+%Y/%m/%d %H:%M:%S")local num=$(($COLUMNS-${#rprompt}-2))printf"%${num}s$rprompt\\r"''}set +e # これが無いと、プロンプトで実行したコマンドにエラーが有った時に動かなくなるPS1='$(nerdPS1 \u \h \w)\n\$ 'PROMPT_COMMAND=__command_rprompt
# ...if[-e ~/nerdps1.sh ];then
source ~/nerdps1.sh
fi
source ~/.git-prompt.sh
GIT_PS1_SHOWDIRTYSTATE=true
GIT_PS1_SHOWUPSTREAM=true
GIT_PS1_SHOWUNTRACKEDFILES=true
GIT_PS1_SHOWSTASHSTATE=true
GIT_PS1_COMPRESSSPARSESTATE=true# 増えたGIT_PS1_STATESEPARATOR=' '# ...
説明
プロンプトの表示の変更
一般に見えているホスト名とか書いてある部分は環境変数PS1
で指定されています。この内容は1行実行ごとに解釈して都度都度実行されます。
後述のC
関数を1つのパンくずごとに実行させたかったのですが、これをそのままC
に埋め込むと思うように動かない(同時に処理される?)ので、今回その内容について全て関数に投げています。
Nerdfonts
powerline用のフォントを始めとする様々なアイコンフォントが含まれたフォントです。外字領域を利用しているいて、Nerdfontsと他の一般的なfontを合成することもできるため、様々な派生があります。
パンくずの仕組み
そもそもあのパンくずは、Nerdfontsに含まれるnf-pl-left_hard_divider
という文字を、文字色をそれ以前の背景色にすることで表現しています。
今回DSPCOLOR
という変数で以前の色を管理しC
という変数で、背景色の変更とnf-pl-left_hard_divider
の表示を行っています。
一元管理しているので、好きなようにパンくずを生やしたり消したりできます。
変数名の汚染は少し心配
色を変える仕組み
\e[{hoge}m
の形で入力する(制御文字を使うためecho
には-e
オプションが必要)することで、{hoge}
に応じた色変更が行えます。具体的な記入例は詳しい説明がいくらでも他の人の記事にあるので任せます。\e
と\033
は同じ意味ですが、後者のほうが互換性が良いみたいです
ユーザ名とホスト名のアイコン化
長ったるいのは嫌だけど非表示にするのも何かあった時アレだな、ということで、普段のものに一致していたら1字に書き換えるようにしておきます。
python venv実行中の表示
pythonにはバージョン管理を司るvenvという機能がありますが、デフォルトだと環境名をPS1
に埋め込みやがります。埋め込むかどうかは環境変数VIRTUAL_ENV_DISABLE_PROMPT
で指定できるし、仮想環境名はbasename $VIRTUALENV
で取得できます。
pipenvを使う時、環境作成時のユニークな値がこれの後ろに付いてきてしまうので、ハイフン以後を削除する設定しています。
git の表示
色々細々した項目について場合分けするのが大変そうですが、公式のgit-prompt.sh
というのがいい感じに処理してくれるので、これを見つけてきて読み込みましょう。ブランチ名と状況を出力してくれる関数__git_ps1
を含んでいます。
これの出力で変更の有る無しを判断しています。
他の記事ではあまり書いてませんでしたが、最近ではGIT_PS1_COMPRESSSPARSESTATE
についても設定する必要があるようです。
ただ、WSLにおいて、通常のWindowsのファイルにこれを実行しようとすると明らかに時間がかかるようになってしまいます。__git_ps1
の仕業です。いつか改善されることを期待して。
右端に時刻を表示
bashでPROMPT_COMMANDを利用して右プロンプトを出力させるという記事のものが今回文句なく動いてくれたのでこれをそのまま使用しました。
もうちょっと飾っても良いかもしれない。
やらかしたとき
これで遊んでると.bashrc
にバグを埋め込んで起動できなくなることが有るので、気をつけましょう。
WSLの場合は、cmdなりPowerShellなりからWSL内部のbashをrcを読みこまずに実行することができます。bash
wsl.exe -e bash --norc
.bashrcでsourceを埋め込む前にとりあえずテストして確認しましょう。(先達の知恵)
最後に
パンくず(そういう言い方で良いのか?)再現の記事は多いけど、このスクリプトでは割と楽に好きな色のパンくずを追加できるので、色々各々の状況に応じた形にカスタムしやすいと思います。作ってる内に互換性への意識がおざなりになっちゃったけど……
参考
- Git のための最強 Bashプロンプト!
__git_ps1
も自作したくなったら役立つかも - シェルスクリプトのechoで”問題なく”色をつける(bash他対応)色について詳しく
- Pythonのvenvのプロンプト表示をカスタマイズする venvの書き換えについて
- bashでPROMPT_COMMANDを利用して右プロンプトを出力させる右端の時刻表示について
- NERD FONTSチートシートが有るので好きなアイコンを探してみてください。
- Ricty を神フォントだと崇める僕が、フリーライセンスのプログラミングフォント「白源」を作った話 NerdFonts合成バージョンも配布中