zsh で使う plugin manager を sheldon に移行

Linux
この記事は約10分で読めます。

はじめに

 Linux で愛用している shell は zsh。あれこれと便利な plugin をインストールしておけばディレクトリ移動や history search がもの凄く捗るしミスも減る
 ここ最近までは plugin manager として zplug を使用してきたが、自分の使い方だと fzf という plugin 更新後に zplug がエラーを吐いて 30 秒位待たなければいけない状態が続いていた。
 そんな折に sheldon という plugin manager の事を知り、速度が速いというクチコミも相まって移行することにした。

Introduction - sheldon docs

sheldon のインストール

 インストールや設定に関しては基本的にドキュメントに目を通せば全部出来る。
 うちは CentOS 7 がメインなので取り敢えずこれでインストールした。

curl --proto '=https' -fLsS https://rossmacarthur.github.io/install/crate.sh \
    | bash -s -- --repo rossmacarthur/sheldon --to ~/.local/bin

 次のコマンドを打ち込んで初期設定を行う。

sheldon init --shell zsh

 すると ~/.config/sheldon/plugins.toml に設定ファイルが生成されるので、これを直接編集することで使用する plugin を記述及び設定していく事にした。
 その他 sheldon ではコマンドラインから plugin の追加/削除/編集も出来るようだ。

設定ファイルを弄る

 基本的に使用したい plugin は github に転がっているのでドキュメント通りに追記してく感じだった。

[plugins]
[plugins.zsh-defer]
github = 'romkatv/zsh-defer'
apply = ['source']

 使用する plugin は [plugins] 以下のエントリーに書いていく。
 上記設定の場合、github の romkatv さんが公開している zsh-defer のリポジトリーを clone し、デフォルトで match するファイル *.zsh を source コマンドに引き渡してあげるという意味になる。

 sheldon がデフォルトでプラグインであるスクリプトと認識する為の match フィルターは次の通り。
 {{ name }} には [plugins.hogehoge] でエントリーしているのなら hogehoge が入る。

match = [
    "{{ name }}.plugin.zsh",
    "{{ name }}.zsh",
    "{{ name }}.sh",
    "{{ name }}.zsh-theme",
    "*.plugin.zsh",
    "*.zsh",
    "*.sh",
    "*.zsh-theme"
]

 apply で指定された source というのはコマンド名ではなく、デフォルトで用意されている template を差す
 また、apply = ['source'] は書かずともデフォルトの動作なので省略可。

細かい制御は template で

 そして問題の plugin は fzf というもの。
 zplug の時はこれ clone してきた後に pre-build で install コマンドを叩いてた訳だが、sheldon ではどの様に実現するものなのかなと。

 ちなみに zplug ではこのように記述していた。

zplug "junegunn/fzf", \
    from:github, \
    as:command, \
    use:bin/fzf, \
    hook-build:"$ZPLUG_HOME/repos/junegunn/fzf/install --all"

 ググっても情報がなかったので、ひたすらドキュメントに目を通したら template を使用すればどうとでもなると分かった。

 よって template を用いたゴリ押しを。

[plugins.fzf]
github = "junegunn/fzf"
apply = ['fzf-install', 'fzf-source']

[templates]
fzf-install = "{{ dir }}/install --bin > /dev/null \n[[ ! $PATH =~ {{ dir }} ]] && export PATH=\"$PATH:{{ dir }}/bin\"\n"
fzf-source = "{% for file in files %}source \"{{ file }}\"\n{% endfor %}"

 動作としては junegunn さんが公開している fzf のリポジトリーをクローンし、今回作成した fzf-install と fzf-source の template を適用するという事となる。
 各 template の中身はぶっちゃけシェルであり、sheldon から与えられるディレクトリ名、ファイル名をよしなに扱って実行する事が出来るというお話しだ。

 各変数は {{}} で囲われたもので今回は 3 つ使用している。

  • dir = clone してきたリポジトリーの root ディレクトリが絶対パスで入る。
  • files = スクリプトファイル名に match したファイル名が絶対パスで入っているリスト。
  • file = files を元にした for ループの中で単一のファイル名がセットされる。

