0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Perlの関数名をPowerLine上に表示する

Last updated at Posted at 2015-01-03

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行目の全行数取得、他にコストの安い方法がありそう
    • 正規表現周りが微妙。.*?に相当するらしい.{-}が動かなかったりで多分関数が入れ子になっているとうまく機能しない
  • プラグイン形式になっていない

まあぼちぼち使いつつ直して行こうかな

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?