@ryoppippi

Vim/Neovimのプラグインマネージャーを悪用してCLIの管理ツールとして使う

15 Oct 2023 ・ 12 min read


Note

この​記事はVim 駅伝の​ 10/16 の​記事です。

TL;DR

  • CLI ツールを​管理する​方​法と​して、​Vim/Neovimの​プラグインマネージャーを​使うと​意外と​便利

はじめに

皆さんは​CLI ツールを​どのように​管理していますか?

私は​macOSで​使う​ツールの​管理に​以下の​パッケージマネージャーたちを​使っています。

  • 汎用的な​パッケージマネージャー
    • aqua - YAMLで​Declarativeに​ツールを​管理できる。​極力​これで​管理したい
    • Homebrew - 有名な​パッケージマネージャー。​macOSの​デファクトスタンダード。​Aquaで​管理できない​ツールを​管理する
  • 言語ごとの​パッケージマネージャー
    • volta - Node.jsの​バージョン管理ツール。​Node.jsの​バージョンを​切り​替えるのに​使う
    • rye - Pythonの​バージョン管理ツール。​Pythonの​バージョン/仮想環境/ツールを​管理するのに​使う
    • rustup - Rustの​管理ツール。​Rustの​バージョン/ツールを​管理するのに​使う
    • zigup - Zigの​バージョン管理ツール。​Zigの​バージョンを​切り​替えるのに​使う
  • ツールごとの​パッケージマネージャー
    • fisher - fishの​プラグインマネージャー。​fishの​プラグインを​管理するのに​使う
    • lazy.nvim - Neovimの​プラグインマネージャー。​Neovimの​プラグインを​管理するのに​使う

結構​多いですね。 ツールは​多岐に​わたるので、​それぞれの​ツールに​合った​パッケージマネージャーを​使っています。

理想の​パッケージマネージャー

私は​複数マシンを​使っているので、​マシン間の​設定を​dotfilesと​して​管理しています。

https://github.com/ryoppippi/dotfiles

自分が​dotfilesで​使用する​パッケージマネージャーに​求める​条件は​以下の​通りです。

  • パッケージマネージャーの​インストール、​アンインストールが​簡単
  • パッケージマネージャーの​設定を​Declarativeに​記述できる
  • パッケージマネージャがー管理する​ツールの​設定や​バージョンを​Declarativeに​記述できる
  • Lockfileで​バージ​ョン、​差分を​管理できる
  • パッケージマネージャーが​管理する​ツールの​バージョンを​切り​替える​ことができる​/簡単に​戻すことができる
  • 設定量は​多過ぎず​少な​過ぎず
  • 暗黙の​動作が​少ない

これらを​満たしていると、​Github上で​差分も​簡単に​確認でき、​また​マシン間でも​git pullして​簡単な​コマンドを​打つだけで​環境を​再現できるので、​とても​便利です。

Aqua

これらを​条件を​考えた​時に、​汎用の​パッケージマネージャーに​おいては、​Aquaが​一番条件を​満たしていると​思います。

https://aquaproj.github.io/

Aquaは​YAMLで​Declarativeに​ツールを​管理でき、​また​Renovateを​併用すれば​最新版の​確認、​更新も​簡単に​できます。 また、​設定も​プリセットの​ものが​多く、もし欲しい​ツールが​なかった​場合も​本家の​Registryに​Pull Requestを​送る​ことで​追加できます。 その​ため、​自分の​使用する​CLI ツールは​極力Aquaで​管理したいと​思っています。

しかし、​Aquaは​Go言語以外の​ビルドを​サポートしていないので、​Go言語以外で​書かれていて​尚且つバイナリが​提供されていない​ツールを​管理する​ことができません。 また、​特定の​場所に​インストールが​必要な​もの​(gh extension)も​管理できません。

追記: Cargoに​よる​Installにも​対応しているようです!

afx

自分は​使用していないのですが、​afxと​いう​パッケージマネージャーも​あります。

https://github.com/babarot/afx

この​パッケージマネージャーは​Aquaと​同じく​YAMLで​Declarativeに​ツールを​管理できます。 Aquaのような​Registryは​存在しないので、​自分で​ビルドスクリプトを​書く​必要が​ありますが、​その​分ビルドスクリプトを​定義したり、​gh extensionを​管理したりと、​より​柔軟な​管理が​できます。 とても​魅力的な​パッケージマネージャーですが、​以下の​理由で​自分は​使用していません。

  • 更新時、​Releaseに​ある​ものは​最新版を​チェックして​落と​すことができるが、​例えば​main ブランチの​HEADを​落と​してきてビルドするような​ことは​できない
  • Lockfileを​採用していないので、​ツールの​バージョン一覧を​1箇所で​確認する​ことができない
  • (これは​Aquaも​同じであるが​) YAMLで​設定を​記述するので、​設定量が​多いと​YAMLの​記述が​煩雑に​なる
  • (これは​afxは​何も​悪くないのですが)​これ以上​パッケージマネージャーを​増や​したくない

とても​良い​パッケージマネージャーでは​あるので、​ぜひ皆さん​チェックしてみてください。

解: lazy.nvimを​悪用する

と​いうわけで、​自分が​求める​条件を​満たすパッケージマネージャーが​なかなか​見つかりません。

これは​自分で​作る​しかないのかなと​思いつつ、​なかなか​手が​つけられない​中数ヶ月が​経ちました。

そんな​中、​先日の​駅伝で​slinさんが​vim/neovimの​パッケージマネージャーであるdeinを​悪用して、​IMEの​辞書を​管理する​方​法を​紹介していました。

https://github.com/Shougo/dein.vim

https://zenn.dev/slin/articles/2023-10-02-skktips#辞書を​deinで​管理する

