📦

vim-jetpack管理のVimプラグインをシェルから追加削除する

に公開

この記事はVim駅伝の368本目の記事です。

Vimのプラグインをインストールするとき、
Vundle方式のプラグインマネージャを利用している場合は、
vimrc、またはvimrcから読み込むTOMLの設定ファイルに設定行を追加し、
:PlugInstall:JetpackSyncを実行してプラグインをインストールします。

しかし、ときにはより手軽にプラグインをインストールしたいもの。
aptやdnfでパッケージをインストールするように、
シェルからコマンドを実行してプラグインをインストールし、プラグインを試したいときもあります。

そんなときに、そのための一般的な方法がある訳ではないですが、
一つの方法として、シェルからVimプラグインを追加削除する方法をこの記事では紹介します。
今回はvim-jetpackを例にしていますが、vim-plugやlazy.nvimといった他のプラグインマネージャであっても、同じ方法でできると思います。

用意するコマンド

次の機能を持つコマンドを用意します。

  • プラグイン追加: 設定ファイルを読み取り、設定ファイルにプラグインインストール行を追記し、プラグインを更新するVimのコマンドを実行
  • プラグイン削除: 設定ファイルを読み取り、設定ファイルからプラグインインストール行を削除し、プラグインを更新するVimのコマンドを実行

例えば、次のコマンドであれば、次のようにしてプラグインの追加削除ができます。

https://github.com/nil-two/vj

# vim/killersheepをインストール
vj install vim/killersheep

# vim/killersheepを削除
vj remove vim/killersheep

このコマンドでは、
プラグイン追加の際は次のようにプラグインインストール行を追加し、
プラグイン削除の際は次のようにプラグインインストール行を削除し、
その後プラグインを更新するVimのコマンドを実行しています。

" vj install vim/killersheepを実行したとき、
" vimrcの次の部分を次のように更新し、:JetpackSyncを実行
"
" vj:jetpack_dein:start
call jetpack#add('tani/vim-jetpack', {'opt': 1})
call jetpack#add('junegunn/fzf.vim')
call jetpack#add('junegunn/fzf', {'build': './install'})
call jetpack#add('thinca/vim-quickrun')
" vj:jetpack_dein:end
" ↓
" vj:jetpack_dein:start
call jetpack#add('tani/vim-jetpack', {'opt': 1})
call jetpack#add('junegunn/fzf.vim')
call jetpack#add('junegunn/fzf', {'build': './install'})
call jetpack#add('thinca/vim-quickrun')
call jetpack#add('vim/killersheep')
" vj:jetpack_dein:end

" vj remove vim/killersheepを実行したとき、
" vimrcの次の部分を次のように更新し、:JetpackSyncを実行
"
" vj:jetpack_dein:start
call jetpack#add('tani/vim-jetpack', {'opt': 1})
call jetpack#add('junegunn/fzf.vim')
call jetpack#add('junegunn/fzf', {'build': './install'})
call jetpack#add('thinca/vim-quickrun')
call jetpack#add('vim/killersheep')
" vj:jetpack_dein:end
" ↓
" vj:jetpack_dein:start
call jetpack#add('tani/vim-jetpack', {'opt': 1})
call jetpack#add('junegunn/fzf.vim')
call jetpack#add('junegunn/fzf', {'build': './install'})
call jetpack#add('thinca/vim-quickrun')
" vj:jetpack_dein:end

vj installでは設定行が追加され、
vj removeでは設定行が削除されていますね。
プラグイン追加削除のコマンドを実行した後にVimを起動すると、
プラグインが追加削除された状態でVimが起動します。

このコマンドがやっているのは、
追加削除どちらとも設定ファイルの更新と、プラグイン更新のコマンドの実行の2つだけですが、
その2つをすることで実質的にプラグインの追加削除ができます。

このコマンドはあくまで一例ですが、このような作りのコマンドがあれば、
それでプラグインの追加削除を始めとしたプラグインの管理ができます。
次はこのような作りのコマンドを作るにあたって、どのようにすると作れるかを示します。

用意するコマンドの作り方

設定ファイルへのマーカー行の追加

コマンドの外の部分になりますが、
コマンドで読み書きする設定ファイルについて、少し手を加える必要があります。
コマンドでは設定ファイルを更新する訳ですが、
設定ファイルのどこにプラグインインストール行を追加するのか、どこのプラグインインストール行を削除するのか、それを識別するのは何も無しだと大変です。
特に、vimrcはVim scriptで設定を書く関係で、プラグインインストール行はどこにでも書けるため、プラグインインストール行がどう追加削除されるべきか決めるのは難しいです。

