VimエディタでもアニメーションGIFが再生したい!
と、いうことで簡単にやってみました。
[必要なもの]
- convert
- afterimage.vim
[動作]
こんな感じ。
基本的には mattn さんのやつと同じ仕組です。
gif データを convert で xpm に変換して1つずつ描画しているだけですね。
ぶっちゃけ結構無理やりやっているのでそんなにパフォーマンスは良くないです。
48x48 ぐらいのサイズであれば割とスムーズにアニメーションが再生されると思います。
(アニメーション数が多くても初期化が遅いだけで再生自体はそれほど問題にならないはず、多分。
あとそのままだと半角で縦長になってしまうので2文字ずつ表示させるようにしています。
両端の " も conceal で消そうとしたんですが、うまく設定できなかったので断念。
これは消したかったんだけどなぁ。
[おまけ]
こちらの gif ファイルを再生させるとこんな感じになります。
若干もっさりしている気がしますが、ちゃんと再生出来ていますね。
ちなみにこの gif ファイルだとアニメーション数が多いので、表示されるまでにだいぶ時間がかかります。
[ソースコード]
let g:xpm_output_directory = $TEMP let g:xpm_wait_ms = 10 function! s:write(data) let i = 0 for line in a:data call setline(i, line) let i += 1 endfor endfunction function! XpmFileSorter(...) return \ len(a:1) > len(a:2) ? 1 \ : len(a:1) < len(a:2) ? -1 \ : a:1 == a:2 ? 0 \ : a:1 > a:2 ? 1 \ : a:1 < a:2 ? -1 \ : 0 endfunction function! s:gif_to_xpm(gif) let name = fnamemodify(a:gif, ":t:r") let output_dir = g:xpm_output_directory."/".name let output = output_dir."/".name if !isdirectory(output_dir) call mkdir(output_dir) call system("convert ".a:gif. " " . output.".xpm") endif return sort(split(glob(output."-*"), "\n"), function("XpmFileSorter")) endfunction function! s:twice_line(line) return join(eval(join(map(split(a:line, '\ze.'), "v:key != 0 && v:key != len(a:line)-1 && v:key != len(a:line)-2 ? [v:val, v:val] : [v:val]"), "+")), "") endfunction function! s:gif_animation(file) if !executable("convert") echoerr "Please install convert" return endif if !filereadable(a:file) echoerr "Not Fount ".a:file return endif if !isdirectory(g:xpm_output_directory) echoerr "Invalid g:xpm_output_directory : " . g:xpm_output_directory return endif let gif = a:file let xpms = map(s:gif_to_xpm(gif), "readfile(v:val)") let images = map(map(copy(xpms), "v:val[index(v:val, '/* pixels */') : len(v:val)-2]"), "map(copy(v:val), 's:twice_line(v:val)')") let images_num = len(images) setlocal conceallevel=2 setlocal concealcursor=n highlight clear Visual highlight clear Cursor let i = 0 while 1 call s:write(xpms[i % images_num]) set ft=xpm syntax match XPM_INV /,/ transparent conceal syntax match XPM_INV2 /"/ transparent conceal silent %d _ call s:write(images[i % images_num]) normal! G redraw if g:xpm_wait_ms execute "sleep" g:xpm_wait_ms."ms" endif let i += 1 endwhile endfunction command! -nargs=1 -complete=file \ GifAnimationTab \ tabnew | call s:gif_animation(<q-args>)