fish shellのはじめかた 2019冬

[PONOS Advent Calendar 2019](https://qiita.com/advent-calendar/2019/ponos)の1日目の記事です。:confetti_ball:

## ⛄はじめに

fish shellは「Friendly interactive shell」の略で、bashやzshの代替として使えるコマンドラインシェルです。他のシェルと比べてかな〜り後発なこともあって、初期状態でも十分高機能かつ使いやすく作られています。

この記事では、fish本体とパッケージマネージャ・カスタマイズ方法についてサラッと解説し、初fishの方がとりあえず使えるようになることを目指します。

### この記事の対象者

- デフォルトのシェルを使い続けていて、そろそろ変えてみたい人
- fish shellを使ったことがない人
- fish shellを試したことがあるけど、色々忘れちゃった人
- 魚が好きな人

## 🐟fish本体の導入

### fishをインストールする

[公式サイト](https://fishshell.com/)のトップページに、各OSごとのインストール方法が載っています。

![インストール方法.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2492/b7d243f5-4040-5608-1354-14e6c111515d.png)

### とりあえず使ってみる

適当なターミナルでおもむろに ``fish`` と打ってみましょう。

```
bash-3.2$ fish
Welcome to fish, the friendly interactive shell
honeniq@honeniq.local ~>
```

``exit``すれば元のシェルに戻れます。

### ログインシェルをfishにする

fishが気に入ってきたら、ログインシェルもfishに変更しましょう。

```
~> which fish
/usr/local/bin/fish
```

fishの実行ファイルがどこにいるのか調べて、

```
~> chsh -s /usr/local/bin/fish
```

``chsh``で変更します。



## 📦パッケージマネージャ

プログラミング言語のように、fishにもパッケージマネージャがあります。何種類かありますが、オススメは[Fisher](https://github.com/jorgebucaran/fisher)(旧名Fisherman)です。

``fishfile``という名前のファイルでパッケージを管理できるので、シェルの設定をgit管理している人にはとても便利です。

### Fisherをインストールする

Fisherの[README](https://github.com/jorgebucaran/fisher)に載っているワンライナーでインストールします。(インストールと言っても、ファイルを1つ置いているだけです。)

```
curl -sL https://git.io/fisher | source && fisher install jorgebucaran/fisher
```

ターミナルを再起動して、叩いてみます。

```
~> fisher -v
fisher version 3.2.10 ~/.config/fish/functions/fisher.fish
```

インストールできました。


### パッケージをインストールする

``fisher add [GitHubリポジトリ名]``でパッケージをインストールできます。(正確には、``fish_plugins``に追加→反映を一気にやっているみたいです。)

例えば[jethrokuan/z](https://github.com/jethrokuan/z)をインストールする場合は、以下のようになります。

```
~> fisher add jethrokuan/z
created new fishfile in ~/.config/fish/fishfile
fetching https://codeload.github.com/jethrokuan/z/tar.gz/master
linking ~/.config/fish/functions/__z.fish
linking ~/.config/fish/functions/__z_add.fish
linking ~/.config/fish/functions/__z_clean.fish
linking ~/.config/fish/functions/__z_complete.fish
linking ~/.config/fish/conf.d/z.fish
added 1 package in 2.70s
```

``fish_plugins``にも追加されます。

```
~> cat ~/.config/fish/fishfile
jethrokuan/z
```

#### 補足: fisherfileを直接編集

``fish_plugins``を直接編集して``fisher update``を実行することでも、パッケージのインストールができます。


## ⚙カスタマイズ

### fishの設定ファイル

fishの設定ファイルは``~/.config/fish/``に作られます。

- ~/.config/fish/
  - completions/
  - conf.d/
  - functions/
  - config.fish

``config.fish``が、bashで言う.bashrcにあたります。カラースキームを何にするかみたいな個人用設定はここに書いていく感じですね。

このファイル、読み込まれる順番が結構後のほうなので、ちょっと工夫が必要だったりします。以下、昔書いた記事からの引用。

> 1. fish組み込みの設定ファイル (編集するべきじゃないファイル)
> 2. システム全体向け設定 /etc/fish/config.fishなど
> 3. 個人向けスニペット ~/.config/fish/conf.d/
> 4. 個人向け設定 ~/.config/fish/config.fish
> [fish shellでrbenvを使う](https://qiita.com/honeniq/items/6b1362dd32b458ef441e#fish%E3%81%AE%E6%8C%99%E5%8B%95)

パッケージによっては``conf.d``配下にインストールされる場合がありますが、このフォルダは``config.fish``よりも先に読み込まれます。特定の環境変数を必要とするパッケージがある場合、読み込み順の関係で``config.fish``に書いていても間に合いません。

対処法として、``conf.d/000-env.fish``みたいなファイルを作って環境変数はそこに書く、というのが定番になっています。(名前は何でもいいですが、他のファイルよりも早く読み込まれるようにすること。)

### カラースキーム設定

''fish_config''コマンドで、ブラウザ上でカラースキームの確認・設定ができます。便利。

![fish_config.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2492/5e2e01f5-eacc-7da4-1f78-6e6b5cd67395.png)


### プロンプト変更

自分でスクリプトを書いて変更したり、他の人が作ったパッケージを利用することができます。

![prompt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2492/a47ba04d-5d3d-18f8-bc9a-812a6a3229a7.png)

[Oh My Fish](https://github.com/oh-my-fish/oh-my-fish)というfishのフレームワークがあるんですが、プロンプト類(テーマ)は接頭辞「theme-」を付けて[まとめられています](https://github.com/oh-my-fish?utf8=%E2%9C%93&q=theme-&type=&language=)。

シンプルなものからPowerLineを使ったゴリゴリカスタマイズ派まで色々ありますが、[oh-my-fish/theme-bobthefish](https://github.com/oh-my-fish/theme-bobthefish)あたりがカスタマイズ性も高くて良いと思います。

#### プロンプトの注意点

fishには``fish_right_prompt``という、ターミナルの画面右端を起点としてプロンプトを表示する機能があります。コマンドの実行時間とかエラー番号を表示することが多い機能です。

これが日本語環境や絵文字と食い合わせが悪くて、だいたい表示が崩れます。

東アジアの文字幅(east asian width)とかあいまい幅(ambiguous width)の問題と言われているヤツで、tmuxとかVimで苦しめられている方も多いんじゃないでしょうか。

``fish_ambiguous_width``と``fish_emoji_width``という設定値で幅を指定できるので、頑張れば回避できるかもしれません。(私は諦めました。)


### 拡張コマンド

fishでは、独自の構文(fish script)でスクリプトを書くことができます。実は先ほど出てきたプロンプトも、``fish_prompt``というコマンド(function)を書き換えることで設定します。

[Awesome fish](https://github.com/jorgebucaran/awesome-fish)に有名どころがまとまっているので、まずはこの範囲で試してみてください。

前述のパッケージマネージャでインストールするだけなので、めっちゃ簡単です。


## 📝参考になるサイト

* [fish shell documentation](https://fishshell.com/docs/current/index.html)
  * 公式のドキュメント。
* [全訳！fishシェル普及計画](http://fish.rubikitch.com/)
  * fishのドキュメントを日本語訳してくれているサイト。
  * 2〜3年前の情報なのでちょっと古くなっていますが、コマンドとかそんなに変わっていないので問題ないはず。
* [Awesome fish](https://github.com/jorgebucaran/awesome-fish)
  * fish関係のおすすめプラグインを紹介しているリポジトリ。


明日は[@e73ryo](https://qiita.com/e73ryo)さんの[「MonKey - Productivity Commands」のコマンド操作でUnity開発を効率化する](https://qiita.com/e73ryo/items/42758bb6c1f33de3adfa)です！