火曜日, 9月 2, 2025
火曜日, 9月 2, 2025
- Advertisment -
ホームニューステックニュースNeovim 0.12(開発版)でcopilot-language-serverを設定してみたぞ(脱copilot.lua)

Neovim 0.12(開発版)でcopilot-language-serverを設定してみたぞ(脱copilot.lua)



この記事はVim駅伝の2025-09-01の記事です。
前回の記事はatusyさんのNeovim 0.12(開発版)ではLSPクライアント経由でGitHub Copilotを使えるぞ(脱copilot.vim)です。

Vim駅伝は常に参加者を募集しています。詳しくはこちらのページをご覧ください。


Neovimの開発ブランチにlspのtextDocument/inlineCompletionのサポートが入りました。まだstableには入っていませんが、最新のnightlyなどで使用できます。

https://github.com/neovim/neovim/pull/33972

名前の通り、インラインの補完を扱うもので、補完候補の表示・選択・確定をすることができます。

この設定が前回の駅伝記事↓で紹介されていたので、

https://blog.atusy.net/2025/08/29/copilot-via-nvim-lsp-client/

筆者もこちらに感化されて、copilot.luaからcopilot-langugage-serverを用いた補完に切り替えてみようと思いたち、設定してみました。

https://github.com/zbirenbaum/copilot.lua

https://www.npmjs.com/package/@github/copilot-language-server

lsp用の設定は自分ですべて書くこともできますが、nvim-lspconfigの力を借りるのが簡単でしょう。このへんは以下の記事に書いたとおりです。

https://zenn.dev/kawarimidoll/articles/b202e546bca344

こちらのPRでcopilot-language-serverの基本設定とサインイン用コマンドが定義されています。

https://github.com/neovim/nvim-lspconfig/pull/4029

筆者のlspの設定はこうなっています。詳しくは前掲の記事を見てください。

ディレクトリ構成

(config)/
├ init.lua # nvim-lspconfigの読み込み ①
└ lua/
│   └ lsp/
│       └ init.lua # copilot-language-serverの有効化 ②
└ after/
    └ lsp/
       └ copilot.lua # 今回のcopilot-language-serverの設定 ③

まず大本のinit.luaではnvim-lspconfigを読み込みます。筆者はmini.depsを使用しているので、こうなります。

init.lua

add('https://github.com/neovim/nvim-lspconfig')

続いて、lua/lsp/init.luaのほうではcopilot-language-serverを有効化します。名前はcopilotです。

lua/lsp/init.lua

vim.lsp.enable('copilot')

設定本体はafter/lsp/copilot.luaです。

after/lsp/copilot.lua

return {
  root_dir = function(bufnr, callback)
    
    local fname = vim.fs.basename(vim.api.nvim_buf_get_name(bufnr))
    local disable_patterns = { 'env', 'conf', 'local', 'private' }
    local is_disabled = vim.iter(disable_patterns):any(function(pattern)
      return string.match(fname, pattern)
    end)
    if is_disabled then
      return
    end

    
    
    local root_dir = vim.fs.root(bufnr, { '.git' })
    if root_dir then
      return callback(root_dir)
    end
  end,
  on_init = function()
    
    
    local hlc = vim.api.nvim_get_hl(0, { name = 'Comment' })
    vim.api.nvim_set_hl(0, 'ComplHint', vim.tbl_extend('force', hlc, { underline = true }))
    local hlm = vim.api.nvim_get_hl(0, { name = 'MoreMsg' })
    vim.api.nvim_set_hl(0, 'ComplHintMore', vim.tbl_extend('force', hlm, { underline = true }))

    
    vim.api.nvim_create_autocmd('LspAttach', {
      callback = function(args)
        local bufnr = args.buf

        
        vim.lsp.inline_completion.enable(true, { bufnr = bufnr })

        
        vim.keymap.set('i', '', function()
          vim.lsp.inline_completion.get()
          
          if vim.fn.pumvisible() == 1 then
            return ''
          end
        end, { silent = true, expr = true, buffer = bufnr })

        
        vim.keymap.set('i', '', function()
          vim.lsp.inline_completion.select()
        end, { silent = true, buffer = bufnr })
        vim.keymap.set('i', '', function()
          vim.lsp.inline_completion.select({ count = -1 * vim.v.count1 })
        end, { silent = true, buffer = bufnr })
      end,
    })
  end,
}

やっていることはコメントしたとおりです。
除外対象のファイルや、マッピングするキーはお好みで設定してください。

ひとつ注意するポイントがあります。lspconfigに入っているコードではon_attachを使って認証コマンドを定義しているため、ユーザー側でon_attachに処理を加えてしまうとこれらが上書きされて使えなくなってしまう点です。

https://github.com/neovim/nvim-lspconfig/blob/44201a94c6b2031f53bdcf645d5de72489e806b9/lsp/copilot.lua#L100-L107

したがって、上記の設定例ではon_initにautocmd LspAttachを記述しています。これを書く位置はcopilot-language-server自体がアタッチされる前ならどこでも(lua/lsp/init.luaなど)良いのですが、copilotの設定とまとめたほうがあとから見やすいと考え、今回はon_initに含めました。

これでcopilot.luaがなくてもGitHub Copilotによる補完サジェストを使えるようになりました。
筆者の環境では設定当初は補完の表示が若干遅い印象でしたが、サインインをやり直したところ、キビキビ動くようになりました。

textDocument/inlineCompletionはcopilotに限らず他のソースでも利用できるようになっているみたいなので、別のLLM補完を使いたくなったときにも設定を流用できそうです。インターフェースが決まっていると提供する側もやりやすいと思うので、今後は個別のプラグインを作るよりもこの方法で呼び出すほうが主流になっていくのではないでしょうか。


Vim駅伝はこの記事のように「Vim駅伝の記事を読んで自分もやってみた」系の投稿も大歓迎です。詳しくはこちらのページをご覧ください。



Source link

Views: 0

RELATED ARTICLES

返事を書く

あなたのコメントを入力してください。
ここにあなたの名前を入力してください

- Advertisment -