Quantcast
Channel: Bashタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 2722

bashプロンプトの表示をNerdfontsで格好良くする

$
0
0

無限人がやってるPowerLineのあのパンくずリスト型の表示が格好いいアレです。

最近は色々なshがあるしプラグイン的な形でサクッと導入できる中、わざわざbashでひいこらやる必要も無いと思うけど、他のshを導入するのは面倒くさいし、それはともかく自分用にカスタマイズしたいなと思ったので頑張りました。

作ってる途中で色々知見を得たので、備忘録的な。

格好いい画像

2020-09-07.png
2020-09-07 (1).png

筆者環境

WindowsTerminal (fontには@tawara_氏のHackGenNerd35 Consoleを利用)
WSL2 (Ubuntu 18.04.5)
bash 4.4.20
これと完全一致じゃなくても別にどうにかなるとは思います

とにかくソースコード

nerdps1.sh
#!/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
.bashrc
# ...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を埋め込む前にとりあえずテストして確認しましょう。(先達の知恵)

最後に

パンくず(そういう言い方で良いのか?)再現の記事は多いけど、このスクリプトでは割と楽に好きな色のパンくずを追加できるので、色々各々の状況に応じた形にカスタムしやすいと思います。作ってる内に互換性への意識がおざなりになっちゃったけど……

参考


Viewing all articles
Browse latest Browse all 2722

Trending Articles