--- title: "Vim/Neovimのプラグインマネージャーを悪用してCLIの管理ツールとして使う" date: '2023-10-15' isPublished: true lang: 'ja' --- > [!NOTE] > この記事は[Vim 駅伝](https://vim-jp.org/ekiden/)の 10/16 の記事です。 # TL;DR - CLI ツールを管理する方法として、Vim/Neovimのプラグインマネージャーを使うと意外と便利 # はじめに 皆さんはCLI ツールをどのように管理していますか? 私はmacOSで使うツールの管理に以下のパッケージマネージャーたちを使っています。 - 汎用的なパッケージマネージャー - [aqua](https://aquaproj.github.io/) - YAMLでDeclarativeにツールを管理できる。極力これで管理したい - [Homebrew](https://brew.sh/) - 有名なパッケージマネージャー。macOSのデファクトスタンダード。Aquaで管理できないツールを管理する - 言語ごとのパッケージマネージャー - [volta](https://volta.sh/) - Node.jsのバージョン管理ツール。Node.jsのバージョンを切り替えるのに使う - [rye](https://rye-up.com/) - Pythonのバージョン管理ツール。Pythonのバージョン/仮想環境/ツールを管理するのに使う - [rustup](https://rustup.rs/) - Rustの管理ツール。Rustのバージョン/ツールを管理するのに使う - [zigup](https://github.com/marler8997/zigup) - Zigのバージョン管理ツール。Zigのバージョンを切り替えるのに使う - ツールごとのパッケージマネージャー - [fisher](https://github.com/jorgebucaran/fisher) - fishのプラグインマネージャー。fishのプラグインを管理するのに使う - [lazy.nvim](https://github.com/folke/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](https://cli.github.com/manual/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](https://github.com/Shougo/dein.vim)を悪用して、IMEの辞書を管理する方法を紹介していました。 https://github.com/Shougo/dein.vim https://zenn.dev/slin/articles/2023-10-02-skktips#%E8%BE%9E%E6%9B%B8%E3%82%92dein%E3%81%A7%E7%AE%A1%E7%90%86%E3%81%99%E3%82%8B またこれについて[楽園](https://vim-jp.org/docs/chat.html)で盛り上がっていたところ、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](https://cli.github.com/manual/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と仲良くしていきたいですね。