【🔰初心者向け】シェルのプロンプトを理解して、美しくしよう🐚

## はじめに
こんにちは！ITスクールRareTECHにてCS（Customer Support）を担当している池村です。今回の記事は、シェルのプロンプトを整えて見やすくしようという記事になります。

前回の記事は以下のリンクです。前回の記事を読んでからこの記事を読んでいただけますと幸いです。今回のカラースキームはSolarized Darkを選択しています。

https://qiita.com/ikemura-ren/items/bc0d2ca90aedd9af8b4f

## プロンプトについて知ろう！
シェルには設定ファイルというものがあり、Mac標準ならzsh（ズィーシェル）で.zshrcファイル、Linuxなどで標準のBash(バッシュ)では.bashrcファイルを編集することで、**見た目の変化や操作性が向上する設定を書くこと**ができます。今回はzshの設定を変更していきます。

前回の記事に引き続き、現在の.zshrcの内容は以下になります。
```Bash:.zshrc
autoload -Uz promptinit && promptinit
PROMPT='%F{cyan}%n@%m %F{blue}%~ %F{yellow}$ %f'

# ここだけ前記事から変更しています
export LSCOLORS="exfxcxdxbxegedabagacad"

alias ls='eza --color=auto'
```

#### autoload -Uz promptinit
まず1行目の前半を解説します。
まず前提として、プロンプトの説明が必要なので解説します。

##### プロンプトとは？
プロンプトは、`$`や`>`などの入力待ちの記号のことです。
画像の部分の表記ですね。こちらの見た目を変えられるのですが、この表示部分をプロンプトと呼びます。**コマンド入力を受け付ける部分**のことですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798971/46a9edae-08ff-df31-3ca6-98b2d2a2203a.png)

##### promptを使ってみる
自分で設定するまでもなく、zshには組み込まれたプロンプトがあります。

```Bash:もともとあるプロンプト一覧を見る
functions -u
```

```Bash:表示結果
add-zle-hook-widget () {
	# undefined
	builtin autoload -XUz
}
prompt_adam1_setup () {
	# undefined
	builtin autoload -XUz
}
prompt_adam2_setup () {
	# undefined
	builtin autoload -XUz
}
prompt_bart_setup () {
	# undefined
	builtin autoload -XUz
}
prompt_bigfade_setup () {
	# undefined
	builtin autoload -XUz
}
prompt_clint_setup () {
	# undefined
	builtin autoload -XUz
}
prompt_default_setup () {
	# undefined
	builtin autoload -XUz
}
prompt_elite2_setup () {
	# undefined
	builtin autoload -XUz
}
prompt_elite_setup () {
	# undefined
	builtin autoload -XUz
}
prompt_fade_setup () {
	# undefined
	builtin autoload -XUz
}
prompt_fire_setup () {
	# undefined
	builtin autoload -XUz
}
prompt_off_setup () {
	# undefined
	builtin autoload -XUz
}
prompt_oliver_setup () {
	# undefined
	builtin autoload -XUz
}
prompt_pws_setup () {
	# undefined
	builtin autoload -XUz
}
prompt_redhat_setup () {
	# undefined
	builtin autoload -XUz
}
prompt_restore_setup () {
	# undefined
	builtin autoload -XUz
}
prompt_suse_setup () {
	# undefined
	builtin autoload -XUz
}
prompt_walters_setup () {
	# undefined
	builtin autoload -XUz
}
prompt_zefram_setup () {
	# undefined
	builtin autoload -XUz
}
```

:::note info
この表示結果こそ、最初から入っているプロンプトテーマです。
:::

ではいくつか見た目を確認してみましょう。

```Bash:組み込まれているプロンプトを使ってみる①
prompt adam1
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798971/f4107b9a-644f-1548-9ef4-b1e5c90c186e.png)

おっと、見にくくなってしまいましたね。adam1はSolarizedと合っていない気がします。次はadam2を使ってみます。

```Bash:組み込まれているプロンプトを使ってみる②
prompt adam2
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798971/bfd8f5a3-f278-461f-b64e-309801b6ba43.png)

