🚀

vim-jetpackでサクサクなvimを目指す

2022/12/07に公開

vim-jetpack 2022

vim-jetpack とは 私が今年の2月から開発を初めたVim/ Neovim用のプラグインマネージャです。ありがたいことに登場初期から多くのVimmerに注目していただいため、開発から1年も経っていませんが、沢山の開発者からフィードバックやパッチの貢献を貰い、他のプラグインマネージャに比肩するプラグインマネージャにまで成長しました。本記事では、vim-jetpackの初期からの変更差分と今後について書きます。

登場背景

昨今最も人気のVimのプラグインマネージャといえば2013年に登場したvim-plugであるということは、誰もが認めるところだと思います。使いやすいインターフェースを持ち、コンパクトな構成で十分なカスタマイズ性をもつ優れたプラグインマネージャです。その導入の容易さから 10年間不動の地位を築いています。

2013年から開発されたvim-plug には、後方互換性とクロスプラットフォームな動作を保証するために、3000行(コメント含む)のVim script (一部Python) で実装されています。ところで2016年にはVim 8/ Neovim自体にプラグイン管理機構 packages が実装されました。後方互換性を多少犠牲にすることで、そのコードの大部分を、packagesによって代替することが可能です。その背景から生み出されたのが vim-jetpackです。

vim-jetpackは vim-plugの後継を目標に2022年2月に開発をスタートしました。vim-plugのインターフェースをそのままに2016年に登場した Vim8/Neovimの packages 機能で同様の機能を再現し、高速化することが目的でした。

問題意識

Vimのプラグインマネージャとして、vim-plugを除いて有名なプラグインマネージャにpacker.nvim と dein.vim があります。これらは、高速に起動するために、内部で沢山の最適化を施し、遅延読み込みのための多くの設定項目を提供しています。vim-plugから更なるカスタマイズ性を求めて移行するケースが良くあります。

しかし、移行に際して問題になるのが、設定項目が多すぎて結局、プラグインを列挙するだけで大した遅延読み込みを設定しないため、むしろ vim-plug よりも使い勝手が悪くなるといったことやもしくは、設定項目を細かく設定しすぎて、他のプラグインマネージャに移行できず、ロックインされてしまうといったことがあげられます。

vim-jetpackでは、このような問題を解決するために、必要以上のカスタマイズ性は提供しないかわりに、高速に動作するためのベストプラクティスを採用する設計を採用しています。つまり 適当に書いても、安定してそこそこ高速に動作します。 そして、カスタマイズできない分、vim-jetpackにロックインされるような独自機能は追加しません。

特徴

  • 起動速度: インストール済みのプラグインに対して最適化を施し、起動を大幅に高速化させます。 後述のベンチマークを参照してください。
  • 可搬性: vim-plug 同様、単一のファイルで構成されています。 jetpack.vim ファイルをダウンロードさえすれば動きます。
  • 依存性: プラグインのダウンロードに使用するプログラムを選ぶことができます。 たとえば、git がインストールされていない環境でもcurl / wget のみで動作します。
  • 記法: インストールするプラグインの宣言方法を複数採用しています。 Lua/Vimどちらの言語で設定ファイルを書いても、相応しい記法を用いることができます。

更新情報

開発当初からインターフェース(UI)の変更はありません。しかし、速度や依存するソフトウェアの削減などのUXでは大きな更新が沢山ありました。
使い方等は、2022年2月の記事を参照してください。

とても速いVimプラグインマネージャvim-jetpack

起動速度を改善した

vim-plug は当初高速なプラグインマネージャとして導入されました。しかし、その開発はメンテナンスフェーズとなり実験的な最適化手法は採用されなくなり、vim-plugよりも高速なプラグインマネージャが多数登場しました。とくにテクニカルブレークスルーとなったのが dein.vim によるruntimepathのマージ機能です。

Vim の起動時間では外部コマンドの起動やファイルI/ Oが問題になります。この問題に取り組んだパイオニアが dein.vimです。

従来のプラグインマネージャではプラグインごとにディレクトリを分け、プラグインの読み込みの度に、管理化にある全てのディレクトリを順々に走査する方法が採用されていました。この方法では、プラグインが増加する度に、その走査に関する最悪計算量が線形オーダーになります。

マージ機能を採用した dein.vim では、プラグイン同士のディレクトリを併合し一つのディレクトリで管理します。これにより走査するディレクトリを最小限に抑え、理想的には最悪計算量を 1 にまで削減させることができます。

