feat: change to diff workflow
This commit is contained in:
@@ -111,17 +111,30 @@ local function preview_changes(changes)
|
||||
""
|
||||
})
|
||||
for _, fileinfo in ipairs(changes) do
|
||||
local indicator = (fileinfo.delete == true) and "Delete file" or "Write file"
|
||||
vim.api.nvim_buf_set_lines(bufnr, -1, -1, false, {
|
||||
string.format("=== %s: %s ===", indicator, fileinfo.path or "<no path>")
|
||||
})
|
||||
if fileinfo.content then
|
||||
if fileinfo.delete then
|
||||
vim.api.nvim_buf_set_lines(bufnr, -1, -1, false, {
|
||||
string.format("=== Delete file: %s ===", fileinfo.path or "<no path>"),
|
||||
""
|
||||
})
|
||||
elseif fileinfo.diff then
|
||||
vim.api.nvim_buf_set_lines(bufnr, -1, -1, false, {
|
||||
string.format("=== Diff for file: %s ===", fileinfo.path or "<no path>")
|
||||
})
|
||||
local lines = vim.split(fileinfo.diff, "\n")
|
||||
for _, line in ipairs(lines) do
|
||||
vim.api.nvim_buf_set_lines(bufnr, -1, -1, false, { line })
|
||||
end
|
||||
vim.api.nvim_buf_set_lines(bufnr, -1, -1, false, { "" })
|
||||
elseif fileinfo.content then
|
||||
vim.api.nvim_buf_set_lines(bufnr, -1, -1, false, {
|
||||
string.format("=== New file: %s ===", fileinfo.path or "<no path>")
|
||||
})
|
||||
local lines = vim.split(fileinfo.content, "\n")
|
||||
for _, line in ipairs(lines) do
|
||||
vim.api.nvim_buf_set_lines(bufnr, -1, -1, false, { line })
|
||||
end
|
||||
vim.api.nvim_buf_set_lines(bufnr, -1, -1, false, { "" })
|
||||
end
|
||||
vim.api.nvim_buf_set_lines(bufnr, -1, -1, false, { "" })
|
||||
end
|
||||
|
||||
vim.cmd("vsplit")
|
||||
@@ -139,9 +152,16 @@ local function partial_accept(changes)
|
||||
""
|
||||
}
|
||||
for _, fileinfo in ipairs(changes) do
|
||||
local action = (fileinfo.delete == true) and "[DELETE]" or "[WRITE]"
|
||||
table.insert(lines, string.format("%s %s", action, fileinfo.path or "<no path>"))
|
||||
if fileinfo.content then
|
||||
if fileinfo.delete then
|
||||
table.insert(lines, string.format("[DELETE] %s", fileinfo.path or "<no path>"))
|
||||
elseif fileinfo.diff then
|
||||
table.insert(lines, string.format("[DIFF] %s", fileinfo.path or "<no path>"))
|
||||
local diff_lines = vim.split(fileinfo.diff, "\n")
|
||||
for _, dl in ipairs(diff_lines) do
|
||||
table.insert(lines, " " .. dl)
|
||||
end
|
||||
elseif fileinfo.content then
|
||||
table.insert(lines, string.format("[WRITE] %s", fileinfo.path or "<no path>"))
|
||||
local content_lines = vim.split(fileinfo.content, "\n")
|
||||
for _, cl in ipairs(content_lines) do
|
||||
table.insert(lines, " " .. cl)
|
||||
@@ -156,46 +176,53 @@ local function partial_accept(changes)
|
||||
local function on_write()
|
||||
local edited_lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
|
||||
local keep_current = false
|
||||
local current_fileinfo = { path = nil, content = nil, delete = false }
|
||||
local content_accum = {}
|
||||
local current_fileinfo = { path = nil, delete = false, diff = nil, content = nil }
|
||||
local accum = {}
|
||||
|
||||
for _, line in ipairs(edited_lines) do
|
||||
if line:match("^#") or line == "" then
|
||||
goto continue
|
||||
end
|
||||
|
||||
local del_match = line:match("^%[DELETE%] (.+)")
|
||||
local diff_match = line:match("^%[DIFF%] (.+)")
|
||||
local write_match = line:match("^%[WRITE%] (.+)")
|
||||
if del_match then
|
||||
|
||||
if del_match or diff_match or write_match then
|
||||
-- store previous if any
|
||||
if keep_current and (current_fileinfo.path ~= nil) then
|
||||
if #content_accum > 0 then
|
||||
current_fileinfo.content = table.concat(content_accum, "\n")
|
||||
if current_fileinfo.diff then
|
||||
current_fileinfo.diff = table.concat(accum, "\n")
|
||||
elseif current_fileinfo.content then
|
||||
current_fileinfo.content = table.concat(accum, "\n")
|
||||
end
|
||||
table.insert(final_changes, current_fileinfo)
|
||||
end
|
||||
|
||||
accum = {}
|
||||
keep_current = true
|
||||
current_fileinfo = { path = del_match, delete = true, content = nil }
|
||||
content_accum = {}
|
||||
elseif write_match then
|
||||
if keep_current and (current_fileinfo.path ~= nil) then
|
||||
if #content_accum > 0 then
|
||||
current_fileinfo.content = table.concat(content_accum, "\n")
|
||||
end
|
||||
table.insert(final_changes, current_fileinfo)
|
||||
|
||||
if del_match then
|
||||
current_fileinfo = { path = del_match, delete = true, diff = nil, content = nil }
|
||||
elseif diff_match then
|
||||
current_fileinfo = { path = diff_match, delete = false, diff = "", content = nil }
|
||||
elseif write_match then
|
||||
current_fileinfo = { path = write_match, delete = false, diff = nil, content = "" }
|
||||
end
|
||||
keep_current = true
|
||||
current_fileinfo = { path = write_match, delete = false, content = nil }
|
||||
content_accum = {}
|
||||
|
||||
else
|
||||
if keep_current then
|
||||
table.insert(content_accum, line:gsub("^%s*", ""))
|
||||
table.insert(accum, line:gsub("^%s*", ""))
|
||||
end
|
||||
end
|
||||
::continue::
|
||||
end
|
||||
|
||||
if keep_current and (current_fileinfo.path ~= nil) then
|
||||
if #content_accum > 0 then
|
||||
current_fileinfo.content = table.concat(content_accum, "\n")
|
||||
if current_fileinfo.diff ~= nil then
|
||||
current_fileinfo.diff = table.concat(accum, "\n")
|
||||
elseif current_fileinfo.content ~= nil then
|
||||
current_fileinfo.content = table.concat(accum, "\n")
|
||||
end
|
||||
table.insert(final_changes, current_fileinfo)
|
||||
end
|
||||
@@ -399,7 +426,7 @@ function M.run_chatgpt_command()
|
||||
|
||||
```yaml
|
||||
commands:
|
||||
- command: "ls"
|
||||
- command: "list"
|
||||
dir: "some/directory"
|
||||
|
||||
- command: "grep"
|
||||
@@ -407,7 +434,6 @@ function M.run_chatgpt_command()
|
||||
target: "path/to/file/or/directory"
|
||||
```
|
||||
|
||||
The "ls" command uses the system's 'ls' command to list directory contents.
|
||||
When these commands are present and enable_debug_commands is true, I'll execute them and return the results in the clipboard.
|
||||
]])
|
||||
end
|
||||
@@ -467,7 +493,7 @@ function M.run_chatgpt_paste_command()
|
||||
|
||||
local is_final = false
|
||||
for _, fileinfo in ipairs(data.files) do
|
||||
if fileinfo.content or fileinfo.delete == true then
|
||||
if fileinfo.content or fileinfo.delete == true or fileinfo.diff then
|
||||
is_final = true
|
||||
break
|
||||
end
|
||||
@@ -518,12 +544,20 @@ function M.run_chatgpt_paste_command()
|
||||
ui.debug_log("Deleting file: " .. fileinfo.path)
|
||||
handler.delete_file(fileinfo.path)
|
||||
print("Deleted: " .. fileinfo.path)
|
||||
elseif fileinfo.diff then
|
||||
ui.debug_log("Applying diff to file: " .. fileinfo.path)
|
||||
local success, err = handler.apply_diff(fileinfo.path, fileinfo.diff)
|
||||
if not success then
|
||||
vim.api.nvim_err_writeln("Error applying diff: " .. (err or "unknown"))
|
||||
else
|
||||
print("Patched: " .. fileinfo.path)
|
||||
end
|
||||
elseif fileinfo.content then
|
||||
ui.debug_log("Writing file: " .. fileinfo.path)
|
||||
ui.debug_log("Writing new file: " .. fileinfo.path)
|
||||
handler.write_file(fileinfo.path, fileinfo.content)
|
||||
print("Wrote: " .. fileinfo.path)
|
||||
else
|
||||
vim.api.nvim_err_writeln("Invalid file entry. Must have 'content' or 'delete'.")
|
||||
vim.api.nvim_err_writeln("Invalid file entry. Must have 'diff', 'content', or 'delete'.")
|
||||
end
|
||||
::continue::
|
||||
end
|
||||
@@ -553,7 +587,7 @@ function M.run_chatgpt_paste_command()
|
||||
"\n\nProject name: " .. (conf.project_name or ""),
|
||||
"\n\nBelow are the requested files from the project, each preceded by its filename in backticks and enclosed in triple backticks.\n",
|
||||
table.concat(file_sections, "\n"),
|
||||
"\n\nIf you need more files, please respond again in YAML listing additional files. If you have all information you need, provide the final YAML with `project_name` and `files` (with `content` or `delete`) to apply changes.\n"
|
||||
"\n\nIf you need more files, please respond again in YAML listing additional files. If you have all information you need, provide the final YAML with `project_name` and `files` (use `diff`, `content`, or `delete`) to apply changes.\n"
|
||||
}
|
||||
|
||||
local prompt = table.concat(sections, "\n")
|
||||
@@ -647,7 +681,6 @@ function M.run_chatgpt_current_buffer_command()
|
||||
target: "path/to/file/or/directory"
|
||||
```
|
||||
|
||||
The "list" command uses the system's 'ls' command to list directory contents.
|
||||
When these commands are present and enable_debug_commands is true, I'll execute them and return the results in the clipboard.
|
||||
]])
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user