VimScript本を買っていた
これ
買って詰んでいたので、正月休みがてら(といっても2時間程度)で読んでいました。
せっかくなので習作がてら、Perlで今いる場所の関数名とパッケージ名を表示するコードを書こうかと思い立ち書いてみた。
let g:getFunctionName = {}
function! g:getFunctionName.getFileFunctionRows() dict
let filename = expand("%")
let self[filename] = []
let lines = readfile(filename)
let maxline = len(lines)
let status = ''
let statusStack = []
for rowcount in range(1 , maxline)
let line = getline(rowcount)
if line =~ '\vpackage\s*(.*);'
let matchlist = matchlist(line , '\vpackage\s*(.*);')
let packageName = matchlist[1]
let status = packageName
" package ~~;の記法は上書きなので
if len(statusStack) && statusStack[-1] != "package"
call add(statusStack , "package")
end
elseif line =~ '\vpackage\s*(.*)\{'
let matchlist = matchlist(line , '\vpackage\s*(.*)\{')
let packageName = matchlist[1]
let status = packageName
call add(statusStack , 'package')
elseif line =~ '\vsub \s*(.*)\{'
let matchlist = matchlist(line , '\vsub \s*(.*)\{')
let subName = matchlist[1]
if status == ''
let status = subName
else
let status = status . '->' . subName
endif
call add(statusStack , 'sub')
elseif line =~ '\v\{.*\}'
elseif line =~ '\v\{'
call add(statusStack , 'other')
elseif line =~ '\v\}'
let removed = remove(statusStack , -1)
if removed == "sub"
if status =~ '->'
let status = substitute(status , '->.*$' , '' , '')
else
let status = ''
endif
elseif removed == "package"
let status = ''
endif
endif
call add(self[filename] , status)
endfor
endfunction
function! g:getFunctionName.getFunctionName() dict
let filename = expand("%")
let linenumber = line('.')
return self[filename][linenumber - 1]
endfunction
function! s:newGetFunctionName()
return copy(g:getFunctionName)
endfunction
let obj = s:newGetFunctionName()
autocmd CursorMoved *.pl,*.pm set statusline=%{obj.getFunctionName()}
autocmd BufRead *.pl,*.pm call obj.getFileFunctionRows()
要件
- 現在の行がパッケージの中の場合にはパッケージ名を表示
- Perlのpackage宣言、package Hoge;とpackage Hoge{}の両方の記法に対応する
- 関数内の場合には関数名を表示
- PowerLine上に表示
作ってみて問題があって解決された点
- スコープとか詳細に書いてあってよかった
- autocmdとかなんとなく使ってたものが詳しくわかった
autocmd {event} {pattern} {command}
- OOPな書き方、dictの使い方等は本を読まないと投げていたかなと思う
まだ問題がある点
- PowerLineの他の全ての項目を削除して関数名だけ出しているので使い物にならない
- 57行目の全行数取得、他にコストの安い方法がありそう
- 正規表現周りが微妙。.*?に相当するらしい.{-}が動かなかったりで多分関数が入れ子になっているとうまく機能しない
- プラグイン形式になっていない
まあぼちぼち使いつつ直して行こうかな