template の動作概要

 fzf-install と名付けた template では clone してきたリポジトリー以下にある install というシェルスクリプトを実行する。
 install スクリプトは bin/ 以下に fzf のバイナリーが存在しなければスクリプト内 5 行目で設定されているバージョンのバイナリをダウンロードしてくるので、同時に PATH も通しましょうって動作にした。

 zsh が起動する度に install スクリプトが呼び出される動作になるが、中身を確認したところ、バージョンチェックが行われた後にダウンロード処理にうつっていた。
 よって無駄な通信が起こらない。
 毎回メッセージが吐かれるのもアレだから stdout は捨てている。

 fzf-source と名付けた template では fzf 実行に必要なファイルである completion.zshkey-bindings.zsh の 2 ファイルを source コマンドに与える役目をさせた。
 要は普通にインストールしたときに .fzf.zsh を実行して有効化するという処理と同じ事をここでしている。

設定ファイルの完成

 設定を終えたら .zshrc 内の任意の位置に eval "$(sheldon source)" と書いておけば設定したプラグインがインストールされてアクティブになる。

 今回完成した設定ファイルは次の通り。

shell = "zsh"

[plugins]
[plugins.zsh-defer]
github = 'romkatv/zsh-defer'
apply = ['source']

[plugins.zsh-syntax-highlighting]
github = 'zsh-users/zsh-syntax-highlighting'
apply = ['defer']

[plugins.enhancd]
github = 'b4b4r07/enhancd'

[plugins.fzf]
github = "junegunn/fzf"
apply = ['fzf-install', 'fzf-source']

[templates]
PATH = 'export PATH="$PATH:{{ dir }}"'
defer = "{% for file in files %}zsh-defer source \"{{ file }}\"\n{% endfor %}"
fzf-install = "{{ dir }}/install --bin > /dev/null \n[[ ! $PATH =~ {{ dir }} ]] && export PATH=\"$PATH:{{ dir }}/bin\"\n"
fzf-source = "{% for file in files %}source \"{{ file }}\"\n{% endfor %}"

 plugin manager を移行したことにより、その他細かい設定も .zshrc の中で修正する必要があったけど非常に良好な結果が得られたので良かった。

plugin 更新チェック

 sheldon では次のように実行してあげることで導入している plugin の更新チェックをしてくれる。
 もちろん更新があれば github ソースの場合、git pull してきてくれる。

% sheldon lock --update
Loaded ~/.config/sheldon/plugins.toml
   Checked https://github.com/b4b4r07/enhancd
   Checked https://github.com/romkatv/zsh-defer
   Checked https://github.com/junegunn/fzf
   Checked https://github.com/zsh-users/zsh-syntax-highlighting
Locked ~/.local/share/sheldon/plugins.lock

 このとき個別で特別な処理をするようにした fzf の更新があったなら、バイナリの更新も行う必要があるので source ~/.zshrc として再度 sheldon を呼び出せば良い。

 Github に置いた最新の内容は以下のリンクに。

https://github.com/buccimoni/dotfiles/blob/master/.config/sheldon/plugins.toml

ベンチマーク

 言葉で「速い」というよりも数値で見た方が良いなぁ…… ということで、zplug と sheldon でそれぞれ .zshrc を読み込ませるベンチマークを行った。
 使用したツールは hyperfine という便利なもの。

 結果はこう。

% hyperfine --warmup 3 --shell=zsh 'source ~/.zshrc.zplug'
Benchmark 1: source ~/.zshrc.zplug
  Time (mean ± σ):     550.3 ms ±  18.5 ms    [User: 312.6 ms, System: 290.7 ms]
  Range (min … max):   501.4 ms … 569.4 ms    10 runs
 
% hyperfine --warmup 3 --shell=zsh 'source ~/.zshrc.sheldon'
Benchmark 1: source ~/.zshrc.sheldon
  Time (mean ± σ):      61.1 ms ±  19.2 ms    [User: 42.5 ms, System: 18.9 ms]
  Range (min … max):    38.7 ms …  99.6 ms    33 runs

 zplug を使用しているときの平均実行時間 550.3ms
 sheldon を使用した時の平均実行時間 61.1ms

 あくまで筆者環境の場合による物だが、およそ 9 倍速い。
 よって体感出来る位の速度差があるので気持ちが良い。

著者プロフィール
ぶっち

本格的に PC へ触れ始めてたのは 1990 年位から。
興味は PC 全般。OS は Windows と Linux などを嗜む。
プログラマやネットワークエンジニアを経てフリーに活動している 2 児の父な 40 代半ばのおじさんです。

ぶっちをフォローする
ぶっちろぐ

コメント

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.