vimfiler でファイルのアイコンを表示させてみた

TweetVim のアイコン表示を見ていて
『vimfiler でもファイルのアイコンを表示させれば面白いんじゃないか』
って事で簡単に表示させてみました。
とりあえず、こんな感じ。

[vimfiler]

[ソース]

let s:icons = {
\   "vim" : "D:/vimfiler_icon/vim.ico",
\   "png" : "D:/vimfiler_icon/png.ico",
\   "folder" : "D:/vimfiler_icon/folder.ico",
\   "empty" : "D:/vimfiler_icon/empty.ico",
\}

function! s:is_directory(word)
    return a:word[ len(a:word)-1 ] == "/"
endfunction

function! s:icon_name(word)
    let attr = s:is_directory(a:word) ? "folder" : fnamemodify(a:word, ':e')
    return has_key(s:icons, attr) ? attr : "empty"
endfunction

function! s:sign_name(word)
    return "vimfiler_icon_".s:icon_name(a:word)
endfunction

function! s:sign_define_icon(word)
    let icon = get(s:icons, s:icon_name(a:word), s:icons.empty)
    let exec =  ":sign define ".s:sign_name(a:word)." icon=".icon." text=X"
    execute exec
endfunction


function! s:sign_place_icon(line, word)
    execute ":sign place ".a:line." line=".a:line." name=".s:sign_name(a:word)." buffer=" . bufnr("%")
endfunction

function! s:sign_unplace_all()
    let lines = map(filter(map(range(1, line("$")), '{
\       "word" : s:get_filename(getline(v:val)),
\       "line" : v:val
\}'), "!empty(v:val.word)"), "v:val.line")
    for line in lines
        execute "sign unplace ".line." buffer=".bufnr("%")
    endfor
"     :sign unplace *
endfunction

function! s:get_filename(word)
    return matchstr(a:word, '^\s*\(|-\||+\|+\|-\) \zs\S*\ze')
endfunction

function! g:vimfiler_icon_update()
    call s:sign_unplace_all()
    call map(filter(map(range(1, line("$")), '{
\       "word" : s:get_filename(getline(v:val)),
\       "line" : v:val
\   }'), "!empty(v:val.word)"), "s:sign_define_icon(v:val.word) || s:sign_place_icon(v:val.line, v:val.word)")
endfunction


まぁ面白いけど、分かりやすいかと言われれば……微妙かな?
需要があるかは分からない。
ざっくりコード書いてみたんですが、問題点が幾つか。

1.アイコンを動的に更新出来ない

vimfiler は動的にディレクトリを移動したり、ディレクトリを作成したり出来るのですが、そのタイミングでアイコンを更新する処理を呼び出す事が出来ない(やり方が分からない。
何か適当な autocmd にでも設定できればいいんだけどもどうするか。
ここは vimfiler 側に直接埋め込んでしまう方がいいのかなぁ…。

2.ファイルからアイコンの取得

上記の場合は予めアイコンを幾つか用意しておいて、拡張子で判別して使用するアイコンを決定しているんですが、システムで使用されているファイルのアイコンを直接使いたいですね。
これは、問題点というか課題かなぁ。
プラットフォーム依存しそうなので難しそう…。

3.ファイル名にスペースがある場合パースがうまく行かない

現状、vimfiler のバッファに表示されているテキストから直接拡張子をパースしているんですが、スペースがある場合にうまく行かなかったりします。
これも vimfiler 側で直接処理してしまえば、生のデータが使えると思うのでそうしたほうがいいかもしれない。


と、いう感じでガーッと書いてみました。
コードがいろいろとアレなのはお察しください。
続けるかどうかは不明。
あと sign を削除辺りがすごく怪しい。