bash 使いが fish でスイスイ泳げるようになるまで (in Mac)

# mac で fish の水槽(環境)整備。

### 気持ち
* 最近、`macOS 10.15 Catalina` では デフォルトのシェルが `bash` から `zsh` になったという記事をちらほら拝見しました。あまのじゃくな僕はこの機会に `fish` の環境を一通り整えてみることにしました。

* fish に関しては、以前 [この記事](https://qiita.com/daichildren98/items/9d3f7169ef39ff1fba5e) で入門をしたものの、「エンジニアは最初に見たシェルを親だと思って着いていく」という性質があるので、ずっと `bash` を使っていました。

* 「一通り」とは言っても、独断と偏見で、こんな感じでいいでしょ と思うとこまでやった、という意味です。

* 内容は以下の通りです。 

1. パッケージ管理ツールを入れる
    - `fisher` ( `fisherman` ) or `oh-my-fish`
2. `powerline`
    - プロンプトが `>Users>Name>Documents>hoge>` みたいになるやつ
    - `theme-bobthefish` とかいうやつで実現できるらしい。
3. `peco`
    - `history` 検索便利ツール
4. `z`
    - ディレクトリの history 検索便利ツール。


ちなみに現状はこんな感じです↓
<img width="538" alt="スクリーンショット 2019-11-08 22.15.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354061/6bd13e1d-aac1-481f-a1b0-3c4236094226.png">

ディレクトリは CNN 研究用なのであまり気にしないでください..
ということで、順次導入していきます。




## mac に fish を install
`$ brew install fish`

* ちなみにバージョンは

```console
~> fish --version
fish, version 3.0.2
```

* `/etc/shells` に fish を追記します。

    - 先に which fish で確認

```console
$ which fish
/usr/local/bin/fish
```

* この結果を `/etc/shells` に追記します。

    - `$ emacs /etc/shells` でもいいですし、
    - `$ cat /usr/local/bin/fish >> /etc/shells` でもよいです。

```/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/ksh
/bin/sh
/bin/tcsh
/bin/zsh
/usr/local/bin/fish  # これを追記
```


### デフォルトの shell を fish にするなら
* `$ chsh -s /usr/local/bin/fish`

### 起動
* ちなみに install 直後に fish を起動すると以下のような感じです

```console
DaiMac:~ sudachi $ fish  # <= bash

Welcome to fish, the friendly interactive shell
sudachi@DaiMac ~>  # <= fish
```

* colorize や conda 環境の設定などはなにもしていません。
    -  `~>` の `~` の部分 (ディレクトリ表示部分) が緑なだけです。

## 設定ファイル

* デフォルトでは 1つだけあるようです。

```console
$ ls .config/fish/
fish_variables
```

* `$ la`, `$ ll` などが普通に (設定してないのに) 動く。
    - すげえ
* `$ l` は動きませんでした。
    - 試しに、これを alias として登録してみましょう。

```console
~> emacs ~/.config/fish/config.fish
-- 8<---- 8<---- 8<---- 8<---- 8<---- 8<---- 8<--
alias l 'ls -CF'  # これを追記
-- 8<---- 8<---- 8<---- 8<---- 8<---- 8<---- 8<--
~> source ~/.config/fish/config.fish
~> l
Downloads/    Desktop/    Documents/ ...
# OK うごきました!
```

* 以下、度々出てくる `-- 8<--` は エディタのバッファを意味します。

## 1. package manager: fisher
([参考2](http://sansuke05.hatenablog.com/entry/2017/11/03/131216) より)
> fish には oh-my-fish という fish のパッケージ管理フレームワークがあるのですが、古いとか著作権問題がどーのこーので停止してたとか結構ディスられてました。
> そこで、Fisherman というプラグインマネージャーがいいということだったので Fishermanを導入してみることに

* そのほか参考にさせていただいたサイトでも、概ね `fisher(man)` を install しているものが多かったので従おうと思います (長いものには巻かれろ)。

### curl で落とします。

```console
~> curl https://git.io/fisher --create-dirs -sLo ~/.config/fish/functions/fisher.fish
~> ls ~/.config/fish/
fish_variables functions  # <= functions/ が増えた。
```

* 確認です。

```console
~> fisher -v
fisher version 3.2.9 ~/.config/fish/functions/fisher.fish
```
* conf 下に配置するだけで使えるようになるみたいですね。

## 3. peco plugin

* すみません順番が前後しますが先に `peco` を入れます。

* package の add (プラグインを入れている感じなのかな?)

```console
~> fisher add oh-my-fish/plugin-peco
created new fishfile in ~/.config/fish/fishfile
fetching https://codeload.github.com/oh-my-fish/plugin-peco/tar.gz/master
linking ~/.config/fish/functions/peco_kill.fish
linking ~/.config/fish/functions/peco_select_history.fish
added 1 package in 0.55s
```

* peco を用いた検索を `Ctrl-r` に割り当てます。
    - ちなみに `bash` では `Ctrl-r` は `history` を後方検索するショートカットに割り当てられていますね。
    - `peco` の設定をする前の `fish` で 同キーバインドを試して見ましたが、特に割り当てられていないようでなにも起こりませんでした。

* `~/.config/fish/config.fish` に設定を追記します。

```~/.config/fish/config.fish
#peco
function fish_user_key_bindings
    bind \cr peco_select_history
end
```

* これだけだと `Ctrl-r` した後に以下のような Error が出てしまいました。

```console
~> fish: Unknown command peco
~/.config/fish/functions/peco_select_history.fish (line 8):
  history|peco $peco_flags|read foo
          ^
in function 'peco_select_history'
    called on standard input

```

* `brew` で 本体にも `peco` を入れる必要があるようです。
    - `peco` 自体は `fish` 関係なく、コマンド履歴とディレクトリ移動先の検索を行える tool として提供されているらしいです。

### brew で peco をインストール
* `$ brew install peco` で取得できるらしい。
    - これも install したら `Ctrl-r` で実行できるようになりました!
    - `peco` そのものと、 `fish` 用 `plugin` が必要ということなのでしょうか..
        + ちなみに `brew` で `peco` を入れたわけですが、 `bash` では `Ctrl-r` しても後方検索のままでした。 
        + `.bashrc` などに設定をかけば変わるかもしれませんね。

## z をいれます。
* `z` : 履歴からディレクトリへ移動ができるコマンドです。

* 訪問履歴からディレクトリ移動候補を表示してくれます。
* また、`z {文字列}` のように入力すると、履歴から一致するものを探して来てくれるようです。

### インストール
* `~> fisher add jethrokuan/z`

    - `~> z python` とかやると下に python 関連のプロジェクトのディレクトリが検索され、候補が出てきてくれるようになりました!
    - 選択後、`z path` となったら、`Enter` を押すと移動してくれるようです。 

## 2. theme-bobthefish プラグインの導入

* いよいよお待ちかね、`powerline` に見えるアレを入れます。

    - コンソールの見た目をリッチにしてくれる上に、 `git` の現在のブランチや差分状況をわかりやすく表示してくれる機能もあるので `git` を使っている方ならぜひオススメしたいですね
    - **ただし、 これを入れると、プロンプトをコピペした時に文字化けします。**
        + 普段コンソールの入出力などのメモを取りながら作業をなさる方は注意です..
        + 以下、`fish` を用いていますがプロンプトは `$` を用います。

### インストールです
* `~> fisher add oh-my-fish/theme-bobthefish`

    - インストール完了するとすぐに反映されますが文字化けする場合があります。
    - その場合は Powerline-fonts をインストールしましょう。
    - 以下に手順を載せます。

### Powerline-fonts をインストール
* どこでもいいので、powerline-fonts をダウンロードしましょう。
    - 僕は fish の設定ファイルの場所に適当にコピリました。

```console
$ cd ~/.config/fish

$ git clone https://github.com/powerline/fonts.git

$ l
config.fish    fish_variables    fonts/  # <= これが増えた
```

* ダウンロード `fonts/` ディレクトリ下に移動し、インストールを実行します。

```console
$ cd fonts
$ ./install.sh
Copying fonts...
Resetting font cache, this may take a moment...
Powerline fonts installed to /Users/sudachi/Library/Fonts
```

* install できれば、`fonts/` は用済みなので、いらなければ削除してしまいましょう。

```console
$ cd ../
$ rm -rf ./fonts
```

### 次に terminal のフォントを powerline-font に変更します
* 次に、`terminal` や `iTeam2` にて、インストールした `powerline-fonts` を使うように設定します。

* `iTerm2` 使いの方
    - `iTerm2 > Preferences > Profiles > Text > Font` から

    - `Literation Mono Powerline` を選択しましょう。

    - ここです↓
<img width="927" alt="スクリーンショット 2019-11-08 23.03.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354061/9d8a8099-816a-d8b3-08b9-f98711e7db4b.png">


        + と、参考には書いてあったのですが.....
        + `ubuntu Mono derivative Powerline` という Font がある!!
        + メイン武器が `ubuntu` なこともありますが `ubuntu` の Font 案外好きなんですよね。
        + これにしても問題なかったのでこれにしてみました!! かわいい!!
        + そして、なんか心なしか文字が小さくなった気がする..ので `12 -> 14` に変更

* `terminal.app` (デフォルトのやつ) をお使いの方

    - `環境設定 > プロファイル > テキスト > フォント` で設定できます。

    - ここ ↓ から同様の手順で変更してください。

<img width="668" alt="スクリーンショット 2019-11-08 23.05.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354061/0116b9c6-272b-dff2-21cb-171800af0142.png">


### ブランチ名が表示されていない場合

* 文字化けが解消されたが、現在のブランチ名が出てきませんでした。

    - その場合は、`config.fish` に 以下をを追記して再読み込みすることで表示されるようになります。


```~/.config/fish/config.fish
set -g theme_display_git_master_branch yes
```

```console
$ source ~/.config/fish/config.fish
```


### optional な設定

* ディレクトリを省略したくない場合
    - デフォルトでは、以下のようにカレントディレクトリ以外は省略されています。

```
~/D/p/0/cnn >> master >
# 本当は ~/Documents/python/020_AI/cnn (master)
```

* 省略させたくない場合は `config.fish` に以下を追記しましょう。

```~/.config/fish/config.fish
set -g fish_prompt_pwd_dir_length 0
```

* 更新をお忘れなく..

```console
$ source ~/.config/fish/config.fish
```


#### 以下、僕が `config.fish` に追記した内容です

* `prompt` を `new line` で実行するように変更

```~/.config/fish/config.fish
set -g theme_newline_cursor yes
```

* 時刻を表示しないように設定

```~/.config/fish/config.fish
set -g theme_display_date no
```

* コマンド実行時間の非表示

```~/.config/fish/config.fish
set -g theme_display_cmd_duration no
```


## anaconda path を通す

* python を使って画像認識の研究をしているので、anaconda を使いたいです。

* 現状

```console
$ which python
/usr/bin/python  # デフォルトで入っている 2系のやつ
```

### pyenv
* 僕の anaconda は `pyenv` の上で動いているので、先に `pyenv` を通します。
    - 以下の path を `config.fish` に追加

```console
-- 8<---- 8<---- 8<---- 8<---- 8<---- 8<--
set PATH $HOME/.pyenv $PATH
eval (pyenv init - | source)
-- 8<---- 8<---- 8<---- 8<---- 8<---- 8<--

$ python --version
Python 3.6.5 :: Anaconda, Inc.  # お??

$ which python
/Users/sudachi/.pyenv/shims/python  # 通った..のかな??
```

### anaconda

* 上記の path を通すと、なぜかすぐに `conda` が使えるようになりました。

```console
$ conda -V
conda 4.6.14

$ conda activate
CommandNotFoundError:

$ conda init fish
$ conda activate  # <= できない??
```

* `conda` は使えるようになりましたが、`conda activate` などが使えない場合は以下を `config.fish` に追記します。

```console
-- 8<---- 8<---- 8<---- 8<---- 8<---- 8<--
set -x PATH $PATH "$PYENV_ROOT/bin"
status --is-interactive; and . (pyenv init - | psub)

source (conda info --root)/etc/fish/conf.d/conda.fish
-- 8<---- 8<---- 8<---- 8<---- 8<---- 8<--

$ source ~/.config/fish/config.fish 

$ conda -V
conda 4.6.14

$ conda activate
$                                                          (base)
$ which python                                             (base)
/Users/sudachi/.pyenv/versions/anaconda3-5.2.0/bin/python

$ conda activate dataflow                              (base)
$ which python                                         (dataflow)
/Users/sudachi/.pyenv/versions/anaconda3-5.2.0/envs/dataflow/bin/python

$ python --version                                     (dataflow)
Python 2.7.16 :: Anaconda, Inc.
```

* ubuntu に fish 入れた時も思いましたが、その末尾に出るスタイルは変わらないんだ..って感じです。

## 最終的に..

* うちの fish はこんな感じにすくすく成長しました↓

<img width="636" alt="スクリーンショット 2019-11-08 19.38.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354061/377c4e35-6320-ea44-fbdd-87d76d5928e8.png">

### 一応設定ファイルも晒しておきます。

```~/.config/fish/config.fish
# ----------
# peco config
# ----------
set fish_plugins theme peco

function fish_user_key_bindings
  bind \cr peco_select_history # Bind for prco history to Ctrl+r
end

# ----------
# bobthefish config
# ----------
set -g fish_prompt_pwd_dir_length 0  # ディレクトリ省略しない
set -g theme_newline_cursor yes  # プロンプトを改行した先に設ける
set -g theme_display_git_master_branch yes  # git の branch 名を表示
set -g theme_color_scheme dracula
set -g theme_display_date no  # 時刻を表示しないように設定
set -g theme_display_cmd_duration no  # コマンド実行時間の非表示


# ----------
# python
# ----------
set -gx PYENV_ROOT "$HOME/.pyenv"
set -x PATH $PATH "$PYENV_ROOT/bin"
status --is-interactive; and . (pyenv init - | psub)

source (conda info --root)/etc/fish/conf.d/conda.fish

# ----------
# node.js
# ----------
set -x PATH $HOME/.nodebrew/current/bin $PATH

# ----------
# alias
# ----------
alias l 'ls -CF'
```

* `git` に `conda` を使い始めるといきなりコンソールが騒がしい感じになりますが、これで `fish` を運用する準備は整ったと思います。

* さあ、遊ぶぞ~


## 参考です。お世話になりました。
1. [fish shell の導入方法と使い方まとめ](https://blogenist.jp/2019/06/20/8807/)
2. [【fish】ターミナル環境をかっこよくしてみた話](http://sansuke05.hatenablog.com/entry/2017/11/03/131216)
3. [詳解 fish](https://qiita.com/susieyy/items/ac2133e249f252dc9a34)
4. [fish shell を使いたい人生だった](https://dev.classmethod.jp/etc/fish-shell-life/)
5. [powerline font](https://qiita.com/park-jh/items/557a9d5b470947aef2f5)
6. [bobthefish 各種設定](https://qiita.com/sugimount/items/ff80f9ba481ec81b5600)
7. [pyenv path](https://qiita.com/nako0123/items/da0c14aafb778a75c1e4)
8. [conda activate](https://qiita.com/snara/items/632d42aa8e98c4658aeb)