rcmdnk's blog
Last update

CoPilot

GitHub Copilotを使い始めました。

Copilot@Vimを始める

まずはGitHub上でCopilotを有効にしておきます。

Quickstart for GitHub Copilot - GitHub Docs

次に、VimにCopilotの設定。

Vim用のプラグインが用意されているのでそれを入れます。

Vim用のプラグインマネージャーとしてdein.vim を使っているので、 対応バージョンを考慮して以下の様な設定を加えます。

if has('nvim') || has('patch-9.0.0185')
  call dein#add('github/copilot.vim')
endif

これでNeoVimかVimの9.0.0185以上であれば使えるようになるので、 あとはVim(NeoVim)内でコマンドラインモードから

:Copilot setup

を行うとブラウザが開いて(もしくはURLが示されるのでそれを開いて)表示されている認証コードを入れることで 実際に使えるようになります。

この際、認証情報は ~/.config/github-copilot/hosts.json に入っていて、

W **~/.config/github-copilot/hosts.json**
1
2
3
4
5
6
{
  "github.com": {
    "user": "<user>",
    "oauth_token": "<token>"
  }
}

みたいなJSONファイルです。

hostsと名前が付いてるので端末毎に認証を行うことが考えられているのだと思いますが、 このファイルを別の環境に持っていって設置すればすぐに始める事もできます。

バージョン17以下のNode.jsの用意

追記: 2023/02/12

いつからかは確認出来てないですが、現状のversion

1
2
3
4
copilot.vim 1.8.2
Neovim 0.8.3
copilot/dist/agent.js 1.71.0
Node.js 19.6.0

だとHomebrewで直接入れられるnode、19.6.0でも動くようになったみたいです。

追記ここまで

CopilotはNode.jsを使いますが、最新の18.Xのバージョンには対応していないので、 17より前のものを用意する必要があります。

Homebrewなどで入れていると18.Xの物が入るので、そのまま使おうとすると、 Copilot setupの際に

Copilot: 'Node.js version 12.x–17.x required but found 18.9.1'

みたいなエラーメッセージが出ます。

適当に17以前のものを入れてそれを使うようにする必要がありますが、nodenvを使って17のものを入れました。

Homebrewで

$ brew install nodenv

としてnodenvを入れて、 nodenv install --listで確認して17の最新のやつとかを入れておきます。

$ nodenv install 17.9.1

これで~/.nodenv/versions/17.9.1/bin/nodeに17のバージョンのものが入りました。

普段のnodeもこれで良いならここにPATHを通せばよいわけですが、Copilotのためだけに使うのであれば ~/.config/nvim/init.vim

let g:copilot_node_command = "~/.nodenv/versions/17.9.1/bin/node"

と加えておけばCopilotがこのnodeを使うようになってくれます。

どの環境でも17.9.1をnodenvで入れればこれで対応できますが、 .vimrc(~/.confg/nvim/init.vim)を色々な環境で使いまわしたいとき バージョン違いが出て書き換える必要があるかもしれません。

この辺、ちょっと頑張ろうと思うと、

.vimrc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function! CheckNodeForCopilot(nodev)
  let l:nodev = split(a:nodev, '\.')[0]
  if stridx(l:nodev, 'v') == 0
    let l:nodev = nodev[1:]
  endif
  return l:nodev > 11 && l:nodev < 18
endfunction

let s:nodev = system('node --version')
if !CheckNodeForCopilot(s:nodev)
  let s:nodev = system('nodenv whence node|grep -v "^18"|sort -n|tail -n1|tr -d "\n"')
  if CheckNodeForCopilot(s:nodev)
    let g:copilot_node_command = "~/.nodenv/versions/" . s:nodev . "/bin/node"
  endif
endif

こんな感じの設定を入れれば、PATH内にある通常のnodeのメジャーバージョンが12~17であればそれを使い、 なければnodenvで入れた17以前の最新のものを使うようにしてくれます。

多分すぐにNode.jsの18にも対応してくれるんじゃないかと思いますが、 それまではこんな感じで。

キーバインド

Copilotを使うにあたって使うキーバインドは

  • 提案を入力する(<Tab>): copilot#Accept()
  • 提案を却下する(<C-]>): <Plug>(copilot-dismiss)
  • 次の提案に移る(<M-]>): <Plug>(copilot-next)
  • 前の提案い移る(<M-[>): <Plug>(copilot-previous)

があります。これらはあらかじめ設定してありますが、特にTabなんかは 別のもので使っていたりとか、普通にTabキーとして使いたい、という場合もあるかもしれません。

そんなときは

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

とするとCtrl-J提案を入力するようにしてTabはCopilotでは使わないようにできます。

個人的な設定としては、next, previousを

imap <silent> <M-i> <Plug>(copilot-next)
imap <silent> <M-o> <Plug>(copilot-previous)

としています。

というのも、macOSで使っているiTerm2だとこれらが分割Paneの選択移動に割り当てられていて 使えないため。 設定で通すことも出来ますが、取り敢えず<M-i><M-o>は他でも使ってなかったのでこれにしておきました。

あと、<Tab>はそのまま使ってますが、 <C-]>

inoremap <silent> <C-]> <C-o>:setlocal paste!<CR>

という設定でインサートモード時にpasteモードにするのに使ってて使えない状態。

ただ、今のところ出てきたものが違うな、と思っても、少し入力を続ければ消えますし、 すぐに消す必要性も感じないのでこの機能は今のところ使わない状態にしています。

使ってみての感想

取り敢えず使い始めた段階でまだまだ使いこなせてない感がありますが、 結構使う前に思っていたイメージと違いました。

関数名やらコメントやらを中心に入力として使って蓄積データの中にある必要なコードを引っ張ってくるだけみたいなイメージでしたが、 既に書いてある自分のコードをちゃんと見て、似たような関数名なら同じ引数にしたり同じ型の返り値を用意したりも してくれるので、ちゃんと自分の補助をしてくれてる、という感じがしました。

思ってた以上にやりたいことを察してくれてる感があって、 場合によってはやりたいことはそのままに知らなかった小技的なものを出してくれる事もあるので 普通に勉強にもなってる感じ。

あと変数名とかも勝手に付けてくれるので無駄に考える時間も減るとか。

下にあるようなものとかもまだあまりやれてなかったりしますが、 慣れてくればより便利になる感じもあるので積極的に使っていこうと思います。

8 things you didn’t know you could do with GitHub Copilot The GitHub Blog

Sponsored Links
Sponsored Links

« starred: GitHubに自分のStarを付けたレポジトリまとめページを作る GitHub Actions中でpushする際にgithub-actions[bot]をユーザーとして使う »

}