Self Reference

Are you receiving this?

MacのVimでBGMを聴く

Vim Advent Calendar 318日目の記事です。
365日更新も目前です。Vimmerの2012年はまだ明けません。

昨日は@unmoremasterさんのページング・エラーでした。皆様ご存知の通り、Vim小説というジャンルを切り開いた方です。今後のご活躍に目が離せません。

さて、今回もMacのお話です。

私の家では音楽データをNASに溜め込んで、いろんなPCからネットワーク経由で再生できるようにしています。
再生はVimから行います。VimfilerがあればネットワークパスもVimから開けるので、NAS内へ移動して音楽ファイルにxを実行し、システムで関連づけられたプログラムで再生しています。しかしその都度GUIがポップアップするので、バックグラウンドで再生できればいいなあと思っていました。

Vimfilerはunite.vimと融合しているので、コマンドラインで音楽を再生できる環境があれば、そのコマンドへ処理を投げるactionをuniteに定義し、Vimfilerからactionを呼べば実現できそうです。

MacOSXにはafplayという素敵なコマンドが入っているようでした。

なんだかやれそうな気がしてきたので、.vimrcに設定してみることにしました。

事前にインストールが必要なもの

設定する

[再生機能]

まずuniteのactionを定義します。

1
2
3
4
5
6
7
let s:start_afplay= {'is_selectable': 0}
function! s:start_afplay.func(candidate)
  call vimproc#system_bg("killall afplay")
  call vimproc#system_bg('afplay -q 1 ' . '"'.a:candidate.action__path.'"')
  echo "Playing... " . a:candidate.vimfiler__filename
endfunction
unlet s:start_afplay

’s:start_afplay’は、afplayコマンドに’candidate’を投げて処理させるfunctionにします。 ‘candidate’はuniteが用意してくれます。’candidate’がどんなプロパティを提供しているかは、functionの中で’echo candidate’とかするとわかります。
afplayコマンドはvimproc#system_bgを通して実行しています。でもafplayじゃなくてもよい気がします。

続いてuniteに’s:start_afplay’を登録します。

1
call unite#custom_action('file', 'afplay', s:start_afplay)

これで、uniteの’file’ kindに、’afplay’という名で、’s:start_afplay’ functionが定義されました。

[停止機能]
1
2
3
4
function! s:stop_afplay()
  call vimproc#system_bg("killall afplay")
endfunction
command! StopAfplay call s:stop_afplay()

いわゆる’ボスが来た’ functionです。
killallが不格好なのはご容赦ください。

[キーマッピング]

‘af’で再生、’fa’で停止するようにしてみました。

1
2
autocmd! FileType vimfiler nnoremap <buffer><expr>af vimfiler#do_action('afplay')
nnoremap <silent>fa :<C-u>StopAfplay<CR>

設定全体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
" 再生する
let s:start_afplay= {'is_selectable': 0}
function! s:start_afplay.func(candidate)
  call vimproc#system_bg("killall afplay")
  call vimproc#system_bg('afplay -q 1 ' . '"'.a:candidate.action__path.'"')
  echo "Playing... " . a:candidate.vimfiler__filename
endfunction
call unite#custom_action('file', 'afplay', s:start_afplay)
unlet s:start_afplay

" 停止する
function! s:stop_afplay()
  call vimproc#system_bg("killall afplay")
endfunction
command! StopAfplay call s:stop_afplay()

" キーマッピング
autocmd! FileType vimfiler nnoremap <buffer><expr>af vimfiler#do_action('afplay')
nnoremap <silent>fa :<C-u>StopAfplay<CR>

これでVimからBGMを再生できるようになりました!

課題

  • 対応していないファイル形式(flac, oggとか)に実行した場合エラーをだす。
  • ファイル名にダブルクォーテーションがあった場合でもうまい具合に再生する。
  • 連続再生できるようにする。
  • Mac以外でも再生できるようにする。

謝辞

当初掲載したコードはuniteのaction定義で’is_selectable’を1にしていて、この場合対象ファイルを複数選択できるようになっていましたが、@osyo-mangaさんが教えてくださり、’is_selectable’が0になるよう修正いたしました。ありがとうございました!

参考にさせていただいたページ

http://hrsh7th.hatenablog.com/entry/20120229/1330525683
http://d.hatena.ne.jp/osyo-manga/20131006/1381065976
http://d.hatena.ne.jp/osyo-manga/20130512/1368370556
http://d.hatena.ne.jp/osyo-manga/20130520/1369049201
http://kuchitama.hateblo.jp/entry/2013/02/08/000320

まとめ

Vimはエディタであり、ブラウザであり、音楽プレイヤーでもあり、つまり良き配偶者だったのです。

明日は@akira_simpsonさんです。