Vim Advent Calendar 2012 の230日目の記事です。昨日の記事は@manga_osyoさんで、明日の記事はvital.vimコミッタの@rbtnnさんです。
今回は意表をついてVim scriptの入門記事です。
Vim script初級者レベルを10段階に分割すると、そのうち簡単な方から3つは、以下のようになります。
- Vim scriptという名称すら知らず、VimScriptやVimLなどといった架空の呼び名を用いる。足し算など、基本的な四則演算がぎりぎり利用できる。
- Vimプラギン開発まではいかないが、自分の
~/.vimrc
に簡単なロジックを記述したことならある - vital.vimモジュールを利用する程度なら可能である。まだvitalそのものの開発には参加していない
- ...
- Vim script中級者である
この記事はレベル1の読書の人を全員レベル3卒業まで引き上げることを目的とします。
Vim script (Vimスクリプト)という言語そのものについては:h eval
やwikipediaのVim scriptのページが参考になります。
- VimScriptという言語は存在しません。JavaScriptやCoffeeScriptなら存在します。
- VimLという言語は存在しません。Isothalamusについては VImL を参照してください。
- なおJavascriptという言語は存在しませんが、Java Scriptingは存在します。
まず初級者レベル1を卒業するためには、thincaさんの記述した文書 Vimスクリプト基礎文法最速マスター が非常に役に立ちます。この文書に記述されている内容をすべて実際に写経し、体験することは、あなたの一生の友になるでしょう。
写経するにあたって、Vim scriptを簡単に実行するため、以下のうち少なくとも1つ、できれば両方を導入することをおすすめします。
なお、"Vimスクリプト基礎文法最速マスター"は簡単のため意図的にVim正規表現の記述を省略しています。これについては後述します。
vital.vimを用い、偉大なる先人の資産を最大限活用しましょう。
vital.vimの用い方はREADMEに詳しく記述されています。vitalを用いたいプラギンをVitalize
すればよいです。が、~/.vimrc
に記述するなど、個人的な用途ならばVitalize
せず単にvital.vimをruntimepath (&rtp
)に入れて独立したプラギンとして利用すればよいです。
NeoBundle 'vim-jp/vital'
こうすると、vital#of('vital')
とすることでvitalが利用可能になります。
let s:V = vital#of('vital')
(著者の~/.vimrc
では、これをs:V
ではなくg:V
に代入しています。ちょっとvitalの関数を使いたいときに、いつでもどこでもg:V
でvitalが利用できて、大変便利です。実際にvimrcの中で多用しています。が、万人にオススメできるわけではありません。)
vital.vimの各モジュールについては同封のhelpファイルを見ればよいのですが、有志による美しい日本語ドキュメント も部分的に利用可能です。ぜひ活用してみてください。
let s:V = vital#of('vital')
let s:L = s:V.import('Data.List')
let s:S = s:V.import('Data.String')
Data
以下にあるモジュールはとくに利用価値が高いものが多いと評判です。ぜひ、すべてのモジュールを用いたプラギン開発や~/.vimrc
育成を行なってみてはいかがでしようか。
純粋なVim scriptだけではなく、Vim script中にVimに組み込まれた他言語インタフェースを用いることもできます。
let s:x = 123
python << EOH
import vim
print(int(vim.eval('s:x')) + 1)
EOH
上記の例はVim script側で定義されたs:x = 123
をPythonから参照し、1加算した124を出力しています。
Vim plugin開発にあたって他言語インタフェースを用いる決定をしたときは、以下のルールに従うことで、多くの問題を事前に回避できます。
- マルチスレッドな機能を一切使わない
- 外部ライブラリを一切使わない (*1)
- forkしない (Vimプロセスをコピーしない)
if_ruby
を使わない
Vimはスレッドセーフではありません。スレッドを作ると、その中でどんな自明な処理をしていたとしても、確率的にVimが音もなく静かに死亡します。自分でスレッドを明示的に使わなくても、外部ライブラリがスレッドを作成していれば同じことです。
外部ライブラリを一切使わない(*1)というルールは、条件付きで回避できます。ライブラリを使うときは、そのライブラリと、そのライブラリが依存しているすべてのライブラリを再帰的にすべて確認し、いずれもいっさいスレッドを使っていないときのみ、安全といえます。言い換えると、ほんのすこしでも自信がないときはやめておきましょう。
例えば、if_ruby
を避ける。意図せずスレッドを用いたライブラリを依存ライブラリの一つとして読み込んでしまうという事例が多々観測されています。
lua
ができることはとても少ないため、比較的安全度が高いといえます。かつ、luajit
のおかげで単純に処理速度が速いです。luaの記述力はVim scriptより低く感じるかもしれませんが、少なくとも(外部プラギンに依存せず利用可能な) lambdaがあります。他の外部言語インタフェースよりもおすすめ度が高いです。
(著者が一番オススメするのは、そもそもVim内で他言語インタフェースを用いるのではなく、別のプロセスとして他言語で記述されたプログラムを起動し、vitalのProcessManagerなどで通信することです。どうしてもオーバーヘッドは残るものの、処理速度の純粋な向上・記述性の向上だけでなく、真の並列性が得られるという利点が残ります。外部ライブラリも使いたい放題です。Clojureなどで記述するとjarファイルにコンパイルできるため、実用的かつ可搬性の高いものになるのではないでしょうか。)