Skip to content

Instantly share code, notes, and snippets.

@ujihisa ujihisa/vac230.md
Last active Jan 9, 2018

Embed
What would you like to do?
Vim Advent Calendar 2012 http://atnd.org/events/33746

Vim Advent Calendar 2012 ujihisa 15 (230日目)

Vim Advent Calendar 2012 の230日目の記事です。昨日の記事は@manga_osyoさんで、明日の記事はvital.vimコミッタの@rbtnnさんです。

今回は意表をついてVim scriptの入門記事です。

Vim script入門!

Vim script初級者レベルを10段階に分割すると、そのうち簡単な方から3つは、以下のようになります。

  1. Vim scriptという名称すら知らず、VimScriptやVimLなどといった架空の呼び名を用いる。足し算など、基本的な四則演算がぎりぎり利用できる。
  2. Vimプラギン開発まではいかないが、自分の~/.vimrcに簡単なロジックを記述したことならある
  3. vital.vimモジュールを利用する程度なら可能である。まだvitalそのものの開発には参加していない
  4. ...
  5. Vim script中級者である

この記事はレベル1の読書の人を全員レベル3卒業まで引き上げることを目的とします。

Vim script初級者レベル1 ~ 2

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正規表現の記述を省略しています。これについては後述します。

Vim script初級者レベル3

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ファイルにコンパイルできるため、実用的かつ可搬性の高いものになるのではないでしょうか。)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.