coc.nvimの多機能セレクタ(CocList)の検索をfzfにやらせるプラグイン

#序文と紹介
以前 [この記事](https://qiita.com/Amadeus_vn/items/5dfcf8d3676c2c5576ef) で `coc.nvim` について紹介させていただきました。

`coc.nvim` の機能の1つに `CocList` というものがあります。
<details><summary>CocListの機能についてはこちら</summary>extentionのトグル、diagnosticsのリスト表示とジャンプ、symbolの検索などを呼び出すメニュー機能です</details>

ただし、CocListの候補検索部分が少し重いようで、検索先の候補が多いと重くなっていました。
これをGo製のあいまい検索ツール [fzf](https://github.com/junegunn/fzf) にやらせることで軽快にするNeoVimプラグインを見つけましたので紹介させていただこうと思います。

# セットアップ
## インストール
[ここ](https://github.com/antoinemadec/coc-fzf) にVimプラグインがあるのでそれぞれのプラグインマネージャでインストールしてください。
### vim-plugを導入済みの場合
ぼくは `vim-plug` なので、以下をinit.vimに書き加え `:PlugInstall` します。

```init.vim
Plug 'antoinemadec/coc-fzf'
```


すると `:CocFzfList` というコマンドが追加されるので設定ファイルにキーバインドなどを設定します。

## オプション：Escキーで抜ける設定
デフォルトだとEscキーで抜けられないので以下のキーバインドの設定を加えます。

```init.vim
tnoremap <expr> <Esc> (&filetype == "fzf") ? "<Esc>" : "<c-\><c-n>"
```

## オプション：Floating Windowでの表示の設定
そのままでも使えますが、Floating Windowを使って表示させたいので以下を設定ファイルに加えます。
(長いので別ファイルに保存して Vim の `:source` コマンドで引っ張ってきてもいいと思います)


```init.vim
fu s:snr() abort
    return matchstr(expand('<sfile>'), '.*\zs<SNR>\d\+_')
endfu
let s:snr = get(s:, 'snr', s:snr())
let g:fzf_layout = {'window': 'call '..s:snr..'fzf_window(0.9, 0.6, "Comment")'}

fu s:fzf_window(width, height, border_highlight) abort
    let width = float2nr(&columns * a:width)
    let height = float2nr(&lines * a:height)
    let row = float2nr((&lines - height) / 2)
    let col = float2nr((&columns - width) / 2)
    let top = '┌' . repeat('─', width - 2) . '┐'
    let mid = '│' . repeat(' ', width - 2) . '│'
    let bot = '└' . repeat('─', width - 2) . '┘'
    let border = [top] + repeat([mid], height - 2) + [bot]
    if has('nvim')
        let frame = s:create_float(a:border_highlight, {
            \ 'row': row,
            \ 'col': col,
            \ 'width': width,
            \ 'height': height,
            \ })
        call nvim_buf_set_lines(frame, 0, -1, v:true, border)
        call s:create_float('Normal', {
            \ 'row': row + 1,
            \ 'col': col + 2,
            \ 'width': width - 4,
            \ 'height': height - 2,
            \ })
        exe 'au BufWipeout <buffer> bw '..frame
    else
        let frame = s:create_popup_window(a:border_highlight, {
            \ 'line': row,
            \ 'col': col,
            \ 'width': width,
            \ 'height': height,
            \ 'is_frame': 1,
            \ })
        call setbufline(frame, 1, border)
        call s:create_popup_window('Normal', {
            \ 'line': row + 1,
            \ 'col': col + 2,
            \ 'width': width - 4,
            \ 'height': height - 2,
            \ })
    endif
endfu

fu s:create_float(hl, opts) abort
    let buf = nvim_create_buf(v:false, v:true)
    let opts = extend({'relative': 'editor', 'style': 'minimal'}, a:opts)
    let win = nvim_open_win(buf, v:true, opts)
    call setwinvar(win, '&winhighlight', 'NormalFloat:'..a:hl)
    return buf
endfu

fu s:create_popup_window(hl, opts) abort
    if has_key(a:opts, 'is_frame')
        let id = popup_create('', #{
            \ line: a:opts.line,
            \ col: a:opts.col,
            \ minwidth: a:opts.width,
            \ minheight: a:opts.height,
            \ zindex: 50,
            \ })
        call setwinvar(id, '&wincolor', a:hl)
        exe 'au BufWipeout * ++once call popup_close('..id..')'
        return winbufnr(id)
    else
        let buf = term_start(&shell, #{hidden: 1})
        call popup_create(buf, #{
            \ line: a:opts.line,
            \ col: a:opts.col,
            \ minwidth: a:opts.width,
            \ minheight: a:opts.height,
            \ zindex: 51,
            \ })
        exe 'au BufWipeout * ++once bw! '..buf
    endif
endfu
```

すると以下のように表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229154/fcb7601f-f379-5946-ed4e-a69b1491baa5.png)


# 注意点
`coc.nvim` の拡張 `coc-lists` などで追加された機能については実装されていません。
ぼくは必要になったら手動で `:CocList` をしています。

# 感想
fzf 軽快でいいですね。日々の相棒のエディタからストレスをなくしていくのは重要だと思っているので、こういった痒いところに手が届くプラグインが作られているのは大変ありがたいです。