うーん、これもいまいち。その後も色々見てみた結果。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798971/7c879eab-e468-cb5d-0d1a-ec66da9fb551.png)

fireは好きな人は好きかな？となるくらいでしょうか。

```Bash:元に戻す
source .zshrc
```

では、`autoload`と`promptinit`とは何か？に話を戻します。
`autoload`はzshの組み込みコマンドで、指定した関数を必要なときに自動で読み込む機能を持っています。そして`promptinit`プロンプト（PROMPT）の設定を管理するための関数です。

:::note info
なので、この記述は`promptinit`と呼ばれる関数を自動で読み込んで有効化している記述です。
:::

オプションについて簡単に説明すると、`-U` は関数を安全に読み込み、`-z` はzsh だけで正しく動くようにする記述になります。

#### &&promptinit
これは&&の前のコマンドが成功したら次のコマンドを実行する記述です。
有効化した`promptinit`を実行して、設定をシェルに適用しているということになります。

#### PROMPT='%F{cyan}%n@%m %F{blue}%~ %F{yellow}$ %f'
こちらはその`promptinit`の設定を書いた部分です。プロンプトをどう見せるかですね。

```Bash:中身がどうなっているか
%F{cyan}%n@%m %F{blue}%~ %F{yellow}$ %f
```

まず`%F`ですが、**zshのプロンプトで色を変更するためのフォーマット指定子**です。（変更しますよという宣言のようなもの）

`%F{cyan}`はシアン色を指定→**指定するのは`%n`で、これはユーザー名に当たります**。

:::note info
`%F{cyan}%n`はプロンプトに表示するユーザー名をシアン色で表示
:::

@は区切り文字として使っています。別に@である必要はありませんが、よく使われるので使っています。

**`%m`はホスト名（コンピュータ名）を指しています**。色は変わらずシアン色です。

次の`%F{blue}`はもうわかると思います。**次の`%~`は現在のディレクトリを指していて**、ディレクトリの移動で表示されるようになるものです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798971/c2b8b81e-23e5-ed2a-a034-b02ada6f74d5.png)

次の`%F{yellow}$`は黄色の設定で$マークを表示しているものです。こういったシェル上で、ここからコマンドを打ってね！という合図記号のようなものです。

最後の`%f`はこれらの色を**リセットする役割**があります。これがないと、例えば`ls`コマンドを実行した結果も黄色になってしまいます。

以下が今回のプロンプトの内訳になります。

| 記号         | 説明                                      |
|-------------|-----------------------------------------|
| `%F{cyan}`  | シアン色を適用                          |
| `%n`        | ユーザー名                              |
| `@`         | 区切り（"@" を表示）                     |
| `%m`        | ホスト名（コンピュータ名）               |
| `%F{blue}`  | 青色を適用                              |
| `%~`        | 現在のディレクトリ（`/home/user` → `~` に短縮） |
| `%F{yellow}`| 黄色を適用                              |
| `$`         | プロンプトの `$` 記号                    |
| `%f`        | 色をリセット（デフォルトに戻す）         |

## プロンプトをもっと見やすくする！
以下のようなプロンプトにすることも可能です
```Bash:.zshrc
# プロンプトの色付けにcolors関数を利用
autoload -U colors; colors

PROMPT="%F{cyan}[%m:%~]%f
> "
```

### autoload -U colors; colors
こちらですが、`colors`というzshの組み込み関数を有効化して使っています。先ほどの`autoload -Uz promptinit && promptinit`は正直言って意味はなく、色々な組み込みプロンプトを使ってみようと思って書いていただけでした。
このcolors関数を使うと、先ほどの記述よりも色指定が細かくできるようになります。

### PROMPTの中身について
```Bash:PROMPTの中身
PROMPT="%{$fg[cyan]%}[%m] %{$fg[blue]%}%~ %{$reset_color%}
> "
```
ここは好みにもよるのですが、私は1行目に今いるディレクトリやホスト名を表示しています。ホスト名はいらない人もいると思うので消してもらって大丈夫です。

