changes for a better approach

This commit is contained in:
2024-12-12 18:57:35 +01:00
parent 7db810c04f
commit 78b0172772
7 changed files with 285 additions and 148 deletions

View File

@@ -1,61 +1,134 @@
-- 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 = {}
function M.get_current_file()
local buf = vim.api.nvim_get_current_buf()
local path = vim.api.nvim_buf_get_name(buf)
if path == "" then
path = "untitled"
end
local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
local content = table.concat(lines, "\n")
return content, path
end
local uv = vim.loop
function M.get_project_structure()
local handle = io.popen("git ls-files 2>/dev/null")
if handle then
local result = handle:read("*a")
handle:close()
if result and result ~= "" then
return "Files:\n" .. result
-- 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
local dhandle = io.popen("find . -type f")
if dhandle then
local dresult = dhandle:read("*a")
dhandle:close()
return "Files:\n" .. (dresult or "")
end
return "No files found."
return patterns
end
local function get_git_root()
local handle = io.popen("git rev-parse --show-toplevel 2>/dev/null")
if handle then
local root = handle:read("*l")
handle:close()
return root
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 nil
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<<<CGPT Current File\n" .. (root .. "/" .. f) .. "\n" .. data .. "\n<<<CGPT Current File END\n")
end
end
end
return table.concat(sections, "\n")
end
function M.get_current_file()
local current_path = vim.fn.expand("%:p")
if current_path == "" then
return nil, nil
end
local fd = uv.fs_open(current_path, "r", 438)
if not fd then return nil, current_path end
local stat = uv.fs_fstat(fd)
local data = uv.fs_read(fd, stat.size, 0)
uv.fs_close(fd)
return data, current_path
end
function M.get_readme_content()
local root = get_git_root()
if not root then
return nil
end
local readme_path = root .. "/README.md"
local f = io.open(readme_path, "r")
if f then
local content = f:read("*a")
f:close()
if content and content ~= "" then
return content
end
end
return nil
local root = vim.fn.getcwd()
local fd = uv.fs_open(root .. "/README.md", "r", 438)
if not fd then return nil end
local stat = uv.fs_fstat(fd)
local data = uv.fs_read(fd, stat.size, 0)
uv.fs_close(fd)
return data
end
return M