TODO: Write in English
Vim script レイヤ (volt.vim) と Go レイヤに分かれる。
Vim script レイヤは curl コマンドで Go レイヤを GitHub releases からダウンロードする。
なるべく依存関係を少なくするため git コマンドは使わない。
できたらダウンロードは何も入れずに行えるのがベター (設計については「Vim script レイヤ (volt.vim)」「設計」の項を参照)。
netrw の機能を使って :so https://raw.githubusercontent.com/vim-volt/vim-volt/master/bootstrap.vim
とすれば「volt コマンドのインストール」と「volt.vim のインストール」を行うこともできる。
Go レイヤは src-d/go-git を使って git clone などを行う。
- 「volt.vim のダウンロードは何も入れずに行えるのがベター」
- Windows では Powershell の機能 などを使い、その他の環境では perl(LWP::Simple), curl, wget などを使い分ける
- 「netrw の機能を使って ~ 「volt コマンドのインストール」と「volt.vim のインストール」を行うこともできる」 (この場合は curl が必要? (netrw が使うため?))
- bootstrap.vim が netrw によってダウンロードされ実行される
$VOLTPATH
ディレクトリが作られる$VOLTPATH
はデフォルトで$HOME/volt
。変える場合は事前に$VOLTPATH
を定義しておく
- Powershell の機能, perl(LWP::Simple), curl, wget などを使って volt コマンドを
$VOLTPATH/bin/volt
にダウンロードする - volt コマンドを使ってリポジトリごと volt.vim を
$VOLTPATH/repos/github.com/vim-volt/vim-volt
にダウンロードする - 新しいバッファが作られ初期設定のガイドが表示される (「vimrc の設定」を参照)
- volt.vim は volt コマンドのバージョン (MAJOR.MINOR.PATCH) を持つ
- 将来は volt コマンドは volt コマンドの MAJOR.MINOR だけ指定して最新版を取得するようにしたい
- どうやって最新版のダウンロード URL を特定する?
{MAJOR}.{MINOR}-latest
のようなタグを MAJOR.MINOR 以下で常に最新の PATCH を指すようにする?
- どうやってリモートの最新版を特定する?
{MAJOR}.{MINOR}-latest
のリリースにLATEST
のようなファイルを置く?
- job で外部コマンド (volt) を叩く
:VoltGet
で外部コマンドvolt get
を叩く感じ
- volt コマンドをインストールする
- GOOS と GOARCH を特定して
$HOME/volt/bin
($VOLTPATH/bin
) にvolt
コマンドのバイナリをインストール
- GOOS と GOARCH を特定して
- volt コマンドを初回に実行する前に volt コマンドのバージョンを調べ、volt.vim と非互換だった場合にアップグレード or ダウングレードする
- vivo.vim も持っていた Vim プラグインごとの設定ファイル (plugconf)
- ファイルは
$VOLTPATH/plugconf/{site}/{user}/{name}.vim
に置く - vivo.vim では
vivo#plugconf#load()
を直接呼ぶ必要があった - volt.vim では本体にインテグレートした扱いにしたい
- 設定ファイルには
set rtp+={volt.vim}
とcall volt#load()
を呼ぶだけでいいようにしたい- 「volt.vim 関連の vimrc の設定」を参照
- ファイルは
set rtp+=$HOME/volt/repos/github.com/vim-volt/vim-volt " * lock.json の active_profile / profiles[] から取得した Vim プラグインをロードする " * プラグインの rtp の追加 ($HOME/.vim 以下にまとめて配置するなら不要) " * plugconf のロード (これもまとめて $HOME/.vim 以下に配置できる?) " * :filetype plugin indent on は? call volt#load()
- なるべく記載を少なくシンプルにしたい
GitHub の README.md を見た人が「こんなシンプルなら使ってみたい」となるような短さがいい
- 既存の vimrc はなるべく
$VOLTPATH/rc/init.vim
に移動してもらう- これは後述の profile 機能を使うためには既存の vimrc の設定が邪魔になることがあるため
- volt.lock に記載があるがインストールされていない Vim プラグインを fetch するのはユーザ側で
:VoltGet -l
させる
基本的に volt コマンドのサブコマンドと一対一になっている。
- :VoltGet
volt get
を実行- lock.json ファイルの trx_id と repos[]/trx_id が一致する Vim プラグインのリストを取得し、それぞれに対し以下を実行
- もし rtp になければ
- rtp に追加
:so plugin/**/*.vim
を実行
:helptags doc
を実行:so {plugconf}
を実行- plugconf の hook_post_update を実行
- もし rtp になければ
- :VoltRm
volt rm
を実行- rtp から削除した Vim プラグインを削除
- :VoltQuery
volt query
を実行
- :VoltProfile [{profile name}] (「profile 機能」を参照)
volt profile
を実行
- :VoltEdit [{glob} …] (oldfilesearch.vim の :OldFileSearch の様なコマンド)
- $VOLTPATH 以下の rc, plugconf ディレクトリ以下からファイルのリストを再帰的に取得
- ファイルのリストを指定された glob で絞り込む
- ファイルのリストが 0 個だったらエラーメッセージ
- ファイルのリストが 1 個だったらそれを開く
- ファイルのリストが 2個以上だったら選択肢を出す
- 選択したら開く
- :VoltVersion
volt query -l vim-volt/vim-volt
とvolt version
を実行し、vim-volt と go-volt のバージョンを表示する- このコマンドはもしインストールされてなければ volt コマンドをインストールするのにも使える
- 上記の動作はこのコマンドに限らず volt コマンドを実行する時に必ず行うが、このコマンドは表示以外何も行わないので lock.json の内容を変えずに go-volt をダウンロードできる
Hooks や プラグインに対する設定を書く。
plugconf にはユーザ用とシステム用があり、それぞれ以下の場所にインストールされる。
- ユーザ用
$VOLTPATH/plugconf/user/{plugconf}
- システム用
$VOLTPATH/plugconf/system/{plugconf}
{plugconf}
は以下のようなパスとなる。
{site}/{user}/{name}.vim
{site}
: リポジトリのホストサイトのホスト名 (eg. github.com){user}
: リポジトリのユーザ名{name}
: リポジトリ名
システム用 plugconf は go-volt により常にインストール・削除される。
ユーザ用 plugconf ではシステム用 plugconf の設定を継承したり上書きすることができる。
継承するには $VOLTPATH/plugconf/user/{site}/{user}/{name}.vim
で a:super()
を実行する。
上書きするにはそれを呼ばなければ良い。
JSON ファイルの場合はユーザ用 plugconf は常にシステム用 plugconf を上書きするので、
システム用 plugconf ($VOLTPATH/plugconf/system/{site}/{user}/{name}.json
) をユーザ用 plugconf ($VOLTPATH/plugconf/user/{site}/{user}/{name}.json
) にコピーしてから編集する (この操作は :VoltEdit
でシステム用 plugconf を読み込んだ後、編集しようとした時にプロンプトが出るので、Yes を選択すると自動的に :saveas
によってコピーされる)。
JSON ファイルの場合も Vim script の場合も、ユーザ用 plugconf がなければシステム用 plugconf が自動的に読み込まれる。
hook については dein.vim の hook も参考のこと。
- post_install_hook
- 初回インストール時に呼ばれる
- pre_update_hook, post_update_hook
- 初回インストール時やアップデート時に呼ばれる
- pre_load_hook, post_load_hook
- Vim プラグインがロードされた時に呼ばれる
- 「ロード」とは何を指す? (TODO)
- filetype_hook
- dein.vim の
on_ft
- dein.vim の
- excmd_hook
- dein.vim の
on_cmd
- dein.vim の
リポジトリのディレクトリ構成は以下の通り。
- `/templates/{site}/{user}/{name}.vim`
- plugconf ファイル (JSON または Vim script ファイル) が置かれる
- template と言いつつ、今は GET してきたファイルをそのまま保存するだけ
読み込む Vim プラグインのセットを決められる。
デフォルトは default profile。
:VoltProfile
コマンドで切り替えられる。
lock.json の load_init フラグと合わせて完全な sandbox 環境を作ることができる (○○プラグインと☓☓プラグインを組み合わせてまっさらな vimrc(init.vim) で起動する)。
dein.vim には on_ft
と on_cmd
があるようだ。
- Q. plugconf と lock.json どちらに指定可能にするべきか?
- A1. plugconf の先頭行にマジックコメントとして書く
- スクリプトファイルをなるべく読み込みたくないが、
on_ft
とon_cmd
は plugconf-templates リポジトリに集約させたい情報 - よって vim-volt は plugconf を読み込む前に先頭のマジックコメントをパースする
- これによって読み込み時は遅くなるが、スクリプトの読み込みは避けられる (スクリプトの読み込みは思ったよりメモリも使うし遅い)
- 速度によってはメタデータとして lock.json か別の JSON ファイルにキャッシュすることも考える
- これだとパースが面倒なのでは?
- スクリプトファイルをなるべく読み込みたくないが、
- A2. plugconf と同じディレクトリに拡張子を .json に変えて保存する
- このファイルに書けるのは結果として静的な値を返す設定のみ (Vim script は書けない)
- Semantic Versioning に則ったバージョン番号にする
- 設定ファイル (JSON) を持つ
$HOME/volt/lock.json
- Vim プラグインリポジトリの git clone 先について
$HOME/volt/repos/{site}/{user}/{name}
$HOME/.vim
ディレクトリ以下の方がいいか?- 設定 (
$VOLTPATH
) で$HOME/.vim
以下にすることもできる?(推奨はしないかもしれない)
- 設定 (
- lock.json に書き込む時にはトランザクションと呼ばれる動作を行い同時に lock.json に書き込んでしまい内容を失うことがないようにする (「トランザクション」を参照)
トランザクションの直前にロックファイルの存在確認を行い、存在すれば “[ERROR] trx.lock exists. If process is already dead, please remove ‘~/volt/trx.lock’ manually” と表示する (これは「トランザクション」の動作には含まれない)。
lock.json に書き込む時にはロックファイルを作り、自身の PID を書き込む。
その後すぐにファイルの内容を読み出し、自身の PID が読み出せればトランザクションを開始してよい。
ファイルの内容が違っていたり、すでにファイルが作られていたらトランザクションは失敗する (コマンドはエラー終了する)。
以下にトランザクションの例を示す。
- A 書き込み
- B 書き込み
- B 読み出し (自身の PID が読み出せたので続行)
- A 書き込み (自身の PID ではなかったためエラー終了)
この図の A のように書き込みが先でも「書き込み」「読み出し」を先に終えた B がトランザクションを獲得する。
- volt get [-L {lock.json uri}] [-V {vimrc uri}] [-u] [-f] [-v] {repository}
- リポジトリが指す Vim プラグインをインストール・アップデートする
- -L オプション:https スキーマの URL かファイルパスで指定した volt.lock に記載の Vim プラグインのリストを使用する
- https スキーマの URL の場合リモートから GET して取得する
- このオプションが指定された場合、同時に引数が指定されるとエラーとなる
- -V オプション:https スキーマの URL かファイルパスで指定した init.vim を
$VOLTPATH/rc/init.vim
にインストールする- もし
$VOLTPATH/rc/init.vim
がすでに存在していたらエラーとなる
- もし
- -u オプション:既存の Vim プラグインを git pull でアップデート (初回インストール時は無視)
- -f オプション:リポジトリを削除して gir clone しなおす
- -l と -u が同時に指定された場合は全てのリポジトリをアップデート
- -v オプション:git clone の出力を出力する
- repository の書式
- github.com/user/name → https://github.com/user/name
- user/name → https://github.com/user/name
- https://github.com/user/name
- private repository アクセス時の ssh のプロンプトをどうやって回避する?
- go get はどうしてる?
- 詳細設計
- -l オプションが指定されたら volt.lock から Vim プラグインのリストを取得する
- -l オプションが指定されなかったら引数から Vim プラグインのリストを取得する
- Vim プラグインのリストのそれぞれに対して以下を実行
- リポジトリが dirty な場合はエラーを出力して終了
- トランザクションを取得
- Vim プラグインのリストのそれぞれに対して以下を実行
- -u オプションが未指定でリポジトリが存在したら
- 警告表示 “[WARN] Repository exists:” {repos} して continue
- リポジトリを一時ディレクトリに clone
- -u オプションが未指定か HEAD が違う場合は
- リポジトリを一時ディレクトリから
$VOLTPATH/repos/{site}/{user}/{name}
に移動 - https://github.com/vim-volt/plugconf-templates のリポジトリから標準 plugconf を取得して plugconf のディレクトリに保存する
- リポジトリを一時ディレクトリから
- -u オプションが未指定でリポジトリが存在したら
- リポジトリが移動された Vim プラグインを変更して lock.json に書き込む
- アップグレードされたプラグインがあった場合、以下のように表示
- “[WARN] Reloading upgraded plugin is not supported.”
- “[WARN] Please restart your Vim to reload the following plugins:”
- アップグレードされたプラグインのリスト
- volt rm {repository}
- Vim プラグインをアンインストールする
- {repository} の書式は
volt get
と同じ
- volt query [-j] [-i] [{repository}]
- Vim プラグインに関する情報を標準出力に出力する
- {repository} の書式は
volt get
と同じ - もし {repository} がインストール済みのものでなければリモートの情報を表示 (もちろんインストールはしない)
- 現時点では必要ないが、検索にも使えるようにしたいため
- -j オプション:JSON で出力
- どうせ volt.vim からしか使わないのなら JSON 出力をデフォルトにしてもいいかもしれない
- -i オプション:インストールされている Vim プラグイン全てを対象とする
- volt enable {repository} [{repository2} …]
- 次のショートカット:
volt profile add {current profile} {repository} [{repository2} ...]
- 次のショートカット:
- volt disable {repository} [{repository2} …]
- 次のショートカット:
volt profile rm {current profile} {repository} [{repository2} ...]
- 次のショートカット:
- volt profile [get]
- 現在の profile を表示
- volt profile set {profile name}
- lock.json の active_profile をセットする
- “[INFO] Please start Vim to load” {profile name} “profile” と表示
- volt profile show {profile name}
- {profile name} の情報を表示する
- volt profile new {profile name}
- {profile name} を持った profile を作成
active_profile
は変更しない
- volt profile destroy {profile name}
- {profile name} を持った profile を削除
- volt profile add {profile name} {repository} [{repository2} …]
- {profile name} の profile に1つかそれ以上の {repository} を追加
- volt profile rm {profile name} {repository} [{repository2} …]
- {profile name} の profile から1つかそれ以上の {repository} を削除
- volt version
- バージョン情報を出力
基本は go コマンドのようにシンプルにしたいが、ロック機能は付けたい。
$VOLTPATH/repos/{user}/{name}
に cd して開発する場合も考える。
開発する時にまた git checkout するのが面倒なので (vivo.vim ではそうしていたが) volt get した時点で git checkout
することはない。
上と同じ理由で branch の情報はいらない。
項目は glide.lock を参考にしている。
- version
- lock.json のフォーマットのバージョン
- trx_id
- 前回行われたトランザクション (lock.json ファイル書き込み) の ID
- active_profile
- 現在アクティブな profile 名
- repos[]
- Vim プラグイン情報のリスト
- repos[]/path
- スキーマ (
https://
) なしの URL ($VOLTPATH/repos/{path}
の path 部分とも言える)
- スキーマ (
- repos[]/version
- Git のコミットハッシュ
- repos[]/trx_id
- 記載のトランザクションの時にインストールされたことを示す ID
- profiles[]
- 「profile 機能」を参照
- 初期値の default profile も例外なくこの配列の中に存在する
- profiles[]/name
- profile 名
- profiles[]/path
- 読み込む Vim プラグインのスキーマ (
https://
) なしの URL
- 読み込む Vim プラグインのスキーマ (
- profiles[]/rc[]
- 起動時に読み込まれる
$VOLTPATH/rc/
以下の Vim script ファイル名を指定
- 起動時に読み込まれる