🤖

Neovim に GitHub Copilot を追加した

2023/04/16に公開

はじめに

Neovim に GitHub Copilot を追加したときに発生した問題を解消した記事です。

対象読者

  • Neovim に GitHub Copilot を導入したが、 Tab で補完するとエラーが発生したり、他のマッピングの影響でうまく GitHub Copilot が動作しなかった人
  • Neovim の設定ファイルを lua で書いている人

本文

前提条件

  • iTerm2、tmux、Neovim を利用
  • プラグイン管理は Packer を利用

発生していた問題

  • If you'd rather use a key that isn't <Tab>, define an <expr> map that calls copilot#Accept(). のようなエラーメッセージが表示される(以前は表示されていたのですが、2023/04/16 現在はエラーメッセージが表示されないかも)
  • もしくはすでにマッピングされている Tab の動作が走り、 GitHub Copilot の補完が実行されない

最初に結論

  • グローバルにフラグを追加し、必要なキーマッピングをすれば OK

以下を既存の設定ファイルに追加して、問題が解消しました。キーマッピングだけ Tab 以外にすればいいと思っていたのですが、グローバルのフラグを設定する必要がありました。

init.lua
--[[ Package manager ]]
return require("packer").startup(function()
  -- Package manager
  use("wbthomason/packer.nvim")

  ...

  -- GitHub Copilot
  use({
    "github/copilot.vim",
    config = function()
      vim.g.copilot_no_tab_map = true

      local keymap = vim.keymap.set
      -- https://github.com/orgs/community/discussions/29817#discussioncomment-4217615
      keymap(
        "i",
        "<C-g>",
        'copilot#Accept("<CR>")',
        { silent = true, expr = true, script = true, replace_keycodes = false }
      )
      keymap("i", "<C-j>", "<Plug>(copilot-next)")
      keymap("i", "<C-k>", "<Plug>(copilot-previous)")
      keymap("i", "<C-o>", "<Plug>(copilot-dismiss)")
      keymap("i", "<C-s>", "<Plug>(copilot-suggest)")
    end,
  })
end)

ヘルプについて

上記の設定ファイルは :h copilot#Accept() に記載されている Vim script を lua で書き直したものです。

help copilot#Accept()
                                                *copilot#Accept()*
If you'd rather use a key that isn't <Tab>, define an <expr> map that calls
copilot#Accept().  Here's an example with CTRL-J:

        imap <silent><script><expr> <C-J> copilot#Accept("\<CR>")
        let g:copilot_no_tab_map = v:true

The argument to copilot#Accept() is the fallback for when no suggestion is
displayed.  In this example, a regular carriage return is used.  If no
fallback is desired, use an argument of "" (an empty string).

まれに謎の文字が挿入される

Copilot の補完は効くようになったんですが、まれにサジェストを確定すると同時に <80>kD という文字列が挿入されることがありました。調べたところ、同様の問題が Discussions に上がっていました。
以下のコメントを参考に、 replace_keycodes = false を設定すると解消しました 🙌

https://github.com/orgs/community/discussions/29817#discussioncomment-4217615

補足

ちなみに私の Neovim 設定ファイルは init.lua の 1 ファイルで構成しています。
以前はディレクトリを分割していたのですが、 keymapping や設定を複数のファイルから探すのが大変だったので、今回の設定追加を機にシンプルにしました。よければご覧ください。

https://github.com/gentamura/dotfiles/blob/main/.config/nvim/init.lua

上記設定は以下の記事をとても参考にさせていただいています。ありがとうございます 🙏

https://zenn.dev/takuya/articles/4472285edbc132

Discussion