2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【2023年版】Neovim (--HEAD) + coc.nvimでTabキー補完とインサートモードでのタブ文字挿入の両方を実現する

Posted at

【概要】

nvim + coc.nvim環境で、coc.nvim公式のキーマップサンプルにあるように、Tabキーにて補完リストを表示するようにできます。しかし、サンプルコードそのままだとコード保管時にTabキー押下にて補完リストを移動できるものの、補完リストが表示されていない状態でTabキーを押下すると、エラーになるため、エラーの状態と対策を行ったキーマップ(Lua版)について例示解説します。

【環境】

Ubuntu 22.04 LTS
neovim 0.10.0-dev (--HEAD)
coc.nvim 0.0.82

【よくあるエラーの起きる書き方】

その1)

lua
  local opts = {silent = true, noremap = true, expr = true, 
  replace_keycodes = false}
  vim.keymap.set("i", "<TAB>", 'coc#pum#visible() ? coc#pum#next(1) : v:lua.check_back_space() ? "<TAB>" : oc#refresh()', opts)
  vim.keymap.set("i", "<S-TAB>", [[coc#pum#visible() ? coc#pum#prev(1) : "\<C-h>"]], opts)

その2)

vim.script
  inoremap <silent><expr> <TAB>
    \ coc#pum#visible() ? coc#pum#next(1):
    \ <SID>check_back_space() ? "\<Tab>" :
    \ coc#refresh()
  inoremap <expr><S-TAB> coc#pum#visible() ? coc#pum#prev(1) : "\  <S-TAB>" " "\<C-h>"
  inoremap <silent><expr> <c-space> coc#refresh()

まず、その1についてですが、下から2行目の v:lua.check_back_space()でluaのグローバル関数check_back_space()を呼び出そうとしているのですが、関数名が見つからず、グローバル変数自体がnilになってしまい、関数の参照エラーで条件分岐に進めず、よって補完リストが表示されていないときにTabキーを押下したケースも実行されないという状態になります。最初、ここはcheck_back_space()からnilが返ってきているのだと思っていたのですが、いろいろ調べているうちにどうやらそうではないということが分かりました。
次にその2ですが、vim.script表記なので、luaに書き換えると、結局ほぼその1と同じになるため、同様のエラーが発生します。

【修正したキーマップ】

lua
  local opts = {silent = true, noremap = true, expr = true, 
  replace_keycodes = false}
- vim.keymap.set("i", "<TAB>", 'coc#pum#visible() ? oc#pum#next(1) : v:lua.check_back_space() ? "<TAB>" : coc#refresh()', opts)
+ vim.keymap.set("i", "<TAB>", 'coc#pum#visible() ? coc#pum#next(1) : "<Tab>"', opts)
  vim.keymap.set("i", "<S-TAB>", [[coc#pum#visible() ? coc#pum#prev(1) : "<C-h>"]], opts)

修正したところは、バックスペースの入力チェックは無くても動作に影響がないため、v:lua.check_back_space() を削除したことと、coc#pum#refresh()も条件に合致しなくなり、削除しても同じく影響がないため削除しています。替わりに、coc#pum#visible() の条件が偽の(つまり補完リストが表示されていない)場合、"<Tab>"でタブ文字を挿入するようにしています。これにより、補完リストはTabキーとShift+Tabキーで順送り/逆送りができるのと、インサートモードで補完リストが表示されていないときにタブ文字の挿入の両方を実現しています。

解説はここまでです。最後までお読みいただき、ありがとうございました。

【あとがき】

luaの記法と補完リストの挙動がわかってしまえば、そんなに難しくない修正なのですが、結構あちこちのサイトを見て回っても解決策が書かれているサイトが見つけられず、エラーの原因を探るのに時間がかかってしまいました。 操作上エラーが頻発していたので、どうしても改善したくいろいろ調べた甲斐がありました。 地味な修正ですが、余計なイライラを起こさなくて済むようになったので、これからnvim作業が捗る・・・・といいなぁ(笑
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?