上記の設定にした場合のプロンプトは以下になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798971/6294d530-ba0c-b6a0-5504-b9cfc9e23f8b.png)


:::note info
色も好みですが、私は緑系統が好きなのでシアン色で設定しています。
`source .zshrc`でうまく反映されていない時は、一度ターミナルを再起動してみてください。
:::

また、colors関数を使った書き方についても少し解説します。
```Bash:書き方
PROMPT="%{$fg[cyan]%}[%m] %{$fg[blue]%}%~ %{$reset_color%}
> "
```

まず、%{ ... %} で囲むことで、Zsh に「この部分は長さを考慮しなくていいよ」と伝えています。その中の$fg[...] や $bg[...]では色の指定ができ、文字色なら$fg、背景色なら$bgになります。

それ以外でもcolorsでは太字を使いたくない場合や、カラーマッピングも使えるので、細かな指定や編集をしたい場合は使って損はありません。

:::note warn
まあでも、記事の最初で使った記法の方が圧倒的にシンプルではあります。
:::

#### （余談）カラーマッピングについて
```Bash:カラーマッピングってどんなもの？
autoload -U colors; colors
typeset -A fg
fg[error]="red"
fg[success]="green"

PROMPT="%{$fg[success]%}Success!%{$reset_color%}"
```
$fg[success] を変更するだけで、全体の配色を一括変更できたりします。

#### （余談）太字を使いたくない場合
```Bash:boldってやつですね
PROMPT="%{$fg_no_bold[blue]%}No Bold Blue%{$reset_color%}"
```
太字を使いたくない場合に便利

:::note info
colors関数を使わないと、こういった特殊な変数は使えない。
:::

## Gitのブランチ名をプロンプトに入れる
エンジニアであればGitのブランチ情報を表示したいと思うので、その設定ファイルを書いておきます。ただ、初心者向けの記事なので、ここの詳細は省きます。

```Bash:Gitを表示させる方法
# Gitブランチ情報を右プロンプトに表示
autoload -Uz vcs_info
setopt prompt_subst
zstyle ':vcs_info:git:*' check-for-changes true
zstyle ':vcs_info:git:*' stagedstr "%F{green}!"
zstyle ':vcs_info:git:*' unstagedstr "%F{red}+"
zstyle ':vcs_info:*' formats "%F{cyan}%c%u[%b]%f"
zstyle ':vcs_info:*' actionformats "[%b|%a]"


precmd () {
    vcs_info 
    RPROMPT="%F{cyan}$vcs_info_msg_0_%f"  # 右側のプロンプト
}

# プロンプト設定
PROMPT="%F{cyan}[%m] %F{blue}%~%f
> "
PROMPT2="%F{cyan}%_> %f"  # セカンダリのプロンプト
SPROMPT="%F{yellow}%r is correct? [Yes, No, Abort, Edit]:%f"  # スペル訂正用プロンプト
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798971/262ef99c-5f04-1ee5-d3c2-15af1ae2dd6a.png)

:::note info
ディレクトリ情報とブランチ情報が逆でもいいかもしれませんね。（自分はこれに慣れちゃっていますが）
:::

| 設定          | 変更後                      | 説明 |
|--------------|----------------------------|------|
| `stagedstr`  | `%F{green}●`               | コミットされる予定のファイルの表示 (●, 緑) |
| `unstagedstr`| `%F{red}✗`                 | 変更済みだが未コミットのファイルの表示 (✗, 赤) |
| `formats`    | `%F{cyan}%c%u[%b]%f`       | ブランチ名はシアン色 |
| `actionformats` | `[%b%a]`| リベースなどのアクション |

## おわりに
この記事を書き終わって思ったのは、この記事マニアックな内容書いてるな〜ってことでした。でもやはり自分でこだわった設定には愛着沸いちゃいますね。次の記事では.zshrcの設定で見た目以外でもいじっていこうと思います。

![cc6955b8-a525-4a5d-b52e-f281986bca90_720.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798971/3d215332-76a5-f9d6-d964-7516007de9c2.png)


## 余談
シェルはやはりたまらん🤤