zshをfishのように使いやすくカスタマイズ

fishからzshに移行する過程を、備忘録的に残したいと思います。

# はじめに
僕は[fish](https://fishshell.com/)が大好きです。
今までのbashとは違った、使いやすくて離れづらいシェルです。
bashが使いづらいとは言ってません。

しかし、fishは**POSIX非互換**なんですよね。すると、いままでbashで構築してきた知識が半分くらい使えないんです。なんか困ったことがあってググっても、基本的にbash前提の記事ばかりなので、微妙に読み替えなきゃいけないところがあるの。
そこで、zshに乗り換えてフレンドリーでインタラクティブにして、fishのような使い勝手に仕立て上げようと思います。（元々インタラクティブではある件は気にせんといて）

（よく考えると、POSIX非互換でそれなりにユーザーがいて有名なシェルって、fishとpwsh(PowerShell)くらいしかないよね。fishすごい。ash含めるかは意見が分かれると思うけど。）

zshをfishに仕立て上げる（？）に当たって、再現するポイントを以下のように挙げました。今回は以下の項目を再現し終えることをゴールとします。

- fisherのようなシンプルで範囲の広い**プラグインマネージャー**
- bobthefishのような**Powerline風**プロンプト
- コマンド入力中に灰色で出てくる**入力サジェスト**
- コマンドの**シンタックスハイライト**
- コマンド入力中に展開されるエイリアス、**abbr**
- jethrokuan/zのように、**```z```コマンド**でぴょんぴょんディレクトリ移動（語彙死亡）

ではれっつごー

# 対象者
- シェルに関しての基礎知識がある方
- bashやfishなどからzshに移行する方

※基本的なことについては書いていないので、初めて触るシェルのセットアップをする方向けではありません。

# まずはzshのインストール
普段使ってるパッケージマネージャでインストールします。
```sh
sudo apt install zsh
```
ログインシェルにする（任意）
```sh
chsh -s /usr/bin/zsh ユーザ名
```
なんかセットアップ画面が出てきました。

<details>
<summary>こんな画面（クリックで開く）</summary>

```
This is the Z Shell configuration function for new users,
zsh-newuser-install.
You are seeing this message because you have no zsh startup files
(the files .zshenv, .zprofile, .zshrc, .zlogin in the directory
~).  This function can help you with a few settings that should
make your use of the shell easier.

You can:

(q)  Quit and do nothing.  The function will be run again next time.

(0)  Exit, creating the file ~/.zshrc containing just a comment.
     That will prevent this function being run again.

(1)  Continue to the main menu.

(2)  Populate your ~/.zshrc with the configuration recommended
     by the system administrator and exit (you will need to edit
     the file by hand, if so desired).

--- Type one of the keys in parentheses --- 
```

</details>

適当なキーを押すと画面が変わります。
初回起動だからホームディレクトリにzsh関連ファイルがなくて出てきたっぽいですね。
めんどくさいので、適当におすすめ設定つけといてもらいましょう。
```2```と打ちます。

zshのプロンプトが出てきました。
![Screenshot 2023-01-10 17.12.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819245/d176c567-3fa4-39cd-289c-9487c2a242a5.png)
だっさ。なにこれ。（ホスト名の消し方雑なのは許して）（あと、メイン端末ではないし、ってユーザー名の付け方も雑なの許して）
試しに```ls```でも打っときましょう。エイリアスも何も設定してないので、真っ白。結構見づらい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819245/08b3c1f0-9885-6651-a9de-799d06d46030.png)
どれがファイルでどれがしれクトリなのかさえわからんね。bashなら多くの場合デフォルトで色がつくのに。

一つだけ便利なところといえば、**入力中に[Tab]で補完**ができます。

これを使いやすくしていきましょう！

# Zplugの導入

:::note
僕は現在、zplugからantigenに乗り換えました。主に、zplugの読み込みがめっちゃ遅かったからです。詳しくはこの章の最後に書きます。
:::

