Skip to content

Commit 9a9d6c6

Browse files
committed
plugins/copilot-chat: init
1 parent f4ce7da commit 9a9d6c6

File tree

3 files changed

+491
-0
lines changed

3 files changed

+491
-0
lines changed

plugins/ai/copilot-chat.nix

Lines changed: 322 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,322 @@
1+
{
2+
lib,
3+
helpers,
4+
config,
5+
pkgs,
6+
...
7+
}:
8+
with lib;
9+
helpers.neovim-plugin.mkNeovimPlugin config {
10+
name = "copilot-chat";
11+
originalName = "CopilotChat.nvim";
12+
luaName = "CopilotChat";
13+
defaultPackage = pkgs.vimPlugins.CopilotChat-nvim;
14+
15+
maintainers = [ maintainers.GaetanLepage ];
16+
17+
settingsOptions = {
18+
debug = helpers.defaultNullOpts.mkBool false ''
19+
Enable debug logging.
20+
'';
21+
22+
proxy = helpers.defaultNullOpts.mkStr null ''
23+
Custom proxy to use, formatted as `[protocol://]host[:port]`.
24+
'';
25+
26+
allow_insecure = helpers.defaultNullOpts.mkBool false ''
27+
Allow insecure server connections.
28+
'';
29+
30+
system_prompt = helpers.defaultNullOpts.mkLua "require('CopilotChat.prompts').COPILOT_INSTRUCTIONS" ''
31+
System prompt to use.
32+
'';
33+
34+
model = helpers.defaultNullOpts.mkStr "gpt-4" ''
35+
GPT model to use, 'gpt-3.5-turbo' or 'gpt-4'.
36+
'';
37+
38+
temperature = helpers.defaultNullOpts.mkNullableWithRaw (types.numbers.between 0.0 1.0) 0.1 ''
39+
GPT temperature.
40+
'';
41+
42+
question_header = helpers.defaultNullOpts.mkStr "## User " ''
43+
Header to use for user questions.
44+
'';
45+
46+
answer_header = helpers.defaultNullOpts.mkStr "## Copilot " ''
47+
Header to use for AI answers.
48+
'';
49+
50+
error_header = helpers.defaultNullOpts.mkStr "## Error " ''
51+
Header to use for errors.
52+
'';
53+
54+
separator = helpers.defaultNullOpts.mkStr "───" ''
55+
Separator to use in chat.
56+
'';
57+
58+
show_folds = helpers.defaultNullOpts.mkBool true ''
59+
Shows folds for sections in chat.
60+
'';
61+
62+
show_help = helpers.defaultNullOpts.mkBool true ''
63+
Shows help message as virtual lines when waiting for user input.
64+
'';
65+
66+
auto_follow_cursor = helpers.defaultNullOpts.mkBool true ''
67+
Auto-follow cursor in chat.
68+
'';
69+
70+
auto_insert_mode = helpers.defaultNullOpts.mkBool false ''
71+
Automatically enter insert mode when opening window and if auto follow cursor is enabled on new prompt.
72+
'';
73+
74+
clear_chat_on_new_prompt = helpers.defaultNullOpts.mkBool false ''
75+
Clears chat on every new prompt.
76+
'';
77+
78+
highlight_selection = helpers.defaultNullOpts.mkBool true ''
79+
Highlight selection.
80+
'';
81+
82+
context =
83+
helpers.defaultNullOpts.mkEnum
84+
[
85+
"buffers"
86+
"buffer"
87+
]
88+
null
89+
''
90+
Default context to use, `"buffers"`, `"buffer"` or `null` (can be specified manually in prompt via @).
91+
'';
92+
93+
history_path = helpers.defaultNullOpts.mkStr (helpers.mkRaw "vim.fn.stdpath('data') .. '/copilotchat_history'") ''
94+
Default path to stored history.
95+
'';
96+
97+
callback = helpers.defaultNullOpts.mkLuaFn null ''
98+
Callback to use when ask response is received.
99+
100+
`fun(response: string, source: CopilotChat.config.source)`
101+
'';
102+
103+
selection =
104+
helpers.defaultNullOpts.mkLuaFn
105+
''
106+
function(source)
107+
local select = require('CopilotChat.select')
108+
return select.visual(source) or select.line(source)
109+
end
110+
''
111+
''
112+
Default selection (visual or line).
113+
`fun(source: CopilotChat.config.source):CopilotChat.config.selection`
114+
'';
115+
116+
prompts =
117+
let
118+
promptType = types.submodule {
119+
freeformType = with types; attrsOf anything;
120+
options = {
121+
prompt = helpers.mkNullOrStr "Prompt text.";
122+
123+
description = helpers.mkNullOrStr "Description for this prompt.";
124+
125+
kind = helpers.mkNullOrStr "Kind of this prompt.";
126+
127+
mapping = helpers.mkNullOrStr "A key to bind to this prompt.";
128+
129+
system_prompt = helpers.mkNullOrStr "System prompt to use.";
130+
131+
callback = helpers.mkNullOrLuaFn ''
132+
Callback to trigger when this prompt is executed.
133+
`fun(response: string, source: CopilotChat.config.source)`
134+
'';
135+
136+
selection = helpers.mkNullOrLuaFn ''
137+
Selection for this prompt.
138+
`fun(source: CopilotChat.config.source):CopilotChat.config.selection`
139+
'';
140+
};
141+
};
142+
143+
default = {
144+
Explain.prompt = "/COPILOT_EXPLAIN Write an explanation for the active selection as paragraphs of text.";
145+
Review = {
146+
prompt = "/COPILOT_REVIEW Review the selected code.";
147+
callback = ''
148+
function(response, source)
149+
-- see config.lua for implementation
150+
end
151+
'';
152+
};
153+
Fix.prompt = "/COPILOT_GENERATE There is a problem in this code. Rewrite the code to show it with the bug fixed.";
154+
Optimize.prompt = "/COPILOT_GENERATE Optimize the selected code to improve performance and readablilty.";
155+
Docs.prompt = "/COPILOT_GENERATE Please add documentation comment for the selection.";
156+
Tests.prompt = "/COPILOT_GENERATE Please generate tests for my code.";
157+
FixDiagnostic = {
158+
prompt = "Please assist with the following diagnostic issue in file:";
159+
selection = "require('CopilotChat.select').diagnostics";
160+
};
161+
Commit = {
162+
prompt = "Write commit message for the change with commitizen convention. Make sure the title has maximum 50 characters and message is wrapped at 72 characters. Wrap the whole message in code block with language gitcommit.";
163+
selection = "require('CopilotChat.select').gitdiff";
164+
};
165+
CommitStaged = {
166+
prompt = "Write commit message for the change with commitizen convention. Make sure the title has maximum 50 characters and message is wrapped at 72 characters. Wrap the whole message in code block with language gitcommit.";
167+
selection = ''
168+
function(source)
169+
return select.gitdiff(source, true)
170+
end
171+
'';
172+
};
173+
};
174+
in
175+
helpers.defaultNullOpts.mkAttrsOf (with types; either str promptType) default ''
176+
Default prompts.
177+
'';
178+
179+
window = {
180+
layout =
181+
helpers.defaultNullOpts.mkEnumFirstDefault
182+
[
183+
"vertical"
184+
"horizontal"
185+
"float"
186+
"replace"
187+
]
188+
''
189+
Layout for the window.
190+
'';
191+
192+
width =
193+
helpers.defaultNullOpts.mkNullableWithRaw
194+
(with types; either (numbers.between 0.0 1.0) ints.positive)
195+
0.5
196+
''
197+
Fractional width of parent, or absolute width in columns when > 1.
198+
'';
199+
200+
height =
201+
helpers.defaultNullOpts.mkNullableWithRaw
202+
(with types; either (numbers.between 0.0 1.0) ints.positive)
203+
0.5
204+
''
205+
Fractional height of parent, or absolute height in rows when > 1.
206+
'';
207+
208+
relative =
209+
helpers.defaultNullOpts.mkEnumFirstDefault
210+
[
211+
"editor"
212+
"win"
213+
"cursor"
214+
"mouse"
215+
]
216+
''
217+
Relative position.
218+
(Only for floating windows.)
219+
'';
220+
221+
border =
222+
helpers.defaultNullOpts.mkEnum
223+
[
224+
"none"
225+
"single"
226+
"double"
227+
"rounded"
228+
"solid"
229+
"shadow"
230+
]
231+
"single"
232+
''
233+
Border for this window.
234+
(Only for floating windows.)
235+
'';
236+
237+
row = helpers.defaultNullOpts.mkUnsignedInt null ''
238+
Row position of the window, default is centered.
239+
(Only for floating windows.)
240+
'';
241+
242+
col = helpers.defaultNullOpts.mkUnsignedInt null ''
243+
Column position of the window, default is centered.
244+
(Only for floating windows.)
245+
'';
246+
247+
title = helpers.defaultNullOpts.mkStr "Copilot Chat" ''
248+
Title of chat window.
249+
'';
250+
251+
footer = helpers.defaultNullOpts.mkStr null ''
252+
Footer of chat window.
253+
'';
254+
255+
zindex = helpers.defaultNullOpts.mkUnsignedInt 1 ''
256+
Determines if window is on top or below other floating windows.
257+
'';
258+
};
259+
260+
mappings =
261+
helpers.defaultNullOpts.mkAttrsOf
262+
(types.submodule {
263+
options = {
264+
normal = helpers.mkNullOrStr "Key for normal mode.";
265+
266+
insert = helpers.mkNullOrStr "Key for insert mode.";
267+
268+
detail = helpers.mkNullOrStr "A description for this binding.";
269+
};
270+
})
271+
{
272+
complete = {
273+
detail = "Use @<Tab> or /<Tab> for options.";
274+
insert = "<Tab>";
275+
};
276+
close = {
277+
normal = "q";
278+
insert = "<C-c>";
279+
};
280+
reset = {
281+
normal = "<C-l>";
282+
insert = "<C-l>";
283+
};
284+
submit_prompt = {
285+
normal = "<CR>";
286+
insert = "<C-m>";
287+
};
288+
accept_diff = {
289+
normal = "<C-y>";
290+
insert = "<C-y>";
291+
};
292+
yank_diff.normal = "gy";
293+
show_diff.normal = "gd";
294+
show_system_prompt.normal = "gp";
295+
show_user_selection.normal = "gs";
296+
}
297+
"Mappings for CopilotChat.";
298+
};
299+
300+
settingsExample = {
301+
question_header = "## User ";
302+
answer_header = "## Copilot ";
303+
error_header = "## Error ";
304+
prompts = {
305+
Explain = "Please explain how the following code works.";
306+
Review = "Please review the following code and provide suggestions for improvement.";
307+
Tests = "Please explain how the selected code works, then generate unit tests for it.";
308+
};
309+
auto_follow_cursor = false;
310+
show_help = false;
311+
mappings = {
312+
complete = {
313+
detail = "Use @<Tab> or /<Tab> for options.";
314+
insert = "<Tab>";
315+
};
316+
close = {
317+
normal = "q";
318+
insert = "<C-c>";
319+
};
320+
};
321+
};
322+
}

plugins/default.nix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
{
22
imports = [
3+
./ai/copilot-chat.nix
4+
35
./bufferlines/barbar.nix
46
./bufferlines/barbecue.nix
57
./bufferlines/bufferline.nix

0 commit comments

Comments
 (0)