LoginSignup
72
37

More than 5 years have passed since last update.

Vim 8.0用のプラグインマネージャを作ってみた話

Last updated at Posted at 2017-02-20

概要

Vim 8.0 では、Vim 本体にプラグイン/パッケージを扱うための機能が追加され、さらに外部プロセスを実行して非同期に通信を行う、ジョブ・チャンネル機能が追加されました。
今回、これらの機能を活用した Vim 8.0(およびNeovim)用のプラグインマネージャを作ってみました。

プラグインマネージャの歴史

本題に入る前に、Vim のプラグインマネージャの歴史を軽くおさらいしてみましょう。(以下の分類は、私による勝手な分類です。)

第 1 世代

Vim には、VimballGetLatestVimScripts という標準プラグインが付属しており、これを使えば対応プラグインを簡単にインストールしたり、更新することができました。
しかし、これらに対応していないプラグインの管理は困難でした。'runtimepath' の管理は手動だったため、すべてのプラグインを単一ディレクトリにインストールすることもよくありました。そのためプラグイン同士のファイルは簡単に混ざってしまい、正しく管理するのは困難でした。

第 2 世代

pathogenunbundle などがあります。特定のディレクトリ構成にしたがってプラグインを配置し、いくつかの設定を書けば、自動で 'runtimepath' を更新してくれるようになりました。
簡単にプラグインごとにディレクトリを分けることができるようになったため、プラグインの更新、削除などが簡単に行えるようになりました。

第 3 世代

VundleNeoBundle などがあります。'runtimepath' の管理に加え、GitHub などから自動でプラグインをダウンロードしてインストールしてくれるようになりました。

第 3.5 世代

vim-plugdein.vim など、第 3 世代の発展形です。速度などに重点を置いて開発されているようです。

Vim 8.0 のパッケージ機能

Vim 8.0 では、pathogen などと同様の 'runtimepath' 管理機能が Vim 本体に搭載されました。
パッケージとは 1 つまたは複数のプラグインをまとめたものであり、それを 'packpath' オプションで指定したディレクトリに配置することで、Vim の起動時に自動でロードしたり、:packadd コマンドを使用して必要な時に手動でロードすることができるようになりました。
詳細は、:help packages を参照してください。

minpac

今回、Vim 8.0 のパッケージ機能と Job 機能を活用した最小限のプラグインマネージャを作ってみました。

開発コンセプト

  • Windows, Linux 対応。
  • Vim 8.0 のパッケージ機能を活用。
  • Vim 8.0 の Job 機能を活用した、プラグインの並列インストール・更新。
  • シンプルかつ最小限度の機能。
  • 高速。
  • 10~20個程度の少数プラグイン向け。

前述のとおり Vim 8 では、'runtimepath' 管理機能が Vim 本体に内蔵されているため、minpac では 'runtimepath' の管理は一切行っていません。プラグインの自動ダウンロード(インストール)、アンインストールのみを処理するようになっています。
これにより、minpac 自体の実装を非常にシンプルにすることができました。それに伴い、minpac のロードも高速 (1ms 以下) になっています。

なお、現時点では以下のような機能の対応は予定していません。

  • 見栄えの良い更新画面。
  • プラグインのインストール後のコマンド自動実行。 v1.0で対応しました。
  • Vim 7.4 以前への対応。

インストール例

'packpath' オプションで指定されたディレクトリのうち、先頭のディレクトリの下に、pack/minpac/opt/ ディレクトリを作成し、そこに minpac を clone してください。

Windows の場合:

cd /d %USERPROFILE%
mkdir vimfiles\pack\minpac\opt
cd vimfiles\pack\minpac\opt
git clone https://github.com/k-takata/minpac.git

Linux, macOS の場合:

mkdir -p ~/.vim/pack/minpac/opt
cd ~/.vim/pack/minpac/opt
git clone https://github.com/k-takata/minpac.git

設定例

.vimrc
packadd minpac

call minpac#init()

" minpac は、`packadd` でロードできるように {'type': 'opt'} を指定する必要がある。
call minpac#add('k-takata/minpac', {'type': 'opt'})

" 他のプラグインはここに追加
call minpac#add('vim-jp/syntax-vim-ex')
...

" プラグインを直ちにロードするには以下を有効化。
"packloadall

'packpath' の先頭に ~/.vim を追加すれば、Windows でも ~/vimfiles の代わりに ~/.vim ディレクトリを使うことができます。

.vimrc
set packpath^=~/.vim
packadd minpac

call minpac#init()
...

使用例

プラグインをインストール、あるいは更新する:

call minpac#update()

使用していないプラグインを削除する:

call minpac#clean()

高度な使い方

興味深いことに、Vim の起動時に minpac を毎回ロードする必要がありません。他のプラグインマネージャとは異なり、プラグインをインストール、更新、削除するときさえロードされていれば良いのです。これは minpac 自身は 'runtimepath' の設定を行わないからです。
minpac をロードして、.vimrc を再読み込みしてプラグインの情報を登録してから minpac#update()minpac#clean() を実行するようなコマンドを定義することで、本当に必要なときだけ minpac をロードすることができます。
(これにより起動の高速化や省メモリ化が期待できるかもしれません。)

.vimrc
if exists('*minpac#init')
  " minpac がロードされている場合
  call minpac#init()
  call minpac#add('k-takata/minpac', {'type': 'opt'})

  " 追加のプラグイン
  call minpac#add('vim-jp/syntax-vim-ex')
  ...
endif

" プラグインの設定はここに記載
...

" プラグインを更新/削除するためのユーザーコマンドの定義
" いずれも、minpac をロードし、.vimrc を再読込してプラグインの情報を
" 登録してから、作業を実行する。
command! PackUpdate packadd minpac | source $MYVIMRC | call minpac#update()
command! PackClean  packadd minpac | source $MYVIMRC | call minpac#clean()

当然 .vimrc は再読込可能になっている必要があります。

今後

vim-plug や dein.vim などとの速度比較は今後の課題です。

また、minpac の開発過程で、Vim 本体にあると便利だと判明した機能があれば、適宜本体にフィードバックしていく予定です。

72
37
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
72
37