Skip to content

Commit b4d6892

Browse files
committed
feat!: add glob pattern support for file context
Replace the basic list/full mode for files context with glob pattern matching support. This allows for more granular file filtering in the workspace using standard glob patterns like *.lua or **/*.js. Split the original files context into two separate contexts: - files: Returns file contents matching the glob pattern - filenames: Returns only filenames matching the glob pattern BREAKING CHANGE: The files context no longer accepts list/full as input options. Instead, it now expects a glob pattern. The old functionality has been split into two separate contexts: files and filenames. Signed-off-by: Tomas Slusny <[email protected]>
1 parent db21158 commit b4d6892

File tree

4 files changed

+57
-30
lines changed

4 files changed

+57
-30
lines changed

README.md

+14-12
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ You can also set default sticky prompts in the configuration:
248248
{
249249
sticky = {
250250
'@models Using Mistral-small',
251-
'#files:full',
251+
'#files',
252252
}
253253
}
254254
```
@@ -285,23 +285,25 @@ The default "noop" agent is `none`. For more information:
285285

286286
Contexts provide additional information to the chat. Add context using `#context_name[:input]` syntax:
287287

288-
| Context | Input Support | Description |
289-
| ---------- | ------------- | ----------------------------------- |
290-
| `buffer` | ✓ (number) | Current or specified buffer content |
291-
| `buffers` | ✓ (type) | All buffers content (listed/all) |
292-
| `file` | ✓ (path) | Content of specified file |
293-
| `files` | ✓ (mode) | Workspace files (list/full content) |
294-
| `git` | ✓ (ref) | Git diff (unstaged/staged/commit) |
295-
| `url` | ✓ (url) | Content from URL |
296-
| `register` | ✓ (name) | Content of vim register |
297-
| `quickfix` | - | Quickfix list file contents |
288+
| Context | Input Support | Description |
289+
| ----------- | ------------- | ----------------------------------- |
290+
| `buffer` | ✓ (number) | Current or specified buffer content |
291+
| `buffers` | ✓ (type) | All buffers content (listed/all) |
292+
| `file` | ✓ (path) | Content of specified file |
293+
| `files` | ✓ (glob) | Workspace files |
294+
| `filenames` | ✓ (glob) | Workspace file names |
295+
| `git` | ✓ (ref) | Git diff (unstaged/staged/commit) |
296+
| `url` | ✓ (url) | Content from URL |
297+
| `register` | ✓ (name) | Content of vim register |
298+
| `quickfix` | - | Quickfix list file contents |
298299

299300
Examples:
300301

301302
```markdown
302303
> #buffer
303304
> #buffer:2
304-
> #files:list
305+
> #files:.lua
306+
> #filenames
305307
> #git:staged
306308
> #url:https://example.com
307309
```

lua/CopilotChat/config/contexts.lua

+16-14
Original file line numberDiff line numberDiff line change
@@ -76,24 +76,26 @@ return {
7676
},
7777

7878
files = {
79-
description = 'Includes all non-hidden files in the current workspace in chat context. Supports input (default list).',
79+
description = 'Includes all non-hidden files in the current workspace in chat context. Supports input (glob pattern).',
8080
input = function(callback)
81-
local choices = utils.kv_list({
82-
list = 'Only lists file names',
83-
full = 'Includes file content for each file found, up to a limit.',
84-
})
81+
vim.ui.input({
82+
prompt = 'Enter glob> ',
83+
}, callback)
84+
end,
85+
resolve = function(input, source)
86+
return context.files(source.winnr, true, input and utils.glob_to_regex(input))
87+
end,
88+
},
8589

86-
vim.ui.select(choices, {
87-
prompt = 'Select files content> ',
88-
format_item = function(choice)
89-
return choice.key .. ' - ' .. choice.value
90-
end,
91-
}, function(choice)
92-
callback(choice and choice.key)
93-
end)
90+
filenames = {
91+
description = 'Includes names of all non-hidden files in the current workspace in chat context. Supports input (glob pattern).',
92+
input = function(callback)
93+
vim.ui.input({
94+
prompt = 'Enter glob> ',
95+
}, callback)
9496
end,
9597
resolve = function(input, source)
96-
return context.files(source.winnr, input == 'full')
98+
return context.files(source.winnr, false, input and utils.glob_to_regex(input))
9799
end,
98100
},
99101

lua/CopilotChat/context.lua

+6-4
Original file line numberDiff line numberDiff line change
@@ -369,9 +369,10 @@ end
369369

370370
--- Get list of all files in workspace
371371
---@param winnr number?
372-
---@param with_content boolean
372+
---@param with_content boolean?
373+
---@param filter string?
373374
---@return table<CopilotChat.context.embed>
374-
function M.files(winnr, with_content)
375+
function M.files(winnr, with_content, filter)
375376
local cwd = utils.win_cwd(winnr)
376377

377378
notify.publish(notify.STATUS, 'Scanning files')
@@ -380,6 +381,7 @@ function M.files(winnr, with_content)
380381
add_dirs = false,
381382
respect_gitignore = true,
382383
max_files = MAX_FILES,
384+
search_pattern = filter,
383385
})
384386

385387
notify.publish(notify.STATUS, 'Reading files')
@@ -401,11 +403,11 @@ function M.files(winnr, with_content)
401403
content = table.concat(chunk, '\n'),
402404
filename = chunk_name,
403405
filetype = 'text',
404-
score = 0.2,
406+
score = 0.1,
405407
})
406408
end
407409

408-
-- Read all files if we want content as well
410+
-- Read file contents
409411
if with_content then
410412
async.util.scheduler()
411413

lua/CopilotChat/utils.lua

+21
Original file line numberDiff line numberDiff line change
@@ -543,4 +543,25 @@ function M.empty(v)
543543
return false
544544
end
545545

546+
--- Convert glob pattern to regex pattern
547+
---@param glob string The glob pattern
548+
---@return string?
549+
function M.glob_to_regex(glob)
550+
if not glob or glob == '' then
551+
return nil
552+
end
553+
554+
-- Escape regex special chars except * and ?
555+
local pattern = glob:gsub('[%^%$%(%)%%%.%[%]%+%-]', '%%%1')
556+
557+
-- Convert glob to regex pattern
558+
pattern = pattern
559+
:gsub('%*%*/%*', '.*') -- **/* -> .*
560+
:gsub('%*%*', '.*') -- ** -> .*
561+
:gsub('%*', '[^/]*') -- * -> [^/]*
562+
:gsub('%?', '.') -- ? -> .
563+
564+
return pattern .. '$'
565+
end
566+
546567
return M

0 commit comments

Comments
 (0)