:help searchpairpos
searchpairpos({start}, {middle}, {end} [, {flags} [, {skip} [, {stopline} [, {timeout}]]]]) |searchpair()|と同様だが、マッチの行番号と桁番号からなるリスト |List|を返す。このリストの最初の要素は行番号で、次の要素はマッ チの桁位置のバイトインデックスである。マッチが見つからなかった 場合は[0, 0]を返す。 > :let [lnum,col] = searchpairpos('{', '', '}', 'n') より大規模で役に立つ例に関しては|match-parens|を参照。
このあたりを使えば入れ子も考慮して見つけられるらしい。
ただ、Ruby は if に対応するのも end だし、do に対応するのも end なのだ。何か解決できる関数があるのかもしれないけど、synIDattr を使って検索するようにしてみた。30 分ぐらいのやっつけ。
command! Pair :call s:search_pair() function! s:search_pair() let word = expand('<cWORD>') if word == 'def' let flg = 'n' elseif word == 'end' let flg = 'b' else return endif while (line('.') != 0 || line('.') != line('$')) let pos = searchpairpos('\s\{}\zsdef\ze', '', '\s\{}\zsend\ze', flg) if pos == [0,0] let line = line('.') + (flg == 'n' ? 1 : -1) call cursor(line,col('.')) continue endif call cursor(pos[0],pos[1]) let attr = synIDattr(synID(line('.'),col('.'),1),'name') if attr == 'rubyDefine' break endif endwhile endfunction
他言語でも使えるように汎用的にするのは無理ぽいんだけど・・・。