-- lua/chatgpt_nvim/context.lua -- Modified to: -- 1) Use directories from config to build project structure. -- 2) Include file contents from those directories. -- 3) Skip files listed in .gitignore. -- local M = {} local uv = vim.loop -- Returns a set of files mentioned in .gitignore patterns. local function load_gitignore_patterns(root) local gitignore_path = root .. "/.gitignore" local fd = uv.fs_open(gitignore_path, "r", 438) if not fd then return {} end local stat = uv.fs_fstat(fd) local data = uv.fs_read(fd, stat.size, 0) uv.fs_close(fd) if not data then return {} end local patterns = {} for line in data:gmatch("[^\r\n]+") do line = line:match("^%s*(.-)%s*$") -- trim if line ~= "" and not line:match("^#") then patterns[#patterns+1] = line end end return patterns end local function should_ignore_file(file, ignore_patterns) for _, pattern in ipairs(ignore_patterns) do -- Simple pattern matching. For more complex patterns, consider using lua patterns. -- This is a basic implementation. Adjust as needed. if file:find(pattern, 1, true) then return true end end return false end local function scandir(dir, ignore_patterns, files) files = files or {} local fd = uv.fs_opendir(dir, nil, 50) if not fd then return files end while true do local ents = uv.fs_readdir(fd) if not ents then break end for _, ent in ipairs(ents) do local fullpath = dir .. "/" .. ent.name if not should_ignore_file(fullpath, ignore_patterns) then if ent.type == "file" then table.insert(files, fullpath) elseif ent.type == "directory" and ent.name ~= ".git" then scandir(fullpath, ignore_patterns, files) end end end end uv.fs_closedir(fd) return files end function M.get_project_files(directories) local root = vim.fn.getcwd() local ignore_patterns = load_gitignore_patterns(root) local all_files = {} for _, dir in ipairs(directories) do local abs_dir = dir if not abs_dir:match("^/") then abs_dir = root .. "/" .. dir end scandir(abs_dir, ignore_patterns, all_files) end return all_files end function M.get_project_structure(directories) local files = M.get_project_files(directories) -- Create a listing of files only (relative to root) local root = vim.fn.getcwd() local rel_files = {} for _, f in ipairs(files) do local rel = f:gsub("^" .. root .. "/", "") table.insert(rel_files, rel) end local structure = "Files:\n" .. table.concat(rel_files, "\n") return structure end function M.get_file_contents(files) local root = vim.fn.getcwd() local sections = {} for _, f in ipairs(files) do local fd = uv.fs_open(root .. "/" .. f, "r", 438) if fd then local stat = uv.fs_fstat(fd) local data = uv.fs_read(fd, stat.size, 0) uv.fs_close(fd) if data then table.insert(sections, "\n<<