EmacsのMagitでコミットメッセージを書く時にGitHub Copilotがある程度効くようにしました
GitHub Copilotが無償配布されるようになりました
弊社pluszeroでは生産性向上のために、希望者にはGitHub Copilotを無料で配布するようになりました。
自分は拡張版のGitHub Copilot Xが、 Visual Studio CodeとVisual Studio以外の、具体的にはNeovim向けにも提供されるまで様子見して、提供されたら一ヶ月の試用期間で使ってみて継続して契約するか決めようかと様子見していました。
そんなことを考えていた理由は、私はEmacsを使っていて、ここから離されると生産性が落ちることが目に見えていたためです。
GitHub CopilotはEmacsには公式には対応していないのですが、 zerolfx/copilot.el: An unofficial Copilot plugin for Emacs.で非公式サポートされています。
これの実装方法はNeovim向けのクライアントに依存しています。 GitHub Copilotは嘆かわしいことにクライアントすらプロプライエタリです。 GitHubに投稿されたコードを利用しているのですから、クライアントぐらいフリーソフトウェアにするのが望ましいと思うのですが。せめてドキュメント化されたAPIを提供してほしい。
ともかくそういう事情があるのでNeovim向けにはどうもlsp(少なくともNode.jsとJSON RPCしている)で接続しているようで、 Emacsの非公式クライアントはNeovimのクライアントをコピーしてくる形で実装されています。
なのでEmacs向けにCopilot Xを実装するにはNeovim向けのクライアントがCopilot Xを待つ必要があったわけです。
一回しか無料の試用期間は使えないのでCopilot Xが実装できそうな雰囲気が出たら使ってみて、コントリビュートも考えていました。一ヶ月1500円ぐらいはそこそこ高いですからねえ。
しかし会社が無料で配布してくれるならXじゃない範囲でも使います。補完はGPT-3の性能的にあんまり期待してなかったのですがそれなりに便利です。どちらかと言うとリファクタリングやドキュメントコメント生成に期待してたのでCopilot Xを待っていましたが、補完だけでも使う価値がかなりありますね。
Gitのコミットメッセージでも補完を効かせたい
copilot.elのドキュメント的にはprog-mode-hook
にcopilot-mode
を追加するのが推奨で、それで概ね動きます。
ただもちろんそれだとプログラミング言語のモードでしか動きません。
Gitのコミットメッセージこそdiffをソースにかなり自動化できそうですね。
EmacsにはMagitというEmacs以外を入れても最強に近いGitクライアントが存在するので、私はこれを使っています。
なのでgit-commit-setup-hook
にcopilot-mode
を追加してやれば当然EmacsのGitのコミットメッセージ編集画面でCopilotは動きます。
しかしMagitのコミット画面ではコミットメッセージ編集画面は簡素になっていて、
diff画面とコミットメッセージ画面が横に2分割されてdiffを見ながらコミットを書くことが出来るようになっています。これは通常の使い方では特に文句はないのですが、
copilot.elは今のバッファとファイルしか読まないようなので、この状態ではcopilotはfeat: add init.el
のようなざっくりとしすぎている上に間違っているコミットメッセージしか作れません。どのファイルに変更があったかぐらいしか見れないからですね。
コミットメッセージバッファに情報を入れます
バッファの内容を読むのであれば当然バッファに入れる情報を増やしてやれば良いわけです。
Magitでコミットする時--verbose
オプションを有効にしてやればコミットメッセージ入力バッファにdiffも入力されるので、
feat: add git-commit-setup-hook to copilot
のようなそれっぽいコミットメッセージが生成されるようになってくれます。
--verbose
をデフォルトにしたい
さて--verbose
を毎回有効にするのは面倒なのでデフォルトにしたいですね。
How can I make --verbose
flag be enabled by default in magit commit screen? - Emacs Stack Exchange
の作者による回答を参考にすると、
--verbose
を有効にしてC-x C-sを実行すれば(magit-popup-save-default-arguments)
が実行されてデフォルトになるようですね。実際の動作を辿ると.emacs.d/transient
ディレクトリに永続化されるようですね。
transient全然わからん
それでもうだいたい目的は達成されているのですが、複数端末での利用や.emacs.dのgit clone
だけでの再構築を考えると、自動で変更される部分ではなく、手動で書くGitマネージドなコード部分にデフォルト値は書いておきたいですね。
昔はmagit-commit-arguments
は単なるリストだったようなのですが、今はmagit-popup
-> transient
の管轄になっているようなので単純に--verbose
をリストに追加する方法では対応できません。
Git自体の設定で解決することにしました
MagitではなくGit自体の設定でgit config --global commit.verbose true
のように設定すれば表示されるようになるので、実用的にはこれでも良いかなと思いました。
Magitのフラグ表示と実際の挙動が異なるのはかなり気持ちが悪いですが、 Transient User and Developer Manualを見たり、 forgeの使用例を見ても解決策が思いつきませんでした。
多少汚いですがadviceで(magit-commit-arguments)
をaroundして解決しようかと思いましたが、構築段階ではなくコミット生成段階で閲覧するためGit自体の設定で解決するのと結果は変わらないですね。
transient
の複雑性と真面目に向き合う必要性を今の所感じないのでこれで良いとしてしまいます。
一応Emacs以外(コマンドラインとか)からコミットを開いたときも設定の有効性を得られるメリットもあります。