Defx.nvim には floating window を使ったイカしたプレビュー機能があります。しかし、何も設定をしていないと、defx を閉じたあともプレビューウィンドウは残ります。この記事は autocmd を活用してプレビューをうまく消そうという記事です。
Defx を閉じたタイミングを取得する
Defx.nvim のウィンドウを閉じると同時にプレビューウィンドウを閉じるには、ウィンドウが閉じたことを検知する必要があります。ウィンドウが閉じたときに発火するイベントはいくつかあります。
- BufLeave
- BufHidden
- BufEnter(ほかのウィンドウに入った=前のウィンドウを離れたとみなせる)
Defx は独自に DefxClosed のようなイベントを発火しないので、これらを使わなければなりません。今回はBufHidden を使います。
BufHidden が発火したときに pclose (プレビューウィンドウを閉じるコマンド)を実行すればやりたいことが実現できます。
(BufLeave ではプレビューウィンドウを開いたタイミングにも発火するのでうまくいきません。また、BufEnter は defx のウィンドウが閉じられたのかを検知できません)
autocmd BufHidden \[defx\]* pclose
これで defx#do_action('quit')
などで閉じればプレビューウィンドウも消えます。
ついでに: Gitのプロジェクトルートで defx を開く
あまりに記事のボリュームが少ないので、ついでに全く関係ない Tips をいくつか盛っておきます。
Defx はデフォルトでは現在のディレクトリを表示します。しかし、プロジェクトルート(.gitなどのある位置)で開いたほうが便利ですよね?というわけで、 DefxProjectFile()
という関数を作りました。といってもほとんど fzf のリポジトリにある ProjectFiles を参考に書いただけですが。
nnoremap <silent> ,f :Defx `system('git rev-parse --show-toplevel 2> /dev/null')[:-2]` -search=`expand('%:p')`<CR>
ウィンドウが defx のみになったら vim を終了
quit をしてもファイラーウィンドウが残ってしまうのが嬉しいことはほとんどないので、ファイラーウィンドウのみになったら quit を実行するようにしてみました。
function! s:previewWindowOpened() abort for nr in range(1, winnr('$')) if getwinvar(nr, "&pvw") == 1 return 1 endif endfor return 0 endfunction autocmd WinEnter \[defx\]* if winnr('$') == 1 || winnr('$') == 2 && <SID>previewWindowOpened() | quit | endif
WinEnter が発火したとき、 defx のウィンドウのみ、あるいは defx ウィンドウとプレビューウィンドウのみだったら終了します。
previewWindowOpened関数はこちらを参考にして、一部動かなかった箇所を修正しています。