vimのシンタックス/インデント自作

大学の授業でLiLFeSという非常にマニアックな言語(ほとんどProlog)をやるのですが、当然シンタックスもインデント規則も定義されていません。
prolog.vimをそのまま使ってもいいのだけれど、せっかくなので自作してみました。
http://mad-projects.iobb.net/misc/lilfes_vim.tar.gz

シンタックス定義ファイル

vimを起動して

:help

を実行して出てくるページの中の

|usr_44.txt| Your own syntax highlighted

に作り方が書いてありました。
基本的には正規表現を使用してマッチするところに色を付けるというだけなので簡単でした。

syn case match "小文字と大文字を区別する

syn keyword     lilKeyword      module pred
...
"正規表現で完全一致するパターン
syn match       lilNumber       +\<[0123456789]*\>+
...
"start, endに一致する部分に囲まれたパターン
syn region      lilCComment     start=+%/\*+ end=+\*/+
" "hogehoge\"hugahuga\"" みたいな文字列のパターンで中の\"にendがマッチしないようにする
syn region      lilString       start=+"+ skip=+\\"+ end=+"+
"containsで指定したパターンが中に含まれる場合にそれを別に色分けする
"matchgroupはstart,endの中までは色分けしないという指定
syn region      lilArray        matchgroup=lilParen start=+\[+ end=+\]+ 
contains=lilArray,lilNumber,lilString,lilVariable,lilAny

"画面に表示されている部分より50行前まで探索の範囲とする
syn sync maxlines=50

command -nargs=+ HiLink hi def link <args>

"上でマッチしたパターンは右で定義されている種類とみなされて色が付けられる。
"color schemeに基づいてStringやNumberに割り当てる色が決められる。
HiLink lilString        String
HiLink lilNumber        Number
...

delcomman HiLink

インデント定義ファイル

helpからたどれるfiletype.txtの中に書いてありました。

"インデントのルール
setlocal indentexpr=GetLilfesIndent()

"以下のキーが押された場合は前の行を読んでインデントの調整が自動的に行われる
setlocal indentkeys-=:,0#
setlocal indentkeys+=0%,-,-;,>,0)

function! GetLilfesIndent()
  let pnum = prevnonblank(v:lnum - 1)
  if pnum == 0
    return 0
  endif
  let line = getline(v:lnum)
  let pline = getline(pnum)

  " 現在のインデント幅
  let ind = indent(pnum)
  
  ...
  
  " 前の行が正規表現に一致する場合に次の行のインデント幅を調整する。&swはshift widthの略。
  " Check for clause head on previous line
  if pline =~ ':-\s*\(%.*\)\?$'
    let ind = ind + &sw
  " Check for end of clause on previous line
  elseif pline =~ '\.\s*\(%.*\)\?$'
    let ind = ind - &sw
  endif
  return ind
endfunction

インストール

これらをインストールするときは$HOME/.vim/{syntax, indent}以下にlilfes.vimという名前で2つのファイルを置いて,/usr/share/vim/vim70あたりにあるfiletype.vimの中に

" Prolog
au BufNewFile,BufRead *.pdb                     setf prolog

" LiLFeS
au BufNewFile,BufRead *.lil                     setf lilfes

こんな感じで追加すると自動的にファイルタイプを識別し対応する名前のシンタックス/インデントファイルをロードしてくれるようです。