【Vim】新しい Denite に爆速で対応する

[Denite][] の新しいバージョン **v3** が出ましたね！ みんなもう早速更新して vimrc も５万行くらい書いてますよね！

[Denite]: https://github.com/Shougo/denite.nvim

この記事では変更内容を（勝手に）紹介しつつ、おすすめ設定も書いていきたいと思います。

| Denite v3           |
|---------------------|
| ![DelBSPcFbe.gif][] |

[DelBSPcFbe.gif]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8880/055c63ee-e9b9-e1bc-b26b-202788574b42.gif

比較のために古いバージョンでほぼ同じことやってみました。

| Denite v2           |
|---------------------|
| ![Y55Louv6UO.gif][] |

[Y55Louv6UO.gif]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8880/0b193bf1-ee61-2a77-09ec-e143e0df3706.gif

違いがわかるでしょうか。見た目でいちばんの違いは、filtering（絞り込み）のためにキーを打つとき補完候補が出ていることです。これにより目当ての候補にたどり着きやすくなっています。

以下、見ただけではわからない変更点も含めて書いていきましょう。

## 変更点その１ 標準ではキーマッピングが提供されなくなった

いちばん重要な変更点です。インストールした時点では filtering を開始するマッピングすら存在しません。ドキュメントを読んで設定しましょう。

```vim
" 一部を抜粋しています。完全版はドキュメントを参照してください
autocmd FileType denite call s:denite_my_settings()
function! s:denite_my_settings() abort
  " filtering ウィンドウを開く
  nnoremap <silent><buffer><expr> i       denite#do_map('open_filter_buffer')
  " Denite を閉じる
  nnoremap <silent><buffer><expr> q       denite#do_map('quit')
endfunction
```

Denite のメインウィンドウは `denite` という filetype を持っています。そのウィンドウでのみ使えるマッピングを設定しているわけですね。

## 変更点その２ filtering のためにコマンドラインではなく、専用のウィンドウを使うようになった

今までは、filtering を開始するとき画面最下部のコマンドラインを利用していました。今回のバージョンでは代わりに、メインウィンドウの下側に新しいウィンドウを開くように UI が変わりました。

これにより、以下のような利点がもたらされます。

### 補完が効く！

<img width="394" alt="スクリーンショット 2019-06-01 17.15.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8880/5d830ba4-7a41-c5af-c8d2-8d32f3666706.png">

filtering ウィンドウで開いているのは `denite-filter` という filetype を持つ普通の buffer です。Denite にはこの filetype で使うための [Deoplete][] source が用意されており、選択対象を絞り込むための文字列を補完候補として出してくれます。これが思いの外快適で、少ないキーストロークで目的の候補に辿り着けるようになりました。

[Deoplete]: https://github.com/Shougo/deoplete.nvim

### マッピングなどのカスタマイズが自由にできる！

普通の buffer であるということは、自由なカスタマイズが可能になったということでもあります。標準では <kbd>Enter</kbd> にのみ、「入力を終えて filtering ウィンドウを閉じる」というマッピングが提供されています。必要に応じて設定してみましょう。

```vim
autocmd FileType denite-filter call s:denite_filter_my_setting()
function! s:denite_filter_my_setting() abort
  " 一つ上のディレクトリを開き直す
  inoremap <silent><buffer><expr> <BS>    denite#do_map('move_up_path')
  " Denite を閉じる
  inoremap <silent><buffer><expr> <C-c>   denite#do_map('quit')
  nnoremap <silent><buffer><expr> <C-c>   denite#do_map('quit')
endfunction
```

ここでは僕が実際に利用しているマッピング（の一部）を載せました。ただ基本的に、filtering ウィンドウは絞り込みのためだけに使うことを想定されています。あまり複雑なことはできないので注意しましょう。

### [Neovim] floating window 利用時に視線の移動が少なくなった

Neovim に搭載された **floating window** という機能をご存知でしょうか？ 従来の Denite は起動すると画面下部に候補を羅列するため、どうしても視線を下に動かさざるを得ませんでした。画面の大きな端末ではこれが不便だったんですよね。floating window を利用することにより、画面上の好きな場所に Denite を登場させることができるようになりました。

* [denite.nvimのFloating Windowオプションを使おう - Qiita](https://qiita.com/lighttiger2505/items/d4a3371399cfe6dbdd56)

ただこれまでは、filtering のためにどうしても視線の移動が発生していました。これが今バージョンでは軽減されたのです。

| Denite v2     | Denite v3     |
|---------------|---------------|
| ![denitev2][] | ![denitev3][] |

[denitev2]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8880/87336104-da68-ec74-bd1a-0be73978f489.png
[denitev3]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8880/9ff31ac9-2da2-6d6c-cb45-c483b01fad4f.png

こうしてみるとスッキリしてますね！

## その他の注意点

今回のバージョンでは内部構造にもかなり手が入っています。上述のマッピング以外、ユーザーが設定を変更すべき点はないのですが、もし Denite と連携するようなプラグインを使っている場合はそちらで修正が必要な場合があります。

具体的には、ステータスラインに関する変更です。Denite はメインウィンドウ、filtering ウィンドウそれぞれに特殊なステータスバーを表示しています。

<img width="896" alt="スクリーンショット_2019-06-01_15_58_44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8880/990307d4-d951-e2f0-78c8-4e9b2330ec07.png">

これが [Airline][] や [Lightline][] といったプラグインを使っているとバッティングしてしまいます。すでに Airline には Denite v3 用の修正が入っていますので、最新版にするとエラーが起きないでしょう。僕は Lightline を使っているのですが、カスタムテーマとして公開している [lightline-delphinus][] でも対応しておきました（[修正差分の PR][pr]）。

[Airline]: https://github.com/vim-airline/vim-airline
[Lightline]: https://github.com/itchyny/lightline.vim
[lightline-delphinus]: https://github.com/delphinus/lightline-delphinus
[pr]: https://github.com/delphinus/lightline-delphinus/pull/18

* [delphinus/lightline-delphinus: Yet another theme for lightline](https://github.com/delphinus/lightline-delphinus)
  - [Lightline で ALE を使って非同期文法チェック - Qiita](https://qiita.com/delphinus/items/af5809b587f2af0a9f7f)

<img width="894" alt="スクリーンショット 2019-06-01 16.17.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8880/79d46f78-93dc-be22-882f-e5b70ef42143.png">

こんな感じです。ただ floating window を使っている場合は、そもそもステータスラインが存在しません。この場合はターミナルのタイトルに、ステータスラインにあたる文字列を表示するようになっています。

<img width="692" alt="スクリーンショット 0001-07-13 8.29.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8880/db930f6a-e245-2ad1-7a77-b977bf7b045b.png">

これは tmux のステータスラインにウィンドウのタイトルを表示した例です。[`'titlestring'` オプション][titlestring]を使って実装されていますので、うまく表示されない方はリンク先のドキュメントを読んでみてください。

[titlestring]: https://vim-jp.org/vimdoc-ja/options.html#'titlestring'

## まとめ

最近 VSCode に押され気味な Vim 界ですが、特に Neovim の登場以降、エンドユーザーにも影響のあるような UI/UX の改善が進んでいます。今回の Denite v3 は最近の流れを受けた、その集大成といっていいでしょう。

上に挙げた変更点を含め、Denite v3 に対応するために修正した dotfiles を以下に PR として記録しています。新しい Denite を使う時に参考にしてください。

* [Adapt here to Denite v3 by delphinus · Pull Request #5 · delphinus/dotfiles](https://github.com/delphinus/dotfiles/pull/5)