また​これに​ついて楽園で​盛り​上がっていた​ところ、​CLI ツールを​管理するのにも​使えるんじゃないかと​いう​話に​なりました。

これに​ついて​考えてみると、​vim/neovimの​パッケージマネージャー、​特に​自分の​使っている​lazy.nvimは​以下のような​特徴が​あります。

  • パッケージマネージャーの​インストール、​アンインストールが​簡単 → vimの​設定の​一部なのですでに​ある
  • パッケージマネージャーの​設定を​Declarativeに​記述できる​ → lua で​記述できる
  • パッケージマネージャーが​管理する​ツールの​設定や​バージョンを​Declarativeに​記述できる​ → lua で​記述できる
  • Lockfileで​バージ​ョン、​差分を​管理できる​ → lazy-lock.jsonが​生成されるので、​差分が​取れる
  • 設定量は​多過ぎず​少な​過ぎず → お作法に​乗っ取れば、​設定量は​少ない。​独自の​ビルドの​設定も​記述できる

https://github.com/folke/lazy.nvim

と​いうわけで、​1から​パッケージマネージャーを​作るよりも、​vim/neovimの​パッケージマネージャーを​悪用する​方が​簡単そうだなと​思い、​実際に​設定を​書いてみました。

以下に​自分が​Aqua/Homebrew管理外だった​ツールを​いかに​して​管理したかを​書いていきます(da-ja-re)。

gh extensionの​管理

gh extensionは、​ghコマンドの​拡張機能です。 自分も​いく​つか​愛用している​ものが​あります。

https://github.com/ryoppippi/gh-cr https://github.com/yusukebe/gh-markdown-preview https://github.com/actions/gh-actions-cache https://github.com/seachicken/gh-poi

これらの​コマンドは​ghコマンドと​一緒に​使う​ことで、​githubに​まつわる​便利な​機能を​提供してくれます。 しかし、​これらの​ツールを​管理する​ツールは​(現時点では​afxを​のぞいて)​存在しません。

これを​lazy.nvimで​管理してみましょう。

https://github.com/ryoppippi/dotfiles/blob/9c94e60236511be2f9cdd87d90cd2cbb21fffdbc/nvim/lua/cli/gh.lua

この​設定ファイルの​中で​やっている​ことは​以下の​通りです。

  • 指定した​レポジトリの​最新版を​落と​してくる
  • go build する
  • ビルドされた​バイナリを​gh extensionの​ディレクトリ(macOSでは~/.local/share/gh/extensions/)に​配置する

これで、​gh extensionを​lazy.nvimで​管理する​ことができました。

新しい​gh extensionを​追加したい​場合は、​この​設定ファイルに​追記するだけで、lazy.nvimの​アップデートを​すると、​自動的に​最新版が​落とされます。 別の​マシンを​使う​時にも、​dotfilesを​pullして​Neovimを​起動するだけで、​最新版の​gh extensionが​自動的に​インストールされます。

lazy-lock.jsonに​バージ​ョンが​記述されるので、​差分も​確認できて​嬉しいですね。

https://github.com/ryoppippi/dotfiles/blob/9c94e60236511be2f9cdd87d90cd2cbb21fffdbc/nvim/lazy-lock.json#L51-L56

追記: gh extension install .で​ローカルの​レポジトリを​インストールできる​ことを​知り、​設定を​簡素化しました。 https://github.com/ryoppippi/dotfiles/blob/b0a7e71f797259847106786a1fce7eefef4b18b3/nvim/lua/cli/gh.lua

zlsの​管理

zlsは​zigの​Language Serverです。 https://github.com/zigtools/zls

自分は​zigの​HEADを​使っているので、​zlsを​使用するには​masterを​cloneして​最新版の​zigで​ビルドする​必要が​あります。

今までは​毎日​手動で​zlsから​git pull、​ビルドしていましたが、​これも​lazy.nvimで​管理する​ことにしました。

https://github.com/ryoppippi/dotfiles/blob/9c94e60236511be2f9cdd87d90cd2cbb21fffdbc/nvim/lua/cli/zls.lua

これも​やっている​ことは​簡単で、​lazy.nvimで​アップデートを​すると、​zlsの​レポジトリを​git pullして​勝手に​ビルドしてくれます。 あとは​ビルドされた​バイナリを​nvim-lspconfigで​指定するだけで、​zlsを​使うことができます。

https://github.com/ryoppippi/dotfiles/blob/9c94e60236511be2f9cdd87d90cd2cbb21fffdbc/nvim/lua/plugin/nvim-lspconfig/init.lua#L359-L364

これで、​zlsを​lazy.nvimで​管理する​ことができました。

https://github.com/ryoppippi/dotfiles/blob/9c94e60236511be2f9cdd87d90cd2cbb21fffdbc/nvim/lazy-lock.json#L214

まとめ

この​記事では、​vim/neovimの​プラグインマネージャーを​悪用して​CLI ツールを​管理する​方​法、​そして​lazy.nvimを​使用した​具体的な​設定を​紹介しました。 推奨されている​方​法ではないので、​自己責任で​お願いします。

これまで、​Vimは​エディタと​して、​単なる​便利な​CLI ツールの​一つでしか​ありませんでした。 しかし、​他の​CLI ツールの​管理を​したり、​また​Gitを​拡張する​ツールと​して​Vim​使ったりしていると、​Vimが​Terminalの​環境を​全て​飲み込んでいくような、​そんな​感覚に​なります。

/blog/2023-08-16-zenn-3b5125f9e06bf9-ja

これからも​Vim/Neovimと​仲良くしていきたいですね。

comment on bluesky / twitter
CC BY-NC-SA 4.0 2022-PRESENT © ryoppippi