🥺

jeetsukumaran ware 3 選

2020/12/12に公開

イントロ

この記事は Vim Advent Calendar 12 日目の記事です。
今年も全力で他人の成果物に乗っていく。

Jeet Sukumaran さんという方をご存知だろうか。
この方の作るプラグインが自分にとても合っているので、その紹介をしようと思う。

TL;DR

出来る事がそれぞれ限られている、またポップアップだのなんだの最近の Vim の機能はなく、
どちらかというと無骨な見た目のプラグイン達だが動作は非常に速くて便利。

FileBeagle

1 つ目。

https://github.com/jeetsukumaran/vim-filebeagle

軽量なファイラー。
vim-dirvish の元ネタ。
vim-molder と同じくらい機能が削ぎ落とされてる。
doc にあるようにファイルのコピー/削除/移動/リネームはできない(ファイルの追加はできる)。
それ以外は OS の機能を使えとある。

mattn さんが
https://zenn.dev/mattn/articles/1da58d6ee91a8e36e690
に書かれてるように、

  • :e /path/to/ でファイラ開きたい
  • $ vim /path/to/ でファイラを開きたい
  • ファイルの一覧を速く表示して欲しい

というのは同感で、それを満たしてる。
あとちょっと特徴的なのが FileBeagle を開いて f を押すとフィルターがかけられる。
便利。

おしゃれなアイコンとかツリーが欲しい?そういう場合は fern.vim を使えばいいと思う。

Buffersaurus

2 つ目。

https://github.com/jeetsukumaran/vim-buffersaurus
buffer の中だけを grep してくれるやつ。

#vimtips_ac の自分の担当で書いたけど、現在開いている buffer の中を検索して一覧をカジュアルに出すのは、
[I を使えばいいけど、開いている全てのバッファーを検索したい場合に便利。

バッファーにある main という文字を全て検索し、一覧に出してそこに飛んでる様子。

vimrc に

nnoremap ,bs :execute ':Bsgrep ' . expand('<cword>')<CR>

とでも書きておけば検索したい単語の上で ,bs と打つと現在開いてるバッファーの中を全部調べてくれる。
便利。

Buffergator

3 つ目。今回紹介する中で一番気に入ってるバッファー管理のプラグイン。
https://github.com/jeetsukumaran/vim-buffergator

Vim のデフォルトの :ls してバッファー番号を覚えて :buffer [N] はシンプルすぎるし、
fzf とかにもバッファー管理のもあるけど、深いところにファイルを置いてたりすると、何のファイルかわかりづらいことがある(ウィンドウ幅を 80 にしてるのが原因だけども)。
:ls や fzf の :Buffers だと末尾が切り取られて何のファイルかわからない。


(極端な例だが、末尾が省略されていてわからない)

バッファー管理に求めるのは

  • 高速で開く
  • 何のファイルかパッとわかる(ファーストビューにほしい)
  • 不要なバッファーを消せる(fzf の :Buffers だとできない?)
    • Buffergator は d を入力すればバッファーが消える

そのほかにもプレビューが欲しいとかはあるが、素早く一覧を開いて、選択したい。
この Buffergator はそういった自分の要望をドンピシャに解決してくれる。

スクリーンキャストにあるようにファーストビューにファイル名が来てそのあとにパスが表示される。
(これは cd と入力することで見た目を切り替えることが可能)

行を選択し、<CR> でそのバッファーを表示してくれる。
また バッファー番号 + 何かのキーを入力すればそのバッファー番号に関するアクションを行う。
例えば 3 + O でバッファー番号 3 をプレビュー開く。
6 + <CR> でバッファー番号 6 のバッファが開く(vsplit や tab も可能)。

こんな感じで素早くアクセスできる。
便利。

ハックする

さらに便利にしたいと思う。
FileBeagle は f を入力するとファイル名をフィルターできるが、Buffergator にはそのようなオプションはない。
検索したいのなら / で検索で十分ということかもしれないが、
せっかくなので、ちょっとしたハックをしてインクリメンタルなフィルターをつけたい。

Buffergator が開いているのはただの Vim のバッファーなので、文字を入力したら、
その入力した文字にマッチしたファイルを残せば良い。
簡易的にフィルターするのは vim-jp でハックする技が投稿されていたので拝借する。

Buffergator を開き <Leader>/ を入力するとプロンプトが表示される。
ファイル名を入力するとバッファーの中をインクリメンタルにフィルターされる。
m を入力するとフィルターされたバッファーを開く。

" Original code was posted to vim-jp.slack.com
" author: https://github.com/kuuote
function! s:buffergator_filter() abort
  let lines = copy(s:lines)
  let text = getcmdline()
  call filter(lines, {_, val -> val =~? text})
  setlocal modifiable
  silent 1,$delete _
  silent 0put=lines
  $d
  setlocal nomodifiable
  call cursor('$', 1)
  redraw
endfunction

function! s:buffergator_cmd() abort
  autocmd FuzzyBuffgator CmdlineChanged * call s:buffergator_filter()
  call input('buffergator: ')
endfunction

augroup FuzzyBuffgator
  autocmd!
  autocmd CmdlineLeave * autocmd! FuzzyBuffgator CmdlineChanged
augroup END

function! s:read_buffergator_buffer(timer) abort
  let s:lines = getline(1, '$')
endfunction

function! s:buffergator_init() abort
  call timer_start(0, function('s:read_buffergator_buffer'))
endfunction

function! s:buffergator_enter() abort
  let line = getline('.')
  let bufnum = matchstr(getline('.'), '^.*\[\zs.*\ze\]')
  execute 'bdelete | wincmd w | '. 'buffer ' . trim(bufnum)
endfunction

autocmd FileType buffergator call s:buffergator_init()
autocmd FileType buffergator noremap <silent> <buffer> <Leader>/ :<C-u>call <SID>buffergator_cmd()<CR>
autocmd FileType buffergator noremap <silent> <buffer> m :<C-u>call <SID>buffergator_enter()<CR>

Buffergator のバッファーは内部で行とバッファー番号をマッピングしているものを持っている。
絞り込んで <CR> を入力しても、該当行にマッピングされたバッファー番号が読み込まれて、開いてしまう。
そのため意図しないバッファー番号が開いてしまう。
本来ならそのマッピングしているものにアクセスできればいいのだが、外部から容易にアクセスできない。

function! s:buffergator_enter() abort
  let line = getline('.')
  let bufnum = matchstr(getline('.'), '^.*\[\zs.*\ze\]')
  execute 'bdelete | wincmd w | buffer ' . trim(bufnum)
endfunction

これを回避するには上記のコードのように現在行の表示されているバッファー番号を読み取って、開いてやればいい。

こういうのが Buffergator 本体の魔改造抜きに実現できるのは単純に Vim のバッファーに表示されているからで、カジュアルにいじって自分好みにできるのはとても良く便利。

結論

どれも無骨だが軽量でハックしやすくてとても良いので、とにかく軽量なのが欲しい方にお勧め。

Discussion