CopilotC-Nvim/CopilotChat.nvim: Chat with GitHub Copilot in Neovim https://github.com/CopilotC-Nvim/CopilotChat.nvim/tree/main
今期イチオシのプラグインなので。
コンテキストとは
https://github.com/CopilotC-Nvim/CopilotChat.nvim/tree/main?tab=readme-ov-file#contexts
プロンプト中に使える特別な文字列で、たとえば、
#buffer
関数をリストアップして説明して。
ってすると、いま開いてるファイル(バッファ)の中身を見て、答えてくれる。
デフォルトでもいくつか定義されてて、よく使うのはこのあたり。
#files
: 今ひらいてるソースを起点に、配下のファイル全部の中身#file:../foo/bar.js
: 単一ファイルの中身
git ls-files
したい
#files
は便利ではあるものの、そのチャットを開いた元ファイルがディレクトリの起点になっちゃう。
なので、具体的にどのファイルがコンテキストに載ったのかがわからないのが不安になるし、毎回それを意識したくない。
というか、だいたいGitのルートから全部載せてくれてもいいのに・・・ってケースもある。
というわけで、#git_files
を独自のコンテキストとして実装したのが以下。
{
-- ...
contexts = {
git_files = {
resolve = function()
local context = require("CopilotChat.context")
local utils = require("CopilotChat.utils")
local cmd = {
"git",
"rev-parse",
"--show-toplevel",
}
local out = utils.system(cmd)
local git_root = out.stdout:gsub("\n$", "")
local files = utils.scan_dir(git_root)
utils.schedule_main()
files = vim.tbl_filter(
function(file)
return file.ft ~= nil
end,
vim.tbl_map(function(file)
return {
name = utils.filepath(file),
ft = utils.filetype(file),
}
end, files)
)
return vim.iter(files)
:map(function(file)
return context.get_file(file.name, file.ft)
end)
:filter(function(file_data)
return file_data ~= nil
end)
:totable()
end,
},
},
},
やってることは単純で、
git rev-parse --show-toplevel
で、ルートのディレクトリを見つける- 標準出力の改行を捨てる
- あとは、そこを起点にするようにして、
#files
の実装と同じものを持ってくる
これだけ。
utils.scan_dir
は、内部的にrg
コマンドを優先的に使うらしく、いくつかのオプションは渡せるみたいだった。