lexima.vimとasyncomplete.vimのキーバインドにハマった話
先日、vim.jp でauto-pairs のプラグインでハマった部分の解決策を教えてもらった。
そのときにlexima.vimを勧めてもらったので試していたが、キーバインド周りで詰まったのでまとめておく。
何が起きたか
- asyncomplete の補完表示中のキーバインドが意図した挙動をしない。
- 上記の問題が時折起こる(毎回起こるわけではない)
私はdein.vimの hook_add
でキーバインドを以下のように設定している。
hook_add = """
inoremap <expr> <C-j> pumvisible() ? "\<C-n>" : "\<C-j>"
inoremap <expr> <Tab> pumvisible() ? "\<C-n>" : "\<Tab>"
inoremap <expr> <C-k> pumvisible() ? "\<C-p>" : "\<C-k>"
inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"
inoremap <expr> <CR> pumvisible() ? "\<C-y>" : "\<CR>"
imap <C-space> <Plug>(asyncomplete_force_refresh)
let g:asyncomplete_auto_completeopt = 1
let g:asyncomplete_matchfuzzy = 1
let g:asyncomplete_auto_popup = 1
"""
補完表示が出ているときに <Tab>
を押すと補完の選択、<CR>
で確定のバインドをしている。
しかし、lexima.vim
を導入した後、時折このバインドが発動せずに通常の <Tab>
,<CR>
の挙動をすることが起きるようになった。
かつ、この挙動が起きない時(正常に動いているように見える時)には lexima
の input_after
の挙動がうまくいかないように見えた。
(|)
[`|`の位置で<CR>を入力すると]
(
|
)
調べた内容
- 何がトリガになっているか
<CR>
にバインドされているものはlexima
とasyncomplete
だけ
- どのような状況で起こるのか
dein.toml
のhook_add
にecho
を仕込んで読み込み順序を確認した
これらをやったところ、どうやら asyncomplete -> lexima
の順に読み込むと補完のバインドがおかしくなることがわかった。
また、lexima
の issue を見ると、同様の issueがあった。
この issue は asyncomplete
ではなさそうだが、同様に <CR>
のバインドがうまくできないようだ。
解決策
- 読み込み順序を指定する
asyncomplete
のプラグイン設定をdein_lazy.toml
に移動し、on_source
オプションでlexima.vim
を読み込んだ後に読み込むように変更した。 また、<CR>
をlexima
の評価を混ぜるように変更した。
[[plugins]]
hook_add = """
inoremap <expr> <C-j> pumvisible() ? "\<C-n>" : "\<C-j>"
inoremap <expr> <Tab> pumvisible() ? "\<C-n>" : lexima#expand("<LT>Tab>","i")
inoremap <expr> <C-k> pumvisible() ? "\<C-p>" : "\<C-k>"
inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"
inoremap <expr> <CR> pumvisible() ? "\<C-y>" : lexima#expand("<LT>CR>", "i")
imap <C-space> <Plug>(asyncomplete_force_refresh)
let g:asyncomplete_auto_completeopt = 1
let g:asyncomplete_matchfuzzy = 1
let g:asyncomplete_auto_popup = 1
"""
repo = "prabirshrestha/asyncomplete.vim"
depends = "lexima.vim"
on_source = "lexima.vim" # if load this binding before loading lexima, override this bindings by lexima's and not work fine.
個人的には asyncomplete
の設定に lexima
の関数が出てくるのが気に食わないが、depends
に lexima
を指定しているので妥協できる。
(dein
の depends
の仕様がよくわかっていない。指定するだけでは読み込まず、別途 [[plugins]]
しなければならないことは知っているが…)