Skip to content

Commit ed7234c

Browse files
committed
feat(context): add full file content support for files
The files context provider now supports two modes: - 'list' (default) - includes only filenames in the workspace - 'full' - includes both filenames and their content This change provides more flexibility when needing full context from workspace files. The implementation also adds proper filetype detection and filtering for files to ensure only text files are included. Closes CopilotC-Nvim#360 Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
1 parent 5c82561 commit ed7234c

5 files changed

Lines changed: 67 additions & 13 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ Default contexts are:
275275
- `buffer` - Includes specified buffer in chat context (default current). Supports input.
276276
- `buffers` - Includes all buffers in chat context (default listed). Supports input.
277277
- `file` - Includes content of provided file in chat context. Supports input.
278-
- `files` - Includes all non-hidden filenames in the current workspace in chat context.
278+
- `files` - Includes all non-hidden files in the current workspace in chat context. By default includes only filenames, includes also content with `full` input. Including all content can be slow on big workspaces so use with care. Supports input.
279279
- `git` - Includes current git diff in chat context (default unstaged). Supports input.
280280
- `register` - Includes content of specified register in chat context (default `+`, e.g system clipboard). Supports input.
281281

@@ -719,7 +719,7 @@ require('CopilotChat').setup({
719719

720720
## Roadmap (Wishlist)
721721

722-
- Use indexed vector database with current workspace for better context selection
722+
- Caching for contexts
723723
- General QOL improvements
724724

725725
## Development

lua/CopilotChat/config.lua

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,14 @@ return {
228228
end,
229229
},
230230
files = {
231-
description = 'Includes all non-hidden filenames in the current workspace in chat context.',
232-
resolve = function(_, source)
233-
return context.files(source.winnr)
231+
description = 'Includes all non-hidden files in the current workspace in chat context. By default includes only filenames, includes also content with `full` input. Including all content can be slow on big workspaces so use with care. Supports input.',
232+
input = function(callback)
233+
vim.ui.select({ 'list', 'full' }, {
234+
prompt = 'Select files content> ',
235+
}, callback)
236+
end,
237+
resolve = function(input, source)
238+
return context.files(source.winnr, input == 'full')
234239
end,
235240
},
236241
git = {

lua/CopilotChat/context.lua

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,9 @@ end
276276

277277
--- Get list of all files in workspace
278278
---@param winnr number?
279+
---@param with_content boolean?
279280
---@return table<CopilotChat.copilot.embed>
280-
function M.files(winnr)
281+
function M.files(winnr, with_content)
281282
local cwd = utils.win_cwd(winnr)
282283
local files = utils.scan_dir(cwd, {
283284
add_dirs = false,
@@ -286,7 +287,35 @@ function M.files(winnr)
286287

287288
local out = {}
288289

289-
-- Create embeddings in chunks
290+
-- Read all files if we want content as well
291+
if with_content then
292+
async.util.scheduler()
293+
294+
files = vim.tbl_map(function(file)
295+
return {
296+
name = utils.filepath(file),
297+
ft = utils.filetype(file),
298+
}
299+
end, files)
300+
files = vim.tbl_filter(function(file)
301+
return file.ft ~= nil
302+
end, files)
303+
304+
for _, file in ipairs(files) do
305+
local content = utils.read_file(file.name)
306+
if content then
307+
table.insert(out, {
308+
content = content,
309+
filename = file.name,
310+
filetype = file.ft,
311+
})
312+
end
313+
end
314+
315+
return out
316+
end
317+
318+
-- Create file list in chunks
290319
local chunk_size = 100
291320
for i = 1, #files, chunk_size do
292321
local chunk = {}
@@ -317,10 +346,14 @@ function M.file(filename)
317346
end
318347

319348
async.util.scheduler()
349+
if not utils.filetype(filename) then
350+
return nil
351+
end
352+
320353
return {
321354
content = content,
322-
filename = vim.fn.fnamemodify(filename, ':p:.'),
323-
filetype = vim.filetype.match({ filename = filename }),
355+
filename = utils.filepath(filename),
356+
filetype = utils.filetype(filename),
324357
}
325358
end
326359

@@ -341,7 +374,7 @@ function M.buffer(bufnr)
341374

342375
return {
343376
content = table.concat(content, '\n'),
344-
filename = vim.fn.fnamemodify(vim.api.nvim_buf_get_name(bufnr), ':p:.'),
377+
filename = utils.filepath(vim.api.nvim_buf_get_name(bufnr)),
345378
filetype = vim.bo[bufnr].filetype,
346379
}
347380
end

lua/CopilotChat/copilot.lua

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -329,9 +329,7 @@ local Copilot = class(function(self, proxy, allow_insecure)
329329
'60',
330330
-- Disable compression (since responses are already streamed efficiently)
331331
'--no-compressed',
332-
-- Important timeouts
333-
'--max-time',
334-
math.floor(TIMEOUT * 2 / 1000),
332+
-- Connect timeout of 10 seconds
335333
'--connect-timeout',
336334
'10',
337335
-- Streaming optimizations

lua/CopilotChat/utils.lua

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,24 @@ function M.filename_same(file1, file2)
180180
return vim.fn.fnamemodify(file1, ':p') == vim.fn.fnamemodify(file2, ':p')
181181
end
182182

183+
--- Get the filetype of a file
184+
---@param filename string The file name
185+
---@return string|nil
186+
function M.filetype(filename)
187+
local ft = vim.filetype.match({ filename = filename })
188+
if ft == '' then
189+
return nil
190+
end
191+
return ft
192+
end
193+
194+
--- Get the file path
195+
---@param filename string The file name
196+
---@return string
197+
function M.filepath(filename)
198+
return vim.fn.fnamemodify(filename, ':p:.')
199+
end
200+
183201
--- Generate a UUID
184202
---@return string
185203
function M.uuid()

0 commit comments

Comments
 (0)