【2023年Mac(Appleシリコン)版】ターミナルを使いずらいと感じている君。fishを使って見ないかい？

# 前提
:::note warn
記事が2年以上古い場合、後述するインストール方法が変わっていたりと参考にならない場合があります。

この記事は**CPUがAppleシリコンのMac**であること前提に進めます。筆者はApple M2チップです。
Appleシリコンかどうかでインストール先が変わるので注意が必要です。
:::

筆者は標準搭載のターミナルではなくiTerm2を使っています。インストールは非常に簡単でGUI操作で完結するので興味のある人はどうぞ(https://iterm2.com/)

# fishは最高だぞ？
![スクリーンショット 2023-08-29 17.12.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195078/3a83e0cd-6df2-4476-f6f9-fedd569cb3d0.png)
まずは上記画像を見てほしい。イケてると思わないか？
ディレクトリは矢印のようなUIでスマートに表示され、テキストは色鮮やか、おまけにコマンドの候補を出してくれる。
この記事を参考にすれば君も最高のターミナルを手に入れることが出来るんだ。

fishとは何か、そもそもターミナルをカスタマイズする必要があるのかという興味深い話題に関しては後で話すとしてとにかく本題に入ろう。

# 0. Homebrewをインストール
fishはHomebrewを使ってインストールするため、まずはbrewをインストールする。
まさかMacを使っていてさらにQiitaを利用しているぐらい関心のあるエンジニアがHomebrewをインストールしていないとは思わないが念のためインストール用のコマンドを置いておこう。
```shell
xcode-select --install
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/${ユーザ名}/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"
```
:::note warn

`${ユーザ名}`の所は、それぞれの環境によって変わるため注意が必要だ。
:::

ここでつまずいても焦ることはない。brewは非常に利用者が多いため情報に困ることはない、検索するもよし、ChatGPTに聞くもよしで解決することができる。

またbrewを使わずともインストールできる方法はあるが、私はわざわざそちらを選ぶメリットを感じないため紹介はしない。
こだわりのある人は調べてみるといい。

# 1. fishをインストール
Homebrewが無事入ったらfishをインストールしていく
```shell
brew install fish
```
これだけだ。非常に簡単。

# 2. fishを使えるように設定
ここからは、こういった設定に慣れていない人は少し難しい。

まずはvimで`/etc/shells`を開き、`/opt/homebrew/bin/fish`を追記。

:::note info
vimに慣れていない人向けに簡単に補足をすると`i`を押してインサートモードに入るとキーボードで入力出来るようになるので十字キー駆使して追記できたら、`esc`を押し`:wq`と入力して`Enter`を押し保存する
:::

これでfishがshellとして認識されて使える様になる。
``` vim:/etc/shells
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.

/bin/bash
/bin/csh
/bin/dash
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
/opt/homebrew/bin/fish # 追記
```

次に`chsh`コマンドを使ってログインシェルをfishに変更する。
ログインシェルに設定することで、デフォルトのシェルをfishにすることが出来る。
```shell
chsh -s /opt/homebrew/bin/fish
```

次にhomebrewにパスを再度通していく、先ほどのインストール際にデフォルト`zsh`にはパスを通していたが`fish`ではまだパスを通していないので設定する必要がある。
パスの追加は今後も必要になるので是非覚えておいてほしい。

まずは先ほど同様vimで`config.fish`を開く
```shell
vi ~/.config/fish/config.fish
```
開けたら`set PATH /opt/homebrew/bin $PATH`を追記する。
```shell:
if status is-interactive
    # Commands to run in interactive sessions can go here
end
set PATH /opt/homebrew/bin $PATH <- 追記
```
これでシェル起動時に`config.fish`が読み込まれてパスが通るのでbrewコマンドが使える様になる。
一度ターミナルを閉じて再起動してみよう。画面が変わっているのがわかるはずだ

# 3. fisherをインストール
fishが無事にインストールできたら次は`fisher`をインストールしていく。
こいつはfishをより便利にするためのプラグインをインストールしたり管理するのに便利な奴だ。

以下のコマンドで簡単にインストールできる。
```shell
curl -Lo ~/.config/fish/functions/fisher.fish --create-dirs git.io/fisher
```
インストールが完了したら以下のコマンドで無事にインストールできたか確認しよう
```shell
fisher -v
```
:::note info
`fisher, version 4.4.3`のように表示されれば無事インストールは完了だ。
:::

# 4. Oh My Fishをインストールしテーマを設定
`Oh My Fish`はイケてる外観のターミナルにするために欠かせない存在だ。
`OMF`や`oh-my-fish`など書き方や呼び方も色々ある。

以下のコマンドでインストールをする。
```shell
curl -L https://get.oh-my.fish | fish
```
インストールできたか確認するために以下のコマンドを実行してみよう
```shell
omf theme
```
以下のような内容が出力されれば正常だ。
ただし`Installed`の内容は少し違うだろうからそこは気にしなくて良い、似たような構成のテキストが出力されていることが重要だ。
```shell
Installed:
bobthefish	default

Available:
agnoster		lambda-zero
aight			lavender
anchor			lolfish
ays			mars
batman			mint
beloglazov		mish
bira			mokou
bobthefish		mtahmed
boxfish			nai
budspencer		neel
cbjohnson		nelsonjchen
chain			neolambda
clearance		numist
cmorrell		ocean
coffeeandcode		one
cor			pastfish
cyan			perryh
dangerous		pie
default			plain
```

## テーマを設定
インストールが確認できたらテーマをインストールしていこう。
OMFには先ほどのコマンドで出力された通り多様なテーマが存在する。しかしそれらがどんなテーマか名前のみで判断するのは難しいだろう。
安心してほしい[公式のテーマ一覧(GitHub)](https://github.com/oh-my-fish/oh-my-fish/blob/master/docs/Themes.md)でお気に入りのテーマを見つけよう。

以下のコマンドでテーマをインストールできる。
```shell
omf install テーマ名
```
私のイチ押しのテーマは**bobrhefish**だ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195078/ffbe2f5d-e16e-8f9b-20a2-a6652d539c42.png)
**bobthefish**が欲しければ以下のコマンドを実行するといい。
```shell
omf install bobthefish
```

テーマを**切り替えたいとき**は以下のコマンドで切り替えることができる
```shell
omf theme テーマ名
```

# 5. フォントを設定
ここまで無事に来れば、自分のターミナルの画面に違和感を覚えるかもしれない。
何か`□`のような文字が表示されていると、それは所謂文字化けで`omf`で入れたテーマで使っている文字に対応しているものがが現在ターミナルに設定されているフォントにないためそうなっている。

もし、文字化けを起こしていないのなら、優秀な過去の自分がターミナルのフォント設定を`Powerline系`などshell向きに制作されたフォントにしているかもしれない。
**素晴らしい！**

文字化けしている人も焦ることはない、今までの作業に比べたらフォント設定なんて朝飯前だ。

さて、まずはフォントをMacにインストールしよう。
もし、あなたにフォントのこだわりがなければ`JetBrains Mono`をお勧めする。
`JetBrains Mono`はプログラミング用に開発されたフォントだが、shellにも使えるし、主観だが`Powerline系`のフォントよりも綺麗で見やすい。

## JetBrains Monoをインストール
[JetBrains Mono公式サイト](https://www.jetbrains.com/ja-jp/lp/mono/)

https://www.jetbrains.com/ja-jp/lp/mono/

上記サイトに飛んで「フォントをダウンロード」をクリックしよう。
![スクリーンショット 2023-08-30 17.02.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195078/8c3a9c62-872e-e895-113f-dfc1e305e209.png)
ダウンロードが完了したら、ダウンロードフォルダに行き、zipファイルを解凍する。
解凍したら、下記画像を参考にして、フォントを全て選択し、FontBookで開く。
![スクリーンショット 2023-08-30 17.03.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195078/068c4808-2137-97a5-138a-e9db26877318.png)
FOntBookが開いたら下記の画像のようなUIが出るので、**フォントをインストール**をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195078/c680d383-9c12-793c-77db-ebd2051c02e6.png)
これを、「ttf」「variable」「webfonts」全てのフォルダ直下のフォントファイルに行う。

## ターミナルでフォントを設定
フォントの設定は非常に簡単だ。
なぜならアプリでGUIを操作するだけだからだ。

### iTerm2
**「Font」** の項目でフォント関連の設定をできる。好きなようにするといい。
私のお勧めは「JetBrains Mono」「Regular」「16px」の組み合わせだ。

余談だが **「Cursor」** の項目でカーソルの見た目を変更できる。もし他のアプリのテキストフィールドのように使い慣れたものにしたければ「Vertical bar」を設定するといい
![スクリーンショット 2023-08-30 17.22.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195078/0644e497-389e-827d-5c3a-bf13d2957760.png)

### 標準搭載のターミナル
`設定`を開き「フォント」の項目の「変更...」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195078/c0c8a52f-d895-cf56-9e8e-ee1151734726.png)
開かれた別ウィンドウでフォントを設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195078/73d668e8-7dda-ee22-c44b-3d13540f6cda.png)
こちらでもカーソルの外観を変更することが出来る。

