|
| 1 | +local async = require('plenary.async') |
1 | 2 | local log = require('plenary.log') |
2 | 3 |
|
3 | 4 | local M = {} |
@@ -72,6 +73,78 @@ local function data_ranked_by_relatedness(query, data, top_n) |
72 | 73 | return result |
73 | 74 | end |
74 | 75 |
|
| 76 | +local get_context_data = async.wrap(function(context, bufnr, callback) |
| 77 | + vim.schedule(function() |
| 78 | + local outline = {} |
| 79 | + if context == 'buffers' then |
| 80 | + outline = vim.tbl_map( |
| 81 | + M.build_outline, |
| 82 | + vim.tbl_filter(function(b) |
| 83 | + return vim.api.nvim_buf_is_loaded(b) and vim.fn.buflisted(b) == 1 |
| 84 | + end, vim.api.nvim_list_bufs()) |
| 85 | + ) |
| 86 | + elseif context == 'buffer' then |
| 87 | + table.insert(outline, M.build_outline(bufnr)) |
| 88 | + elseif context == 'files' then |
| 89 | + outline = M.build_file_map() |
| 90 | + end |
| 91 | + |
| 92 | + callback(outline) |
| 93 | + end) |
| 94 | +end, 3) |
| 95 | + |
| 96 | +--- Get supported contexts |
| 97 | +---@return table<string> |
| 98 | +function M.supported_contexts() |
| 99 | + return { |
| 100 | + buffers = 'Includes all open buffers in chat context', |
| 101 | + buffer = 'Includes only the current buffer in chat context', |
| 102 | + files = 'Includes all non-hidden filenames in the current workspace in chat context', |
| 103 | + } |
| 104 | +end |
| 105 | + |
| 106 | +--- Get list of all files in workspace |
| 107 | +---@return table<CopilotChat.copilot.embed> |
| 108 | +function M.build_file_map() |
| 109 | + -- Use vim.fn.glob() to get all files |
| 110 | + local files = vim.fn.glob('**/*', false, true) |
| 111 | + |
| 112 | + -- Filter out hidden files |
| 113 | + local filtered_files = vim.tbl_filter(function(file) |
| 114 | + local file_name = vim.fn.fnamemodify(file, ':t') |
| 115 | + local file_dir = vim.fn.fnamemodify(file, ':h') |
| 116 | + |
| 117 | + if file_name:match('^%.') or file_dir:match('^%.') then |
| 118 | + return false |
| 119 | + end |
| 120 | + |
| 121 | + return vim.fn.isdirectory(file) == 0 |
| 122 | + end, files) |
| 123 | + |
| 124 | + if #filtered_files == 0 then |
| 125 | + return {} |
| 126 | + end |
| 127 | + |
| 128 | + local out = {} |
| 129 | + |
| 130 | + -- Create embeddings in chunks |
| 131 | + local chunk_size = 100 |
| 132 | + for i = 1, #filtered_files, chunk_size do |
| 133 | + local chunk = {} |
| 134 | + for j = i, math.min(i + chunk_size - 1, #filtered_files) do |
| 135 | + table.insert(chunk, filtered_files[j]) |
| 136 | + end |
| 137 | + |
| 138 | + table.insert(out, { |
| 139 | + content = table.concat(chunk, '\n'), |
| 140 | + filename = 'project_map', |
| 141 | + filetype = 'text', |
| 142 | + }) |
| 143 | + end |
| 144 | + |
| 145 | + return out |
| 146 | +end |
| 147 | + |
75 | 148 | --- Build an outline for a buffer |
76 | 149 | --- FIXME: Handle multiline function argument definitions when building the outline |
77 | 150 | ---@param bufnr number |
@@ -198,21 +271,7 @@ function M.find_for_query(copilot, opts) |
198 | 271 | local filetype = opts.filetype |
199 | 272 | local bufnr = opts.bufnr |
200 | 273 |
|
201 | | - local outline = {} |
202 | | - if context == 'buffers' then |
203 | | - -- For multiple buffers, only make outlines |
204 | | - outline = vim.tbl_map( |
205 | | - function(b) |
206 | | - return M.build_outline(b) |
207 | | - end, |
208 | | - vim.tbl_filter(function(b) |
209 | | - return vim.api.nvim_buf_is_loaded(b) and vim.fn.buflisted(b) == 1 |
210 | | - end, vim.api.nvim_list_bufs()) |
211 | | - ) |
212 | | - elseif context == 'buffer' then |
213 | | - table.insert(outline, M.build_outline(bufnr)) |
214 | | - end |
215 | | - |
| 274 | + local outline = get_context_data(context, bufnr) |
216 | 275 | outline = vim.tbl_filter(function(item) |
217 | 276 | return item ~= nil |
218 | 277 | end, outline) |
|
0 commit comments