Skip to content

vim-volt/design

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 

Repository files navigation

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 などを行う。

Vim script レイヤ (volt.vim)

設計

  • 「volt.vim のダウンロードは何も入れずに行えるのがベター」
    • Windows では Powershell の機能 などを使い、その他の環境では perl(LWP::Simple), curl, wget などを使い分ける
  • 「netrw の機能を使って ~ 「volt コマンドのインストール」と「volt.vim のインストール」を行うこともできる」 (この場合は curl が必要? (netrw が使うため?))
    1. bootstrap.vim が netrw によってダウンロードされ実行される
    2. $VOLTPATH ディレクトリが作られる
      • $VOLTPATH はデフォルトで $HOME/volt。変える場合は事前に $VOLTPATH を定義しておく
    3. Powershell の機能, perl(LWP::Simple), curl, wget などを使って volt コマンドを $VOLTPATH/bin/volt にダウンロードする
    4. volt コマンドを使ってリポジトリごと volt.vim を $VOLTPATH/repos/github.com/vim-volt/vim-volt にダウンロードする
    5. 新しいバッファが作られ初期設定のガイドが表示される (「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 コマンドをインストールする
    • GOOSGOARCH を特定して $HOME/volt/bin ($VOLTPATH/bin) に volt コマンドのバイナリをインストール
  • 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 の設定」を参照

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 させる

Ex コマンド

基本的に volt コマンドのサブコマンドと一対一になっている。

  • :VoltGet
    1. volt get を実行
    2. lock.json ファイルの trx_id と repos[]/trx_id が一致する Vim プラグインのリストを取得し、それぞれに対し以下を実行
      1. もし rtp になければ
        1. rtp に追加
        2. :so plugin/**/*.vim を実行
      2. :helptags doc を実行
      3. :so {plugconf} を実行
      4. plugconf の hook_post_update を実行
  • :VoltRm
    1. volt rm を実行
    2. rtp から削除した Vim プラグインを削除
  • :VoltQuery
    1. volt query を実行
  • :VoltProfile [{profile name}] (「profile 機能」を参照)
    1. volt profile を実行
  • :VoltEdit [{glob} …] (oldfilesearch.vim の :OldFileSearch の様なコマンド)
    1. $VOLTPATH 以下の rc, plugconf ディレクトリ以下からファイルのリストを再帰的に取得
    2. ファイルのリストを指定された glob で絞り込む
    3. ファイルのリストが 0 個だったらエラーメッセージ
    4. ファイルのリストが 1 個だったらそれを開く
    5. ファイルのリストが 2個以上だったら選択肢を出す
      1. 選択したら開く
  • :VoltVersion
    • volt query -l vim-volt/vim-voltvolt version を実行し、vim-volt と go-volt のバージョンを表示する
    • このコマンドはもしインストールされてなければ volt コマンドをインストールするのにも使える
      • 上記の動作はこのコマンドに限らず volt コマンドを実行する時に必ず行うが、このコマンドは表示以外何も行わないので lock.json の内容を変えずに go-volt をダウンロードできる

plugconf

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}.vima: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
  • excmd_hook
    • dein.vim の on_cmd

plugconf-templates リポジトリ

リポジトリのディレクトリ構成は以下の通り。

  • `/templates/{site}/{user}/{name}.vim`
    • plugconf ファイル (JSON または Vim script ファイル) が置かれる
    • template と言いつつ、今は GET してきたファイルをそのまま保存するだけ

profile 機能

読み込む Vim プラグインのセットを決められる。
デフォルトは default profile。
:VoltProfile コマンドで切り替えられる。

lock.json の load_init フラグと合わせて完全な sandbox 環境を作ることができる (○○プラグインと☓☓プラグインを組み合わせてまっさらな vimrc(init.vim) で起動する)。

filetype や コマンド実行時に初めて Vim スクリプトファイルを読み込む (遅延ロード機能)

dein.vim には on_fton_cmd があるようだ。

  • Q. plugconf と lock.json どちらに指定可能にするべきか?
  • A1. plugconf の先頭行にマジックコメントとして書く
    • スクリプトファイルをなるべく読み込みたくないが、 on_fton_cmd は plugconf-templates リポジトリに集約させたい情報
    • よって vim-volt は plugconf を読み込む前に先頭のマジックコメントをパースする
    • これによって読み込み時は遅くなるが、スクリプトの読み込みは避けられる (スクリプトの読み込みは思ったよりメモリも使うし遅い)
    • 速度によってはメタデータとして lock.json か別の JSON  ファイルにキャッシュすることも考える
    • これだとパースが面倒なのでは?
  • A2. plugconf と同じディレクトリに拡張子を .json に変えて保存する
    • このファイルに書けるのは結果として静的な値を返す設定のみ (Vim script は書けない)

Go レイヤ (volt コマンド)

設計

  • 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 が読み出せればトランザクションを開始してよい。
ファイルの内容が違っていたり、すでにファイルが作られていたらトランザクションは失敗する (コマンドはエラー終了する)。

以下にトランザクションの例を示す。

  1. A 書き込み
  2. B 書き込み
  3. B 読み出し (自身の PID が読み出せたので続行)
  4. 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 の書式
    • 詳細設計
      1. -l オプションが指定されたら volt.lock から Vim プラグインのリストを取得する
      2. -l オプションが指定されなかったら引数から Vim プラグインのリストを取得する
      3. Vim プラグインのリストのそれぞれに対して以下を実行
        1. リポジトリが dirty な場合はエラーを出力して終了
      4. トランザクションを取得
      5. Vim プラグインのリストのそれぞれに対して以下を実行
        1. -u オプションが未指定でリポジトリが存在したら
          1. 警告表示 “[WARN] Repository exists:” {repos} して continue
        2. リポジトリを一時ディレクトリに clone
        3. -u オプションが未指定か HEAD が違う場合は
          1. リポジトリを一時ディレクトリから $VOLTPATH/repos/{site}/{user}/{name} に移動
          2. https://github.com/vim-volt/plugconf-templates のリポジトリから標準 plugconf を取得して plugconf のディレクトリに保存する
      6. リポジトリが移動された Vim プラグインを変更して lock.json に書き込む
      7. アップグレードされたプラグインがあった場合、以下のように表示
        • “[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]
    1. 現在の profile を表示
  • volt profile set {profile name}
    1. lock.json の active_profile をセットする
    2. “[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
    • バージョン情報を出力

$HOME/volt/lock.json の項目

基本は 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
  • profiles[]/rc[]
    • 起動時に読み込まれる $VOLTPATH/rc/ 以下の Vim script ファイル名を指定

About

Design memo about vim-volt, go-volt

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published