79 lines
2.8 KiB
Lua
79 lines
2.8 KiB
Lua
local handler = require("chatgpt_nvim.handler")
|
||
local robust_lsp = require("chatgpt_nvim.tools.lsp_robust_diagnostics")
|
||
|
||
local M = {}
|
||
|
||
-- Enhanced search_and_replace to track if a string was found. We use Lua’s gsub return value
|
||
-- (updatedString, replacementCount) to see if any replacements occurred.
|
||
local function search_and_replace(original, replacements)
|
||
local updated = original
|
||
local info_msgs = {}
|
||
|
||
for _, r in ipairs(replacements) do
|
||
local search_str = r.search or ""
|
||
local replace_str = r.replace or ""
|
||
|
||
local replacement_count = 0
|
||
updated, replacement_count = updated:gsub(search_str, replace_str)
|
||
|
||
-- If the string was not found, append an info message
|
||
if replacement_count == 0 then
|
||
table.insert(info_msgs, string.format(
|
||
"[replace_in_file Info] The string '%s' was NOT found in the file and was not replaced.",
|
||
search_str
|
||
))
|
||
else
|
||
table.insert(info_msgs, string.format(
|
||
"[replace_in_file Info] The string '%s' was replaced %d time(s).",
|
||
search_str,
|
||
replacement_count
|
||
))
|
||
end
|
||
end
|
||
|
||
return updated, table.concat(info_msgs, "\n")
|
||
end
|
||
|
||
M.run = function(tool_call, conf, prompt_user_tool_accept, is_subpath, read_file)
|
||
local path = tool_call.path
|
||
local replacements = tool_call.replacements or {}
|
||
|
||
if not path or #replacements == 0 then
|
||
return "[replace_in_file] Missing 'path' or 'replacements'."
|
||
end
|
||
local root = vim.fn.getcwd()
|
||
|
||
if not is_subpath(root, path) then
|
||
return string.format("Tool [replace_in_file for '%s'] REJECTED. Path outside project root.", path)
|
||
end
|
||
|
||
local orig_data = read_file(path)
|
||
if not orig_data then
|
||
return string.format("[replace_in_file for '%s'] FAILED. Could not read file.", path)
|
||
end
|
||
|
||
-- Now we get not only the updated data but also info messages about replacements
|
||
local updated_data, info_messages = search_and_replace(orig_data, replacements)
|
||
handler.write_file(path, updated_data, conf)
|
||
|
||
local msg = {}
|
||
msg[#msg+1] = string.format("[replace_in_file for '%s'] Result:\nThe content was successfully saved to %s.", path, path)
|
||
msg[#msg+1] = "\nHere is the full, updated content of the file that was saved:\n"
|
||
msg[#msg+1] = string.format("<final_file_content path=\"%s\">\n%s\n</final_file_content>", path, updated_data)
|
||
msg[#msg+1] = "\nIMPORTANT: For any future changes to this file, use the final_file_content shown above as your reference.\n"
|
||
|
||
-- If there are any info messages (strings not found, etc.), include them
|
||
if info_messages and info_messages ~= "" then
|
||
msg[#msg+1] = "\nAdditional info about the replacement operation:\n" .. info_messages .. "\n"
|
||
end
|
||
|
||
if conf.auto_lint then
|
||
local diag_str = robust_lsp.lsp_check_file_content(path, updated_data, 3000)
|
||
msg[#msg+1] = "\n" .. diag_str
|
||
end
|
||
|
||
return table.concat(msg, "")
|
||
end
|
||
|
||
return M
|