かわいいプロンプト

# プロンプトがかわいくない
今使っている bash-git-prompt。大変シュッとしてていいんだけど可愛くない。

![シュッとしてる](https://qiita-image-store.s3.amazonaws.com/0/14380/067b0b1a-8d89-677c-b61a-13ff0d78f84c.png)


今までちゃんとプロンプトと向き合ってなかったので、作ってみることにしました。

# こんな機能がほしい
* 時刻
* 現在のディレクトリ
* ブランチ
* 作業スペースの状態

# 作ってみた

https://github.com/ken1flan/cawaii_prompt/blob/master/cawaii_prompt.sh

```bash
# cawaii_prompt.sh
CAWAII_PROMPT_DIR_COLOR='\033[0;33m'
CAWAII_PROMPT_BRANCH_COLOR='\033[0;35m'
CAWAII_PROMPT_STATUS_OK_COLOR='\033[0;32m'
CAWAII_PROMPT_STATUS_WARN_COLOR='\033[1;33m'
CAWAII_PROMPT_STATUS_NG_COLOR='\033[0;31m'
CAWAII_PROMPT_STATUS_BUG_COLOR='\033[1;36m'
CAWAII_PROMPT_TURN_OFF_COLOR='\033[0m'

CAWAII_PROMPT_STATUS_OK="${CAWAII_PROMPT_STATUS_OK_COLOR}(≧∇≦)b OK${CAWAII_PROMPT_TURN_OFF_COLOR}"
CAWAII_PROMPT_STATUS_WARN="${CAWAII_PROMPT_STATUS_WARN_COLOR}（;´▽｀A${CAWAII_PROMPT_TURN_OFF_COLOR}"
CAWAII_PROMPT_STATUS_NG="${CAWAII_PROMPT_STATUS_NG_COLOR}く(\"\"0\"\")＞なんてこった!!${CAWAII_PROMPT_TURN_OFF_COLOR}"
CAWAII_PROMPT_STATUS_BUG="${CAWAII_PROMPT_STATUS_BUG_COLOR}m(_ _)m promptのバグです${CAWAII_PROMPT_TURN_OFF_COLOR}"

function cawaii_prompt_preprocess () {
  if [ -z $(git rev-parse --git-dir 2> /dev/null) ]; then
    if [ -n "$CAWAII_PROMPT_OLD_PS1" ]; then
      export PS1=$CAWAII_PROMPT_OLD_PS1
    fi
  else
    if [ -z "$CAWAII_PROMPT_OLD_PS1" ]; then
      export CAWAII_PROMPT_OLD_PS1=$PS1
    fi
    export PS1="${CAWAII_PROMPT_DIR_COLOR}\w${CAWAII_PROMPT_TURN_OFF_COLOR}[${CAWAII_PROMPT_BRANCH_COLOR}$(git rev-parse --abbrev-ref HEAD)${CAWAII_PROMPT_TURN_OFF_COLOR}$(git_status_string)]\n\D{%H:%M} $ "
  fi
}

function git_status_string () {
  local statuses=$(git status -s 2> /dev/null | sed 's/^ *//' | cut -d ' ' -f 1 | sort | uniq)
  if [ -z "$statuses" ]; then echo $CAWAII_PROMPT_STATUS_OK; return; fi
  if [ -z "${statuses/*U*/}" ]; then echo $CAWAII_PROMPT_STATUS_NG; return; fi
  if [ -z "${statuses/*[MA?]*/}" ]; then echo $CAWAII_PROMPT_STATUS_WARN; return; fi
  echo $CAWAII_PROMPT_STATUS_BUG
}

PROMPT_COMMAND="cawaii_prompt_preprocess"
```

## PS1
プロンプトを設定する環境変数です。

https://github.com/ken1flan/cawaii_prompt/blob/master/cawaii_prompt.sh#L24

```bash
PS1="${CAWAII_PROMPT_DIR_COLOR}\w${CAWAII_PROMPT_TURN_OFF_COLOR}[${CAWAII_PROMPT_BRANCH_COLOR}$(git rev-parse --abbrev-ref HEAD)${CAWAII_PROMPT_TURN_OFF_COLOR}$(git_status_string)]\n\D{%H:%M} $ "
```

↓の要素を、色設定`CAWAII_PROMPT_*_COLOR`と`CAWAII_PROMPT_TURN_OFF_COLOR`で囲んで色をつけています。

* `\w` … 現在ディレクトリの表示
* `\D{%H:%M}` … 時刻表示
* `$(git rev-parse --abbrev-ref HEAD)` … gitのブランチ名
* `$(git_status_string)` … gitの作業ディレクトリの状態

## git_status_string

https://github.com/ken1flan/cawaii_prompt/blob/master/cawaii_prompt.sh#L28-L34

```bash
function git_status_string () {
  local statuses=$(git status -s 2> /dev/null | sed 's/^ *//' | cut -d ' ' -f 1 | sort | uniq)
  if [ -z "$statuses" ]; then echo $CAWAII_PROMPT_STATUS_OK; return; fi
  if [ -z "${statuses/*U*/}" ]; then echo $CAWAII_PROMPT_STATUS_NG; return; fi
  if [ -z "${statuses/*[MA?]*/}" ]; then echo $CAWAII_PROMPT_STATUS_WARN; return; fi
  echo $CAWAII_PROMPT_STATUS_BUG
}
```

`git status`の短い表示をステータス文字列だけ取るようにして、ヤバそうな順に検査をしてます。
ここでは下のように分類しています。
* なにもなかったら … OK
* コンフリクトがあったら … NG
* 追加/変更/不明なファイルがあったら … Warning

## PROMPT_COMMAND
プロンプトを表示する前に実行するコマンドを設定する環境変数です。

https://github.com/ken1flan/cawaii_prompt/blob/master/cawaii_prompt.sh#L15-L26

```bash
function cawaii_prompt_preprocess () {
  if [ -z $(git rev-parse --git-dir 2> /dev/null) ]; then
    if [ -n "$CAWAII_PROMPT_OLD_PS1" ]; then
      export PS1=$CAWAII_PROMPT_OLD_PS1
    fi
  else
    if [ -z "$CAWAII_PROMPT_OLD_PS1" ]; then
      export CAWAII_PROMPT_OLD_PS1=$PS1
    fi
    PS1="${CAWAII_PROMPT_DIR_COLOR}\w${CAWAII_PROMPT_TURN_OFF_COLOR}[${CAWAII_PROMPT_BRANCH_COLOR}$(git rev-parse --abbrev-ref HEAD)${CAWAII_PROMPT_TURN_OFF_COLOR}$(git_status_string)]\n\D{%H:%M} $ "
  fi
}
```

今いるディレクトリがgitの管理しているところだったら新しいプロンプトを設定し、
そうでなかったら以前のものに戻すようにしています。

## こんな感じ
![prompt.png](https://qiita-image-store.s3.amazonaws.com/0/14380/72a839c1-0f9c-7e9d-dfd1-49199b94cb89.png)

![こんな感じ](https://qiita-image-store.s3.amazonaws.com/0/14380/f73e54b6-6e07-3113-88f6-3f8916aae101.png)

# まとめ
`PS1`は知ってたけど、`PROMPT_COMMAND`は知らなかった。
これがあれば、いろんなプロンプトを設定できそう。
プロンプトにサーバの負荷を表示するとか…。

# 参考
* [bash-git-prompt](https://github.com/magicmonty/bash-git-prompt)
* [bashマニュアル](https://linuxjm.osdn.jp/html/GNU_bash/man1/bash.1.html)