vim-jetpack では vim-plugのインターフェースを維持しつつ、裏でこの最適化手法を採用しました。以下は、適当なプラグイン100個をインストールしたVimの起動時間を100回計測したときの統計情報です。

vim-plugは起動時間にムラがあり平均起動時間が150msほど遅いです。一方で vim-jetpackの起動時間は、ほぼ常にvim-plugの平均より100msから200ms程高速に起動しています。この実験ではプラグインの指定しかしておらず、ほかのプラグイン固有の設定などはおこなっていません。

パスの走査時間が削減されているため、autoloadに定義してある関数の呼びだしなどの固有の設定をした場合の実測値は、この結果よりもさらに高速に起動することが見込まれます。

単一ファイルでインストールできるようになった

vim-plug の素晴らしい点に、その実装が 2800行の単一ファイルのみで構成されている点があります。とりあえず、ファイルをダウンロードし、適当な場所に設置すれば、直ちに vim-plugを使い始めることができます。

この方法を採用しているプラグインマネージャは少なく、多くのプラグインマネージャでは、メンテナンス性やautoloadによる遅延化のために複数ディレクトリ複数ファイルの構成で開発されています。この方法はムダなファイル読み込みを減らせて、モジュール化ができる等のメリットがある一方で、プラグインマネージャをインストールするために、特定のワークアラウンドが必要であったり、専用のインストールスクリプトを実行する必要がありました。

vim-jetpackは、vim-plugと比較して30%程度 (800行) までコード行数を減らすことで、読み込みに必要な時間を短縮させつつ、単一のファイルでインストールすることを達成しました。

クロスプラットフォームで動くことを保証した

vim-jetpackは Neovim/Vim のどちらでも動作することを保証しています。さらにLinux/macOS/Windows の全てのOS上でCIを実行し、同じクオリティで使用できることを検証しています。さらに全ての設定項目の組み合せもテストしており、どの組み合せでも期待通り動作する、あたりまえ を実現しています。

新機能: 依存するソフトウェアを減らした

現在広く使われている プラグインマネージャの多くは、gitのインストールを前提にしています。しかし、gitがインストールされていないが、vimがインストールされている環境も相当数存在します。

サーバー環境では設定ファイルを編集するためのvimがインストールされていても、開発に必要なgitはインストールされないというのは、十分にありうるシチュエーションです。

また、僕はiPadでVimを使いたいとき iVimという Vimを使います。このiVimでは、もちろん gitを使用することができません。

vim-jetpackでは、gitを前提としないよう、プラグインのダウンロード処理を抽象化し、curl/wget のみでも動作するよう、設定オプション g:jetpack_download_method を追加しました。

記法の互換性が向上した

もともと vim-plugをベースにしたプラグインマネージャであったため、dein.vim / packer.nvim 向けの記法でもオプション名は vim-plugと共通のオプション名を採用していました。しかし、最近の更新でエイリアスとして dein.vim / packer.nvim のオプション名を使えるようにしました。また、素晴らしい貢献者の協力によって packer.nvimとの互換性が強化され、とくに config フックが vim-jetpackでも使用できるようになりました。

ちなみに、最近packer.nvimでは次期バージョンの開発がスタートしており、記法や機能が大幅に変更されることが見込まれています。詳細は packer.nvim の main ブランチで確認できます。packer.nvim のような、カスタマイズ性の高いプラグインマネージャでの大規模な変更によって、設定ファイルを大きく書き直す必要がでてくるかもしれません。

vim-jetpackは、vim-plug/ dein.vim/ packer.nvim との互換性維持を強化していく予定です。もし vim-jetpackに大きな変更が入った場合でも、他のプラグインマネージャに戻ることは容易になっています。

今後について

vim-jetpack は着実に進化を続けます。主な変更は互換性の向上と速度の向上です。速度を犠牲にせず互換性を上げる。独自の新機能は追加しないつもりです。 ただ高速に起動する その一点にしぼっていろいろな実験をしていきます。そして、packer.nvim がメジャーアップデートを控える中、互換性を向上させることでvimのライト/ミドルユーザが使い易いプラグインマネージャを目指します。今後ともvim-jetpackをよろしくお願いします!

謝辞

この記事の公開にあたりvim-jpのみなさんから、多くのフィードバックをもらいました。
稚拙な文章力のなか辛抱強く読み、フィードバックをくださった諸氏に感謝申し上げます。
また vim-jetpack 本体に対して、Issue/ Pull Resuest を起票してくださった貢献者のみなさまに感謝いたします。

GitHubで編集を提案

Discussion