171 lines
5.3 KiB
Lua
171 lines
5.3 KiB
Lua
local M = {}
|
|
local uv = vim.loop
|
|
|
|
local config = require('chatgpt_nvim.config')
|
|
|
|
local function ensure_dir(path)
|
|
local st = uv.fs_stat(path)
|
|
if st and st.type == 'directory' then
|
|
return true
|
|
end
|
|
local parent = path:match("(.*)/")
|
|
if parent and parent ~= "" then
|
|
ensure_dir(parent)
|
|
end
|
|
uv.fs_mkdir(path, 511)
|
|
return true
|
|
end
|
|
|
|
function M.get_clipboard_content()
|
|
local conf = config.load()
|
|
local content = vim.fn.getreg('+')
|
|
if conf.debug then
|
|
vim.api.nvim_out_write("[chatgpt_nvim:handler] Clipboard content length: " .. #content .. "\n")
|
|
end
|
|
return content
|
|
end
|
|
|
|
function M.write_file(filepath, content)
|
|
local conf = config.load()
|
|
local dir = filepath:match("(.*)/")
|
|
if dir and dir ~= "" then
|
|
ensure_dir(dir)
|
|
end
|
|
local fd = uv.fs_open(filepath, "w", 438)
|
|
if not fd then
|
|
vim.api.nvim_err_writeln("Could not open file for writing: " .. filepath)
|
|
if conf.debug then
|
|
vim.api.nvim_out_write("[chatgpt_nvim:handler] Failed to open file for writing: " .. filepath .. "\n")
|
|
end
|
|
return
|
|
end
|
|
uv.fs_write(fd, content, -1)
|
|
uv.fs_close(fd)
|
|
if conf.debug then
|
|
vim.api.nvim_out_write("[chatgpt_nvim:handler] Successfully wrote file: " .. filepath .. "\n")
|
|
end
|
|
end
|
|
|
|
function M.delete_file(filepath)
|
|
local conf = config.load()
|
|
local st = uv.fs_stat(filepath)
|
|
if st then
|
|
local success, err = uv.fs_unlink(filepath)
|
|
if not success then
|
|
vim.api.nvim_err_writeln("Could not delete file: " .. filepath .. " - " .. (err or "unknown error"))
|
|
if conf.debug then
|
|
vim.api.nvim_out_write("[chatgpt_nvim:handler] Failed to delete file: " .. filepath .. "\n")
|
|
end
|
|
else
|
|
if conf.debug then
|
|
vim.api.nvim_out_write("[chatgpt_nvim:handler] Deleted file: " .. filepath .. "\n")
|
|
end
|
|
end
|
|
else
|
|
vim.api.nvim_err_writeln("File not found, cannot delete: " .. filepath)
|
|
if conf.debug then
|
|
vim.api.nvim_out_write("[chatgpt_nvim:handler] File not found for deletion: " .. filepath .. "\n")
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Applies a unified diff to the specified file.
|
|
function M.apply_diff(filepath, diff_content)
|
|
local conf = config.load()
|
|
local tmp_original = vim.fn.tempname()
|
|
local tmp_patch = vim.fn.tempname()
|
|
|
|
-- 1) Read original file (or empty if it doesn't exist)
|
|
local fd_in = uv.fs_open(filepath, "r", 438)
|
|
local original_data = ""
|
|
if fd_in then
|
|
local stat = uv.fs_fstat(fd_in)
|
|
original_data = uv.fs_read(fd_in, stat.size, 0)
|
|
uv.fs_close(fd_in)
|
|
end
|
|
|
|
-- 2) Write original content to a temp file
|
|
local fd_orig = uv.fs_open(tmp_original, "w", 438)
|
|
if fd_orig then
|
|
uv.fs_write(fd_orig, original_data, -1)
|
|
uv.fs_close(fd_orig)
|
|
end
|
|
|
|
-- 3) Write diff to a temp file
|
|
local fd_patch = uv.fs_open(tmp_patch, "w", 438)
|
|
if fd_patch then
|
|
uv.fs_write(fd_patch, diff_content, -1)
|
|
uv.fs_close(fd_patch)
|
|
else
|
|
return false, "Could not open temporary file to write patch."
|
|
end
|
|
|
|
if conf.debug then
|
|
vim.api.nvim_out_write("[chatgpt_nvim:handler] Applying diff to: " .. filepath .. "\n")
|
|
vim.api.nvim_out_write("[chatgpt_nvim:handler] Original file contents saved at: " .. tmp_original .. "\n")
|
|
vim.api.nvim_out_write("[chatgpt_nvim:handler] Patch file saved at: " .. tmp_patch .. "\n")
|
|
vim.api.nvim_out_write("[chatgpt_nvim:handler] Patch contents:\n" .. diff_content .. "\n")
|
|
end
|
|
|
|
-- 4) Attempt to run 'patch'
|
|
local patch_cmd = "patch -u --reject-file=- " .. vim.fn.shellescape(tmp_original)
|
|
.. " < " .. vim.fn.shellescape(tmp_patch)
|
|
local handle = io.popen(patch_cmd)
|
|
if not handle then
|
|
return false, "Failed to run patch command."
|
|
end
|
|
local result = handle:read("*a")
|
|
local success_close, errmsg = handle:close()
|
|
|
|
if conf.debug then
|
|
vim.api.nvim_out_write("[chatgpt_nvim:handler] Patch command was: " .. patch_cmd .. "\n")
|
|
vim.api.nvim_out_write("[chatgpt_nvim:handler] Patch command output:\n" .. (result or "") .. "\n")
|
|
if not success_close then
|
|
vim.api.nvim_out_write("[chatgpt_nvim:handler] Patch command closed with error: " .. (errmsg or "unknown") .. "\n")
|
|
else
|
|
vim.api.nvim_out_write("[chatgpt_nvim:handler] Patch command succeeded.\n")
|
|
end
|
|
end
|
|
|
|
if not success_close then
|
|
if conf.debug then
|
|
vim.api.nvim_out_write("[chatgpt_nvim:handler] Patch command failed: " .. (errmsg or "unknown") .. "\n")
|
|
end
|
|
return false, errmsg
|
|
end
|
|
|
|
-- If successful, read the patched file and write it back
|
|
if conf.debug then
|
|
local debug_read = uv.fs_open(tmp_original, "r", 438)
|
|
if debug_read then
|
|
local debug_stat = uv.fs_fstat(debug_read)
|
|
local debug_data = uv.fs_read(debug_read, debug_stat.size, 0)
|
|
uv.fs_close(debug_read)
|
|
vim.api.nvim_out_write("[chatgpt_nvim:handler] Post-patch temp file:\n" .. debug_data .. "\n")
|
|
vim.api.nvim_out_write("[chatgpt_nvim:handler] End of patched temp file content.\n")
|
|
end
|
|
end
|
|
|
|
local fd_out = uv.fs_open(tmp_original, "r", 438)
|
|
if fd_out then
|
|
local stat_out = uv.fs_fstat(fd_out)
|
|
local new_data = uv.fs_read(fd_out, stat_out.size, 0)
|
|
uv.fs_close(fd_out)
|
|
|
|
M.write_file(filepath, new_data)
|
|
if conf.debug then
|
|
vim.api.nvim_out_write("[chatgpt_nvim:handler] Successfully applied patch to: " .. filepath .. "\n")
|
|
end
|
|
else
|
|
return false, "Could not read patched file."
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
function M.finish()
|
|
print("Finished processing files.")
|
|
end
|
|
|
|
return M
|