zinitでzsh環境をいい感じにしたメモ

# はじめに

プログラミングで使っているPC（プログラミングに使わないPCは持ってないけど）のシェルはここ3年くらいは **zsh** を使っていて、zshの機能を拡張するためのプラグインマネージャには [Prezto](https://github.com/sorin-ionescu/prezto) を利用していました。

> ↓過去にPreztoでzsh環境を作ったときの記事
> [Macのzshでプロンプトをカスタマイズしたり、コマンド履歴を検索したりできるようにする](https://qiita.com/crossroad0201/items/7b8db9fc8c6f85562a66)

今回、仕事で使うPCが新しくなったので、今どきのプラグインマネージャはどれが良いんだろう？と調べてみたところ、 [zinit](https://github.com/zdharma/zinit)（旧名 zplugin）が良さそうだったのでこれを使ってシェル環境を作ってみました。
結果としては以前に **Prezto** で設定していたシェル環境よりも快適になったと思います。

なお、数多あるzshプラグインマネージャの情報は [awesome-zsh-plugins](https://project-awesome.org/unixorn/awesome-zsh-plugins) がまとまっていて参考になりました。

# zinitのいいところ

* 起動が速い。
* 従来のプラグインマネージャ [oh-my-zsh](https://github.com/robbyrussell/oh-my-zsh) や [Prezto](https://github.com/sorin-ionescu/prezto) の豊富なプラグイン資産を使える。

# セットアップ後に使える機能

後述の手順で **zinit** をセットアップし終えると、以下の機能が使えるようになります。

これら以外にも多彩なプラグインで機能追加することが可能です。

|機能|説明|起動方法|
|----|----|----|
|プロンプトのカスタマイズ|プロンプトにGitのステータスやブランチ、日時などを表示。|-|
|コマンド・オプション入力補完|入力中のコマンドやそのオプションを補完。|`TAB`|
|ハイライト|コマンドやオプションを色分けして表示。|-|
|コマンド履歴検索|以前に実行したコマンド履歴をインクリメンタルサーチで呼び出す。|`Ctrl+r`|
|GitHubを開く|コマンドでGitHub Webサイトを開く。|`ghg`|
|インタラクティブなjq| `jq` によるJSONサーチをインクリメンタルに。|`Alt+j`|
|高機能なls|Gitステータスが色分けされて見れる ls。|`k`|
|AWS CLI v2入力補完|AWS CLI v2のサブコマンド・オプションを補完。|`TAB`|
|pecoでcd履歴検索|以前に `cd` で移動したディレクトリの履歴を、 `peco` で検索して呼び出す。|`Ctrl+x` -> `b` ※注|
|pecoでコマンド履歴検索|以前に実行したコマンド履歴を、 `peco` で検索して呼び出す。|`Ctrl+x` -> `r` ※注|
|pecoでGitブランチ検索|Gitブランチを `peco` で検索して切り替える。|`Ctrl+x` -> `Ctrl+b` ※注|
|pecoでGit作業コピーを検索| `ghq` でクローンしたGit作業コピーを、 `peco` で検索して移動する。|`Ctrl+x` -> `g` ※注|

* 注）自分は普段 **Emacs** を使っているので Emacs風のキーバインドにしていますが、任意のキーバインドを割り当て可能です。

# 手順

## zshのインストール

今の OS X（Mac前提です...mm）はデフォルトのシェルが **zsh** になってるので問題ないですね（笑）

## zinitのインストール

[公式のインストールガイド](https://github.com/zdharma/zinit#option-1---automatic-installation-recommended) に従ってインストールします。

```sh
$ sh -c "$(curl -fsSL https://raw.githubusercontent.com/zdharma/zinit/master/doc/install.sh)"
```

*~/.zshrc* に **zinit** の設定が追記されるのでリロードし、 **zinit** 自身を最新化します。

```sh
$ source ~/.zshrc
$ zinit self-update
```

これでインストール自体は完了です。

## zinitのカスタマイズ

続いて *~/.zshrc* を **zinit** の機能を使ってカスタマイズしていきます。

前述の手順で *~/.zshrc* に↓のような設定が追加されているので、それより下に追記していきます。
必要に応じて [公式の.zshrcサンプル](https://github.com/zdharma/zinit#example-usage) を見たり、 `zinit` やら `snippet` やら `light` やらの詳細は [zinitの解説](http://zdharma.org/zinit/wiki/INTRODUCTION/) を参照してください。

```sh:~/.zshrc
### Added by Zinit's installer
  :
  略
  :
### End of Zinit's installer chunk

これ以降に設定を追記していく
```

*~/.zshrc* を編集・保存してリロードすると、自動的に必要なリソースがダウンロードされてセットアップされます。


### Preztoのセットアップ

以前に **Prezto** を使っていて慣れているのもあるので、今回も **zinit** から **Prezto** を使えるようにします。

```sh:~/.zshrc
# Preztoのセットアップ
zinit snippet PZT::modules/helper/init.zsh
```

### oh-my-zshのセットアップと、プロンプトのカスタマイズ

**oh-my-zsh** は使ってなかったのですが、 **zinit** のプロンプトのカスタマイズは [oh-my-zshのテーマを使う](https://github.com/zdharma/zinit#using-oh-my-zsh-themes) ようなので、こっちも設定します。

```sh:~/.zshrc
# oh-my-zshのセットアップ
zinit snippet OMZL::git.zsh
zinit snippet OMZP::git # <- なんかおまじないらしい
zinit cdclear -q

# プロンプトのカスタマイズ
setopt promptsubst
zinit snippet OMZT::gnzh
zinit light agnoster/agnoster-zsh-theme # <- ここで好きなテーマのGitHubリポジトリを Group/Repository で指定。
```

### プラグインのセットアップ

プラグインは基本的に `zinit light [プラグインのGitHubリポジトリの Group/Repository]` と書くだけで使えます。便利ー

#### 一般的なプラグイン

ぜったいに使うようなプラグインをセットアップします。

```sh:~/.zshrc
# 補完
zinit light zsh-users/zsh-autosuggestions

# シンタックスハイライト
zinit light zdharma/fast-syntax-highlighting

# Ctrl+r でコマンド履歴を検索
zinit light zdharma/history-search-multi-word
```

#### お好みのプラグイン

あとは前出の [awesome-zsh-plugins](https://project-awesome.org/unixorn/awesome-zsh-plugins) あたりから使いたいプラグインを探してセットアップしていきます。

```sh:~/.zshrc
# クローンしたGit作業ディレクトリで、コマンド `git open` を実行するとブラウザでGitHubが開く
zinit light paulirish/git-open

# iTerm2を使っている場合に、コマンド `tt タブ名` でタブ名を変更できる
zinit light gimbo/iterm2-tabs.zsh

# jq をインタラクティブに使える。JSONを標準出力に出すコマンドを入力した状態で `Alt+j` すると jq のクエリが書ける。
# 要 jq
zinit light reegnz/jq-zsh-plugin

# Gitの変更状態がわかる ls。ls の代わりにコマンド `k` を実行するだけ。
zinit light supercrabtree/k

# AWS CLI v2の補完。
# 要 AWS CLI v2
# この順序で記述しないと `complete:13: command not found: compdef` のようなエラーになるので注意
autoload bashcompinit && bashcompinit
source ~/.zinit/plugins/drgr33n---oh-my-zsh_aws2-plugin/aws2_zsh_completer.sh
complete -C '/usr/local/bin/aws_completer' aws
zinit light drgr33n/oh-my-zsh_aws2-plugin
```

### anyframeのセットアップ

自分の場合はこれに加えて `peco` を便利に使えるようにしてくれる [anyframe](https://github.com/mollifier/anyframe) も使います。

```sh:~/.zshrc
# anyframeのセットアップ
zinit light mollifier/anyframe

# Ctrl+x -> b
# peco でディレクトリの移動履歴を表示
bindkey '^xb' anyframe-widget-cdr
autoload -Uz chpwd_recent_dirs cdr add-zsh-hook
add-zsh-hook chpwd chpwd_recent_dirs

# Ctrl+x -> r
# peco でコマンドの実行履歴を表示
bindkey '^xr' anyframe-widget-execute-history

# Ctrl+x -> Ctrl+b
# peco でGitブランチを表示して切替え
bindkey '^x^b' anyframe-widget-checkout-git-branch

# Ctrl+x -> g
# GHQでクローンしたGitリポジトリを表示
bindkey '^xg' anyframe-widget-cd-ghq-repository
```

### その他

あとはお好みで、いつもどおり環境変数をセットしたり、エイリアスを切ったりしていくだけです。

### 完全な例

```sh:~/.zshrc

### Added by Zinit's installer
if [[ ! -f $HOME/.zinit/bin/zinit.zsh ]]; then
    print -P "%F{33}▓▒░ %F{220}Installing %F{33}DHARMA%F{220} Initiative Plugin Manager (%F{33}zdharma/zinit%F{220})…%f"
    command mkdir -p "$HOME/.zinit" && command chmod g-rwX "$HOME/.zinit"
    command git clone https://github.com/zdharma/zinit "$HOME/.zinit/bin" && \
        print -P "%F{33}▓▒░ %F{34}Installation successful.%f%b" || \
        print -P "%F{160}▓▒░ The clone has failed.%f%b"
fi

source "$HOME/.zinit/bin/zinit.zsh"
autoload -Uz _zinit
(( ${+_comps} )) && _comps[zinit]=_zinit

# Load a few important annexes, without Turbo
# (this is currently required for annexes)
zinit light-mode for \
    zinit-zsh/z-a-patch-dl \
    zinit-zsh/z-a-as-monitor \
    zinit-zsh/z-a-bin-gem-node

### End of Zinit's installer chunk

zinit snippet PZT::modules/helper/init.zsh

zinit snippet OMZL::git.zsh
zinit snippet OMZP::git
zinit cdclear -q
setopt promptsubst
zinit snippet OMZT::gnzh
zinit light agnoster/agnoster-zsh-theme


zinit light zsh-users/zsh-autosuggestions
zinit light zdharma/fast-syntax-highlighting
zinit light zdharma/history-search-multi-word

zinit light paulirish/git-open
zinit light gimbo/iterm2-tabs.zsh
zinit light reegnz/jq-zsh-plugin
zinit light supercrabtree/k

autoload bashcompinit && bashcompinit
source ~/.zinit/plugins/drgr33n---oh-my-zsh_aws2-plugin/aws2_zsh_completer.sh
complete -C '/usr/local/bin/aws_completer' aws
zinit light drgr33n/oh-my-zsh_aws2-plugin


zinit light mollifier/anyframe

bindkey '^xb' anyframe-widget-cdr
autoload -Uz chpwd_recent_dirs cdr add-zsh-hook
add-zsh-hook chpwd chpwd_recent_dirs

bindkey '^xr' anyframe-widget-execute-history
bindkey '^x^b' anyframe-widget-checkout-git-branch
bindkey '^xg' anyframe-widget-cd-ghq-repository
```

# おわり

まだまだ **zinit** を使いこなせてませんが、ひとまず最低限のことはできるようになりました。

以上です。