**プラグインマネージャーである[Zplug](https://github.com/zplug/zplug)** を導入します。
プラグインマネージャー（の機能を持つものも含む）には、他にも、Oh My ZshやZinit（旧Zplugin）などがあります。

なぜZplugを選んだかというと、**シンプルだから**です。
Oh My Zshは、フレームワークというだけあって、機能が多すぎて複雑。一方のZinitは、比較的シンプルなのはいいのですが、2021年頃に作者がリモートリポジトリを削除してしまったという事件がありました。直後に有志がローカルのリポジトリから復元したらしいのですが、他のものを使ったほうが良さそうかなと思いました。

[日本語版公式ドキュメント](https://github.com/zplug/zplug/tree/master/doc/guide/ja)があるので、それに従いましょう。
（なんで日本語版があるのかな、と思ったら、GitHubのOrganizationメンバー3人中2人は日本人ですね。残りの一人は、個人じゃないっぽい？）

1. インストールする
    ```zsh
    curl -sL --proto-redir -all,https https://raw.githubusercontent.com/zplug/installer/master/installer.zsh| zsh
    ```
    インストール画面かっこいいね
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819245/77488bf1-842f-132e-181d-786ef17c6367.png)
1. ```~/.zshrc```に追記する（公式ドキュメントの解説部分は削ったもの+αを貼っときます）
    ```zsh:.zshrc
    #zplugの読み込み
    source ~/.zplug/init.zsh

    #zplugをzplug自身で管理
    zplug 'zplug/zplug', hook-build:'zplug --self-manage'

    #ここに他のプラグインについて設定する

    # 未インストール項目をインストールする
    if ! zplug check --verbose; then
        printf "インストールしますか? [y/N]: "
        if read -q; then
            echo; zplug install
        fi
    fi

    # コマンドをリンクして、PATH に追加し、プラグインは読み込む
    zplug load --verbose
    ```

これで、```source ~/.zshrc```で読み込めます。

なお、ここに管理するプラグインを記述する際は以下のようにします。（READMEより）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819245/b755fb4b-bb57-2e41-1cda-f278525894dd.png)
tagに関しては、[README#3-タグ](https://github.com/zplug/zplug/tree/master/doc/guide/ja#3-%E3%82%BF%E3%82%B0)を参照。

Oh-my-zshのプラグインも読み込めるし、gistのプラグインも読み込めるし、すごい便利です。
これも、[README](https://github.com/zplug/zplug/tree/master/doc/guide/ja)を参考にしてみてください。

## antigenに乗り換えました
**zplugの読み込みが遅かったので、[antigen](https://antigen.sharats.me/)に乗り換えました。**

zinitは気になっていたのですが、上述の理由からちょいとやめようかと思い、他に気になったのが**sheldon**と**antigen**でした。

antigenは以下に書いている入力サジェストとシンタックスハイライトと同じ提供元である**zsh-usersが公開**していたので選びました。

以下は[README](https://github.com/zsh-users/antigen/blob/develop/README.mkd)と[Wiki](https://github.com/zsh-users/antigen/wiki/Commands)に従います。

1. インストール
    ```zsh
    curl -sL git.io/antigen ~/antigen.zsh
    ```

1. .zshrcに追記
    ```zsh:.zshrc
    source ~/antigen.zsh

    #各種プラグインのインストール設定

    antigen apply
    ```

プラグインのインストール設定は以下のような書式です。
```zsh
antigen bundle [<url>[@tag|branch] [<loc>]]
```
例えば以下のようにします。
```zsh
antigen bundle alpaca-honke/prowpt@main prowpt.plugin.zsh
```
なお、ブランチ名とファイル名は省略可です。



# Powerline-shellのインストール
:::note
僕は現在、自作のプロンプト[Prowpt](https://github.com/alpaca-honke/prowpt)を使っています。詳しくはこの章の下に書いています。
:::

**カスタムプロンプトの[Powerline-shell](https://github.com/b-ryan/powerline-shell)** をインストールします。

[公式ガイド](https://github.com/b-ryan/powerline-shell#setup)に従いましょう。
今回はpipでのインストールを試します。

まずは**Pythonをインストール**します。
1. Pythonが入ってるか確認```python --version``` ```pip -v```
1. もしも未インストールなら```sudo apt install python```でPython2が入ります。
1. 念の為```sudo apt install python3```でPython3も入れときます。
1. もしも未インストールなら```sudo apt install pip```でpython3-pipが入りました。

次に**Powerline-shellをインストール**します。zplugでの管理方法がわからないので、普通にインストールします。
1. ```pip install powerline-shell```
1. 画像のように、PATH通ってないよーって言われたら、PATHを通しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819245/1c725208-c418-64dd-a034-1cd694aefacf.png)
```~/.zshrc```のPATH指定部分を編集します。もしなければ、適当に作っといてください。
    ```zsh:.zshrc
    export PATH="$HOME/.local/bin:$PATH"
    ```
1. ```~/.zshrc```に以下を追記。
    ```zsh:.zshrc
    function powerline_precmd() {
        PS1="$(powerline-shell --shell zsh $?)"
    }

    function install_powerline_precmd() {
      for s in ${precmd_functions[@]}; do
        if [ "$s" = "powerline_precmd" ]; then
          return
        fi
      done
      precmd_functions+=(powerline_precmd)
    }

    if [ "$TERM" != "linux" ]; then
        install_powerline_precmd
    fi
    ```
1. ターミナルを再起動で適用されます。
![Screenshot 2023-01-10 20.55.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819245/a09df9be-0343-8239-71d8-4cdbe73f187f.png)
かっこいい。

もし、文字化けが酷いようであれば、[Powerline Fonts](https://github.com/powerline/fonts)や[Nerd Fonts](https://www.nerdfonts.com/)を使いましょう。
個人的には後者の方がグリフが多くてオススメです。

※なぜか```source ~/.zshrc```するごとにプロンプトがダサいやつに戻ってしまうので、ターミナルを再起動してます。原因わかる方いたら教えて下さい。

カスタマイズは、[PowerlineのREADME#customization](https://github.com/b-ryan/powerline-shell#customization)参考。

## Prowptに乗り換えました。
これは自作です。自分の好みにピッタリ合うものを作ったんです。
[日本語README](https://github.com/alpaca-honke/prowpt/blob/main/README-ja.md)に従います。
とは言っても.zshrcに追記するだけです。

- zplugの場合
    ```zsh
    zplug "alpaca-honke/prowpt", as:plugin, at:main
    ```
- antigenの場合
    ```zsh
    antigen bundle alpaca-honke/prowpt@main
    ```

その他のカスタマイズは[日本語README](https://github.com/alpaca-honke/prowpt/blob/main/README-ja.md)に詳しく書いたので、見てみてください。

# zsh-autosuggestionの導入
**入力サジェストのプラグイン、[zsh-autosuggestion](https://github.com/zsh-users/zsh-autosuggestions)** を導入します。

1. ```~/.zshrc```に追記する
    - zplug
        ```zsh:.zshrc
        zplug "zsh-users/zsh-autosuggestions", as:plugin
        ```
    - antigen
        ```zsh:.zshrc
        antigen bundle zsh-users/zsh-autosuggestions
        ```
1. ターミナルを再起動

**これだけ！**
こんな感じでサジェストされました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819245/29197e27-b35e-761e-5c11-8021d8eb7622.png)
**右矢印キーで候補を入力** できます！

# zsh-syntax-highlightingを導入する
**シンタックスハイライトプラグイン、[zsh-syntax-highlighting](https://github.com/zsh-users/zsh-syntax-highlighting)** を導入します。

上記autosuggestionsと同じ要領です。

1. ```~/.zshrc```に追記する
    - zplug
        ```zsh:.zshrc
        zplug "zsh-users/zsh-syntax-highlighting"
        ```
    - antigen
        ```zsh:.zshrc
        antigen bundle zsh-users/zsh-syntax-highlighting
        ```
1. ターミナルを再起動

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819245/be06bd86-b40e-738b-ede3-345123d1bf78.png)
ちょっと見づらいですがこんな感じでハイライトされました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819245/0e64f20e-2748-f2f7-39a8-b3d77571617a.png)
間違ってると赤くなります

# zsh-abbrを導入
**展開されるaliasである[zsh-abbr](https://github.com/olets/zsh-abbr)** を導入します。

1. ```~/.zshrc```に追記する
    - zplug
        ```zsh:.zshrc
        zplug "olets/zsh-abbr"
        ```
    - antigen
        ```zsh:.zshrc
        antigen bundle olets/zsh-abbr@main
        ```
1. ターミナルを再起動

これで、```.zshrc```に **```alias```の代わりに```abbr```を使用することで、コマンド入力中にエイリアスが[Space]or[Enter]で展開される** ようになります。このとき、```.zshrc```の末尾にabbrを追加しないと、コマンドがねえぞって怒られました。

```-S```オプションは、セッション限定のabbrになります。これを使うことで、aliasと同じような感覚で設定できます。
あと、**標準出力を捨てないと、起動時にメッセージがエグい** ことになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819245/dae82166-42ac-1680-1269-18ce410eb1f9.png)
例えば、以下は僕の設定です。（git系のabbrが一部、一般的に使われてるaliasとは違うのは僕の好みです）

```zsh:.zshrc
abbr -S ll='ls -l' >>/dev/null
abbr -S la='ls -A' >>/dev/null
abbr -S lla='ls -l -A' >>/dev/null
abbr -S gst='git status' >>/dev/null
abbr -S gsw='git switch' >>/dev/null
abbr -S gbr='git branch' >>/dev/null
abbr -S gfe='git fetch' >>/dev/null
abbr -S gpl='git pull' >>/dev/null
abbr -S gad='git add' >>/dev/null
abbr -S gcm='git commit' >>/dev/null
abbr -S gmg='git merge' >>/dev/null
abbr -S gpsh='git push' >>/dev/null
```
プロンプトに入力時に、こんなコマンドねえよって赤くハイライトされることはちょっと不満ですが、まあ大して困らないんで良しとします。

ついでに、普通のエイリアスとして以下も登録しとこう。
```ls```打った時に、アイテムの種類（通常ファイルか、実行権限つきか、ディレクトリか、シンボリックリンクか、パイプか、ソケットか）がひと目でわかるようになります。
```zsh:.zshrc
alias ls='ls -F --color=auto'
```

# zの導入
**ディレクトリを簡単に飛び回れるコマンド、[rupa/z](https://github.com/rupa/z)** を導入します。

1. ```~/.zshrc```に追記する
    - zplug
        ```zsh:.zshrc
        zplug "rupa/z", use:"*.sh" #useタグを忘れないように
        ```
    - antigen
        ```zsh:.zshrc
        antigen bundle rupa/z z.sh
        ```
1. ターミナル再起動

これで、 **一度アクセスしたディレクトリなら、ディレクトリ名の一部を入力するだけで移動** できます！

例えば、こんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819245/958f5399-c366-b754-9771-dab87354fab8.png)
これ、めちゃくちゃ便利で、階層が深くてカレントディレクトリから遠いとこに移動したいときにすっごいありがたいんです。

# おわり
zshがかっこよくなって、つかいやすくなった！
あるかっぱのレベルが、1あがった！
（終わり方雑）

なお、僕のdotfiles的なリポジトリに置いてある.zshrcを使うとこの辺の設定が手間いらずで行われます。ミソは、antigenがインストールされてなければ勝手にインストールするコマンドを書くことです。

https://github.com/alpaca-honke/config/blob/main/zsh

なおこのリポジトリを使用したことによる損害等に関して一切の責任は負いません。