### 反映されたか確認
設定画面を閉じてターミナルを見てみよう無事に`□`が無くなりイケてる外観になれば成功だ。
もし、文字化けが治っていなかったら以下を試してみよう。
- ターミナルを再起動
- 自分の設定したフォントが対応しているフォントか

#### おめでとう！ここまで完了すれば必要な作業はすべて完了だ！快適なターミナルライフをLet`s エンジョイ:thumbsup:

# ex. テキストや背景の色を調整する
あなたがもしデザインに興味やこだわりを持つ人であれば、自分好みにカラーパレットをカスタマイズしたいと思うかもしれない。
大丈夫。できますよ。

iTerm2なら赤枠で囲んだ場所で設定を行うことができる。
初めはどこがどの設定かわからないかもしれないが、カラーパレットの編集は破壊的な影響を及ばさないので色々試してみるといいだろう。
![スクリーンショット 2023-08-30 17.43.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195078/55bde743-4012-67b9-2f30-45d34dd571b1.png)
また、右下の「Color Presets...」から
- 保存しているカラーパレットを設定
- 今の設定のカラーパレットをファイルにExportする
- ExportされたファイルをInportして、誰かの作ったカラーパレットを追加
したりすることができます。

ここまでこの記事を読んでくれたお礼として私のイチ押しのカラーパレットをプレゼントしましょう！
```xml:material-color.itermcolors
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Ansi 0 Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>0.12549020349979401</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.12549020349979401</real>
		<key>Red Component</key>
		<real>0.12549020349979401</real>
	</dict>
	<key>Ansi 1 Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>0.21176470816135406</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.26274511218070984</real>
		<key>Red Component</key>
		<real>0.95686274766921997</real>
	</dict>
	<key>Ansi 10 Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>0.29019609093666077</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.76470589637756348</real>
		<key>Red Component</key>
		<real>0.54509806632995605</real>
	</dict>
	<key>Ansi 11 Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>0.46274510025978088</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.94509804248809814</real>
		<key>Red Component</key>
		<real>1</real>
	</dict>
	<key>Ansi 12 Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>0.96470588445663452</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.70980393886566162</real>
		<key>Red Component</key>
		<real>0.39215686917304993</real>
	</dict>
	<key>Ansi 13 Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>0.84705883264541626</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.57647061347961426</real>
		<key>Red Component</key>
		<real>0.80784314870834351</real>
	</dict>
	<key>Ansi 14 Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>0.88235294818878174</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.81568628549575806</real>
		<key>Red Component</key>
		<real>0.30196079611778259</real>
	</dict>
	<key>Ansi 15 Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>0.99999994039535522</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.99999994039535522</real>
		<key>Red Component</key>
		<real>1</real>
	</dict>
	<key>Ansi 2 Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>0.31372550129890442</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.68627452850341797</real>
		<key>Red Component</key>
		<real>0.29803922772407532</real>
	</dict>
	<key>Ansi 3 Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>0.23137255012989044</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.92156863212585449</real>
		<key>Red Component</key>
		<real>1</real>
	</dict>
	<key>Ansi 4 Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>0.9529411792755127</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.58823531866073608</real>
		<key>Red Component</key>
		<real>0.12941177189350128</real>
	</dict>
	<key>Ansi 5 Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>0.78431373834609985</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.40784314274787903</real>
		<key>Red Component</key>
		<real>0.729411780834198</real>
	</dict>
	<key>Ansi 6 Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>0.83137255907058716</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.73725491762161255</real>
		<key>Red Component</key>
		<real>0.0</real>
	</dict>
	<key>Ansi 7 Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>0.78104287385940552</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.78104287385940552</real>
		<key>Red Component</key>
		<real>0.78104299306869507</real>
	</dict>
	<key>Ansi 8 Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>0.7764706015586853</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.7764706015586853</real>
		<key>Red Component</key>
		<real>0.7764706015586853</real>
	</dict>
	<key>Ansi 9 Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>0.45098039507865906</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.45098039507865906</real>
		<key>Red Component</key>
		<real>0.89803922176361084</real>
	</dict>
	<key>Background Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>0.12549020349979401</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.12549020349979401</real>
		<key>Red Component</key>
		<real>0.12549020349979401</real>
	</dict>
	<key>Badge Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>0.5</real>
		<key>Blue Component</key>
		<real>0.0</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.1491314172744751</real>
		<key>Red Component</key>
		<real>1</real>
	</dict>
	<key>Bold Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>0.99999994039535522</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.99999994039535522</real>
		<key>Red Component</key>
		<real>1</real>
	</dict>
	<key>Cursor Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>0.054901961237192154</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>1</real>
		<key>Red Component</key>
		<real>0.08235294371843338</real>
	</dict>
	<key>Cursor Guide Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>0.25</real>
		<key>Blue Component</key>
		<real>1</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.9268307089805603</real>
		<key>Red Component</key>
		<real>0.70213186740875244</real>
	</dict>
	<key>Cursor Text Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>1</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>1</real>
		<key>Red Component</key>
		<real>1</real>
	</dict>
	<key>Foreground Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>1</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>1</real>
		<key>Red Component</key>
		<real>1</real>
	</dict>
	<key>Link Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>0.38823530077934265</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.11764705926179886</real>
		<key>Red Component</key>
		<real>0.91372549533843994</real>
	</dict>
	<key>Selected Text Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>0.0</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.0</real>
		<key>Red Component</key>
		<real>0.0</real>
	</dict>
	<key>Selection Color</key>
	<dict>
		<key>Alpha Component</key>
		<real>1</real>
		<key>Blue Component</key>
		<real>0.64959716796875</real>
		<key>Color Space</key>
		<string>sRGB</string>
		<key>Green Component</key>
		<real>0.64959716796875</real>
		<key>Red Component</key>
		<real>0.64959716796875</real>
	</dict>
</dict>
</plist>
```
`material-color.itermcolors`という名前のファイルを作り、上記内容をコピペしてiTerm2でimportすればOKだ！

# 最後に
今回は私の好きな`fish`を紹介した。
初めに述べたとおり`fish`には
- インストール/設定が比較的容易
- プラグインを入れずとも自動補完やコマンドの候補を出してくれる
- おしゃれ

などの**強み**がある、だから私は初めてshellをカスタマイズする人には`fish`をお勧めする。
だが、`bash`や`zsh`でもカスタマイズすれば`fish`と同じようにいけてる外観や便利な機能を搭載させることができる。
shell自体のカスタマイズだけでなくコマンドの入力をサポートしてくれるツールも沢山ある(`Homebrew`とかでインストールする奴)

要は好きなものを使えという事だ！身近にいる先輩や憧れているエンジニアが使っていたからで初めてみるのでも良いだろう。

たくさん試行錯誤しながらそれぞれの **My Favorite ターミナル:star:** を見つけてみてくれ！