vim script tips about eval

top level の list item はそのまま :help するための keyword 。

  • :execute
    • script を書く上でないと死ぬ。引数にとった式を評価した結果を ex command として実行してくれる。 if なんかで判断して得た data ( file path とか option の設定とか ) とかをなんらかの ex command の引数として渡したい場合はこれを使わないと不可能だったりする。
    • というか vim で式評価が行われる timing が未だによくわからないんだけど script はすべて ex command の連続ということと ex command に続くものは評価が行われることもある、というあたりから推測して何か引数を評価して実行してくれるものがあるんじゃないかと思って探してみたらあったという経緯で。
    • 例は以下のような感じで。 filetype 別に読み込む template file を切り替える script 。
if &filetype == 'vimperator'
    let s:template = 'vimperator.js'
else
    let s:template = 'javascript.js'
endif
execute '0read ' . s:template
  • filename-modifiers
    • :help すれば済むハナシなんだけど知らないと :help のしようもないのでメモ。 expand() 関数で "%" や "#" なんかを展開するときに ":p" ( full path ) だとか ":h" ( heading path ? filename をのぞいた direcitory path ) だとかの修飾子を指定することができる。 script とかでその buffer で編集してる file の名前だけとか拡張子名だけが欲しいという場合にすごい有用。
  • :let-&
    • option の値は set opt? で参照して set opt / set opt=val なんかで設定したりするのが普通だけど option 名の最初に "&" をつけると普通の変数と同じように扱うことが出来る。 script を書くときはこれ知らないとツライ、というかたぶん常識なんだと思う。
    • 大体とりあえず "&" をつけておけば問題ないんだけどたまに local / global を意識しないといけない。そのときは setlocal と setglobal に相当する prefix がそれぞれ "&l:" と "&g:" なのでこれを使う。以下のようにすると実行した buffer だけ 'path' を変えられる ( expand() やらの関数を使う必要がない場合は普通に :set を使うのが楽 ) 。
" refer ":help filename-modifiers" about '%:p:h'
let &l:path = expand('%:p:h') . ',' . &l:path
  • split()
    • major な scripting language をいじってるなら説明のいらない超絶便利関数。 vim は list まわりの操作が最近の scripting language と同じ感覚で行えるのでとりあえず split() とかで list に変換しとく、で大体問題ないみたい。
    • あらかじめ file path が与えられてて上記の filename modifier が使えない場合とか expand() や glob() なんかで wild card を展開した場合に以下のように処理するのが定型、かな ?
" get extension name
let b:file = 'foo.txt'
let b:ext = split(b:file, '\.')[-1]

" expand wild card and process each files
for b:file in split(expand('*'), '\n')
    " some codes
endfor
  • Windows 端末上で動いてるかどうかの判別
    • UNIXLinux かどうかってのはあんまり考えなくていいみたい。というのも元々想定してるのが UNIX / Linux 上で C 言語を使った開発なのでほとんどの機能がそれにあうように設計されているから、かな。なので Windows だとか他の platform で使う際の例外処理をつらつらと書いていけばいいわけだね。
if has('win32')
    " some codes
endif