そのため、設定ファイルのどの部分がコマンドの管理範囲なのかをコマンドが識別可能な形で示すため、
マーカーとなるマーカー行を設定ファイルに追加します。
マーカーは管理範囲を指定するため、始端のマーカー行、終端のマーカー行の2つを追加します。
例えば次の例では、" vj:jetpack_dein:startが始端のマーカー行、" vj:jetpack_dein:endが終端のマーカー行になります。

packadd vim-jetpack
call jetpack#begin()
" vj:jetpack_dein:start
call jetpack#add('tani/vim-jetpack', {'opt': 1})
call jetpack#add('junegunn/fzf.vim')
call jetpack#add('junegunn/fzf', {'build': './install'})
call jetpack#add('thinca/vim-quickrun')
" vj:jetpack_dein:end
call jetpack#end()

この例だと、" vj:jetpack_dein:start" vj:jetpack_dein:endの行がマーカー行で、
" vj:jetpack_dein:start" vj:jetpack_dein:endで囲まれた部分が管理範囲になります。
上記の通りであれば、次の4つのプラグインインストール行が管理範囲になります。

call jetpack#add('tani/vim-jetpack', {'opt': 1})
call jetpack#add('junegunn/fzf.vim')
call jetpack#add('junegunn/fzf', {'build': './install'})
call jetpack#add('thinca/vim-quickrun')

マーカー行は単にコマンドが管理範囲の識別に利用するもので、それ以上の意味合いは持ちません。
例えば、WordPressのプラグインには、.htaccessに始端、終端となるマーカー行を書き込み、設定を管理するものがありますが、あれが読み書きしているものと同じです。
単にそのツール、そのプラグイン、そのコマンドがファイル読み取るにあたって、管理範囲はどこか、管理範囲外はどこかを識別するためのマーカーになります。
コマンドでは、この管理範囲についてのみ設定ファイルを更新するようにし、管理範囲外の部分については更新しません。
プラグイン追加の際はこの管理範囲に行を追加することで、
プラグイン削除の際はこの管理範囲から行を削除することで、
設定の管理を行います。

設定ファイルのマーカー行で囲まれている管理範囲を更新するコマンドの作成

設定ファイルにマーカー行を追加できたのであれば、
設定ファイルのマーカー行で囲まれた管理範囲を更新し、プラグインを更新するVimのコマンドを実行するコマンドを用意すれば出来上がりです。
プラグイン追加、プラグイン削除のときはそれぞれ、次のように管理範囲を更新します。

  • プラグイン追加
    • 管理範囲にプラグインインストール行があれば何もしない
    • 管理範囲にプラグインインストール行が無ければ、管理範囲の末尾にプラグインインストール行を追加し、プラグインを更新するVimのコマンドを実行する
  • プラグイン削除
    • 管理範囲にプラグインインストール行が無ければ何もしない
    • 管理範囲にプラグインインストール行があれば、そのプラグインインストール行を削除し、プラグインを更新するVimのコマンドを実行する

管理範囲の更新についてはこれだけですが、
プラグインを更新するVimのコマンドの実行については、プラグインマネージャによってはscriptコマンドを使って実行をラップする必要があります。
画面の描画由来なのか、はたまた…どうしてか未把握です。前者でいければ前者の形で、前者でいけない場合は後者の形でするとできると思います。

# Vim scriptを実行してプラグインを更新(vim-jetpackの場合この形ではできない)
vim -e -s +':JetpackSync' +'qall!'

# Vim scriptを実行してプラグインを更新(vim-jetpackの場合この形でできる)
printf '%s\n' ':JetpackSync | qall!' | script -c vim /dev/null > /dev/null

vim -e -sの、-eはVimをExモードで起動するオプション、-sはサイレントモードでVimを起動するオプションです。この2つのオプションを指定しているとVimの画面を出さずにVimを使えます。
そして、この2つのオプションの指定に加えて、+'Vimのコマンド'でプラグインを更新するVimのコマンドを指定しプラグインを更新し、+'qall!'でVimを終了します。
scriptは色々なことができるコマンドですが、一つの機能として、操作の入力をコマンドに渡して、その通りに操作するということができるため、標準入力から操作の入力を流しコマンドを実行することで、プラグインの更新を行えます。

おわりに

大分原始的な方法ですが、
このような方法でVimプラグインをシェルから追加削除することができます。
このようなコマンドがあると、ふとnyancat-vimを遊びたいと思ったときなどに、すぐ入れて遊べて便利です。よければお試しください。

Discussion