「猫が好きなら、シェルはやっぱりfish でしょ！」と冗談半分で乗り換えたら、案外良かったので Laravel + Vue.js の開発環境を fish で整える話

[qnote Advent Calendar 2020](https://qiita.com/advent-calendar/2020/qnote) の10日目です。

世にはいろんなシェルがある。
fish というシェルを皆さんはご存知でしょうか。

私は入社前から入社後しばらくは、シェルに種類があるなんてことも知らずに bash を使っていました。

しかし、ある日同僚の @adwin さんの画面を見てみるとなんかすごい。予測変換とか画面分割（tmux）してたりとか、vim もカラフル！
そこで、はじめて zsh の存在を知りました。

そレから一年くらい [Oh My Zsh](https://ohmyz.sh/) で、zsh ライフを楽しんで一人でどやってましたｗ（全然使いこなせてないなかったと思う。）
しかし、起動時に遅かったり、なんか色々できるみたいだけど設定よくわからないな。。と思っていました。

そんな時、ふと「そういえば @adwin さんがフィッシュってのもあるって言ってたな！」と思い出し
**「やっぱり、猫がいる会社に務めているんだし、シェルはフィッシュでしょ！」**
と冗談半分でフィッシュを使い始めた。

----
（2021/04/02 追記）
Big Sur でタブ補完が遅いバグが合ったようですが、バージョン 3.2.0 以降では改善しています。

https://qiita.com/hanlio/items/52b3a5c540fc2568cfe3

---

# 余談
フィッシュと言えば、25才くらいの時に、私はフィッシングにハマった時期がありました。

その当時の職場では、同僚が30,40代の人が多く、同僚が釣りの話をよくしていたので、私も釣りを始めました。
初めは、[本牧海づり施設](http://honmoku.yokohama-fishingpiers.jp/)で小鰯をサビキ釣りして、マリネなんかにして楽しんでいました。

その後、チョイ投げなんかもやりたくなって、江ノ島水族館の近くの東プロムナードという防波堤に通うようになりました。
防波堤から見る夕焼けは、とても綺麗でのんびりデートなんかにも良いですよ。[江ノ島 小屋](http://enoshima-koya.com/)というご飯処もオススメです。
ここの防波堤で、一度に舌平目が４匹も釣れたことがあり、帰って youtube を観ながらヒラメを見よう見まねで捌いてムニエルにして食べたことは良い思い出です。

当時は横浜勤務だったので、会社帰りにみなとみらいの方に少し寄ってルアーを投げてみたり、毎日通勤中に[GO!GO!九ちゃんフィッシング](https://www.youtube.com/channel/UC9pXJVDwG7YfjR7ZQxiFC5g)を観たりと、どハマりしていました。

あと、もし[沼津深海魚水族館](http://www.numazu-deepsea.com/)に行くことがあったら、[五鉄](http://numazu-gotetsu.com/)に寄って海鮮丼食べてみてください。ここの海鮮丼はとても美味しかった思い出があるので、オススメです。

# 本題
今回は、既に bash や zsh などのシェル環境で既に Laravel + Vue.js の開発を行っている方が、 fish に切り替える際の設定と、 fish の基本的なコマンドやお作法を紹介したいと思います。

なぜ、他シェルからの切り替えについてかというと、今まで出来ていたことがシェルを切り替えて出来なくなると、「もう良いや。元に戻そう」となりがちじゃないですか！
なので、スムーズに fish に切り替える手助けになればと考えたからです。

# fish とは？
![](https://rootnroll.com/static/inara/images/logos/fish-shell.png)
fish は、ユーザフレンドリーを謳っているシェルです。
fish は、デフォルトでコマンドの補完や予測が使え、機能を絞っているから故に起動が早い。

![スクリーンショット 2020-12-09 16.36.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185846/b7fd4aef-4181-0e08-e1ad-b1575badf704.png)
![スクリーンショット 2020-12-09 16.38.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185846/7ee0e7bf-3d86-453b-915b-c02e4faad1d7.png)

[fish shell HP](https://fishshell.com/)

# fish install
Mac あれば homebrew でインストール可能

```sh
$ brew install fish
```

# fish shell に切り替える
```sh
$ fish

# 終了する場合
> exit
```

# php と composer のバスを通す
`php` のバージョンを変える際など、 `brew link php@8.0` にしても `fish` では変わらない。
`$fish_user_path` で `brew` でインストールした `php` のバージョンを見るようにパスを設定する必要があります。

```sh
# php8.0 のパスを通す
> set -U fish_user_paths /usr/local/opt/php@8.0/bin/ $fish_user_paths

# composer のパスを通す
> set -U fish_user_paths $HOME/.composer/vendor/bin $fish_user_paths
```

[fish shell環境下でMacのPHPバージョンを上げる](https://qiita.com/s-yoshida/items/11dc5f69bbdf461f6c5e)
[fish shell チュートリアル](http://fish.rubikitch.com/tutorial/)

# homestead
bash でも zsh は、 .bash_profile や .zprofile に関数を書き込みますが、 fish の場合は、 function として作成することができます。

## function でシェル関数作成
```sh
> function homestead
        set DIR $PWD
        cd ~/Homestead
        eval vagrant $argv
        cd $DIR
  end
```

## 動作確認
```sh
> homestaed up
```

# シェル関数を永続化
```sh
> funcsave homestead
```

https://gist.github.com/tikolakin/d59b4fc87c0af9720d0d

※ fish-homestead というプラグインを以前見つけて使っていたが、 GitHub がアーカイブされていたので上記に変更した

# fisher
fisher は、fish のプラグイン管理ツールです。
[Fisher GitHub](https://github.com/jorgebucaran/fisher)

[Oh My Fish](https://github.com/oh-my-fish/oh-my-fish) のブラグインやテーマが使用できる

```sh
# インストール
> curl -sL https://git.io/fisher | source && fisher install jorgebucaran/fisher
```

以下のように使用する

```sh
# プラグインの追加
> fisher add ***
# 追加ずみのプラグインの確認
> fisher ls
# プラグインの削除
> fisher rm ***
```

# fish-nvm を使えるようにする
fish では、nvm をインストールしただけでは使用できない
fish-nvm をインストールする必要があります。

```sh
> fisher add FabioAntunes/fish-nvm
> fisher add edc/bass
```

普通に nvm が利用できるようになります。

```sh
# nvm が使える
> nvm install lts

```

functions で関数を確認すると、 nvm が追加されています。

```sh
> functions nvm
function nvm
        if not type -q bass
    echo 'Bass is not installed please install it running fisher edc/bass'
    return
  end
  set -q NVM_DIR; or set -gx NVM_DIR ~/.nvm
  set -q nvm_prefix; or set -gx nvm_prefix $NVM_DIR

  bass source $nvm_prefix/nvm.sh --no-use ';' nvm $argv

  set bstatus $status

  if test $bstatus -gt 0
    return $bstatus
  end

  if test (count $argv) -lt 1
    return 0
  end

  if test $argv[1] = "use"; or test $argv[1] = "install"
    set -g NVM_HAS_RUN 1
  end
end

```

https://github.com/FabioAntunes/fish-nvm


以上で、laravel + Vue.js の開発環境は整いました。
それでは皆さん良い fish ライフを！

# fish の基本的なコマンドやお作法
ここからは bash zsh とは異なる fish を使ってい上で、最低限押さえておいて基本的なコマンドやお作法について紹介します。

## fish_config
fish では color や history などをブラウザ上で変更したり確認することができます。

```sh
> fish_config
```

と実行すると、以下の画面がブラウザで開きます。
![スクリーンショット 2020-12-01 21.22.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185846/a3965915-22e1-fc20-bc6a-765f549d0cbb.png)

お好みの color を選んだら、 Set Theme を押すだけで変更できます。
(まあ、すぐテーマを使いたくなると思いますがねw）

## function　funcsave
fish は、 bash や zsh とは異なり alias が存在しません。
全てのコマンドは、 `~/.config/fish/functions` に `.fish` というファイルで格納される。

homestead で登場したが、fish でシェル関数を作成するコマンドが `function` です。
なお、function で作成したシェル関数は、ローカル関数になのでログインし直すと消えてしまいます。
function で作成したローカル関数を永続化するのが、`funcsave` です。

例えば、

```sh
# git fetch -p の function を作る
$ function gf
     git fetch -p
end

# --discription で説明も追加可能
$ function gf --discription 'git fetch -p の短縮コマンド'
     git fetch -p
end
```


## functions
`~/.config/fish/functions` にシェル関数が格納されると説明しましたが、 `functions` でその関数を確認することができます。

```sh
# シェル関数を指定して、内容を確認
> functions homestead
function homestead
        set DIR $PWD
        cd ~/Homestead
        eval vagrant $argv
        cd $DIR
end


# 全てのシェル関数を一覧表示
> functions
., :, N_, abbr, alias, bass, bg, bobthefish_display_colors, cd, cdh, contains_seq, cwd_in_scm_blacklist, delete-or-exit, dirh, dirs, disown, down-edu, down-or-search, edit_command_buffer, eval, export,
fg, fish_breakpoint_prompt, fish_clipboard_copy, fish_clipboard_paste, fish_config, fish_cursor_name_to_code, fish_default_key_bindings, fish_default_mode_prompt, fish_fallback_prompt, fish_greeting,
fish_hybrid_key_bindings, fish_indent, fish_key_reader, fish_md5, fish_mode_prompt, fish_opt, fish_print_hg_root, fish_prompt, fish_right_prompt, fish_sigtrap_handler, fish_title, fish_update_completions,
fish_vi_cursor, fish_vi_key_bindings, fish_vi_mode, fisher, funced, funcsave, gco, get_hostname, gf, grep, gstatus, help, hg_get_state, history, homestead, hostname, isatty, kill, la, lint, ll, ls, man,
nextd, nextd-or-forward-word, node, npm, npx, nvm, nvm_alias_command, nvm_alias_function, open, parse_git_dirty, phpunit, popd, prevd, prevd-or-backward-word, prompt_dir, prompt_finish, prompt_git,
prompt_hg, prompt_hostname, prompt_pwd, prompt_segment, prompt_status, prompt_svn, prompt_user, prompt_vi_mode, prompt_virtual_env, psub, pt, pull, push, pushd, q, realpath, seq, setenv, string, suspend,
svn_get_branch, svn_get_revision, trap, type, umask, up-edu, up-or-search, vared, wait, yarn,
```

## set
fish は、 bash や zsh とは異なり export コマンドが存在しません。
パスを通す場合は、set コマンドを使用します。

なお、fish のパスには、 `$PATH` と `$fish_user_paths` が存在する。

- `$PATH` : 文字通りパスです。
- `$fish_user_paths` : `$PATH` の前に追加されるパスを指定できます

パスは、先に書かれたパスが優先されます。

そのため、私は `$fish_user_paths` を積極的に使っています。

```sh
# パスの追加
> set -U fish_user_paths /usr/local/opt/php@7.4/bin/ $fish_user_paths

# パスの確認
> echo $fish_user_paths
```

パスを削除する場合は `-e -U` オプションを使用しますが、削除対象はインデックス番号で指定する必要があるのが、少し難点。
そのため、以下のようにすることで、インデックス番号を確認した上で削除するとよいでしょう。
※ちなみに、 fish での配列は 1 から始まります。

```sh
# パスの確認（インデックスも含めて）
> echo $fish_user_paths | tr " " "\n" | nl
     1  /usr/local/opt/php@7.4/bin/
     2  /usr/local/opt/php@7.3/bin/
     3  /usr/local/opt/php@7.4/bin/
     4  /Users/higashiizumi/.nodebrew/current/bin

# パスの削除
> set -e -U fish_user_paths[1]
```

 
https://fishshell.com/docs/current/index.html

## theme
fish_config で配色を変更できますが、theme を使用することもできます。
Oh My Fish の theme ページから好きなものを選んでください。
https://github.com/oh-my-fish/oh-my-fish/blob/master/docs/Themes.md

選んだら、 `fisher add` で適用できます。

```sh
# bobthefish を適用したい場合
> fisher add oh-my-fish/theme-bobthefish 
```

![](https://cloud.githubusercontent.com/assets/53660/18028510/f16f6b2c-6c35-11e6-8eb9-9f23ea3cce2e.gif)

# 終わりに
どうでしょうか？
少し fish を使ってみたくなりましたか？
これで1人でも多くの人に fish を知ってもらい、好きになってもらえたら嬉しく思います。

もっと fish について知りたい方は、[全訳！fishシェル普及計画](http://fish.rubikitch.com/) や他の方の記事を読んでみてください。

ついでに、余談であげたご飯処とかも興味があれば行ってみて、感想くださいw

~~余談書いてて楽しくなっちゃって、そっちばっか書いちゃった。~~

終わりです。

明日は、 @adwin さん。
スマートホーム化がどうなったのか楽しみです。