Panda Noir

JavaScript の限界を究めるブログでした。最近はいろんな分野を幅広めに書いてます。

Defx.nvim でプレビューウィンドウを自動的に閉じる

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関数はこちらを参考にして、一部動かなかった箇所を修正しています。