feat: also allow the config file without dot, give an error message at search replace if search was not found in file
This commit is contained in:
@@ -4,6 +4,7 @@ local uv = vim.loop
|
||||
local ok_yaml, lyaml = pcall(require, "lyaml")
|
||||
local prompts = require("chatgpt_nvim.prompts")
|
||||
|
||||
-- Determines the Git root or fallback directory.
|
||||
local function get_project_root()
|
||||
local current_file = vim.fn.expand("%:p")
|
||||
local root_dir
|
||||
@@ -28,14 +29,30 @@ local function get_project_root()
|
||||
return root_dir
|
||||
end
|
||||
|
||||
-- Attempt to locate either .chatgpt_config.yaml or chatgpt_config.yaml, returning whichever exists first.
|
||||
local function get_config_path()
|
||||
local root = get_project_root()
|
||||
return root .. "/.chatgpt_config.yaml"
|
||||
local dot_config = root .. "/.chatgpt_config.yaml"
|
||||
local non_dot_config = root .. "/chatgpt_config.yaml"
|
||||
|
||||
local dot_fd = uv.fs_open(dot_config, "r", 438)
|
||||
if dot_fd then
|
||||
uv.fs_close(dot_fd)
|
||||
return dot_config
|
||||
end
|
||||
|
||||
local non_dot_fd = uv.fs_open(non_dot_config, "r", 438)
|
||||
if non_dot_fd then
|
||||
uv.fs_close(non_dot_fd)
|
||||
return non_dot_config
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
function M.load()
|
||||
-- Attempt to find either config file, else fallback
|
||||
local path = get_config_path()
|
||||
local fd = uv.fs_open(path, "r", 438)
|
||||
local config = {
|
||||
initial_prompt = "",
|
||||
directories = { "." },
|
||||
@@ -62,10 +79,22 @@ function M.load()
|
||||
}
|
||||
}
|
||||
|
||||
-- If no config file found, alert user and return default config
|
||||
if not path then
|
||||
config.initial_prompt = "You are a coding assistant who receives a project's context and user instructions..."
|
||||
vim.notify(
|
||||
"No config file found (tried .chatgpt_config.yaml, chatgpt_config.yaml). Using defaults.",
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
return config
|
||||
end
|
||||
|
||||
local fd = uv.fs_open(path, "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 and ok_yaml then
|
||||
local ok, result = pcall(lyaml.load, data)
|
||||
if ok and type(result) == "table" then
|
||||
@@ -109,7 +138,6 @@ function M.load()
|
||||
config.enable_step_by_step = result.enable_step_by_step
|
||||
end
|
||||
|
||||
-- auto_lint controls whether we do LSP-based checks
|
||||
if type(result.auto_lint) == "boolean" then
|
||||
config.auto_lint = result.auto_lint
|
||||
end
|
||||
|
||||
@@ -289,6 +289,7 @@ local M = {
|
||||
- If multiple tools are needed, list them sequentially in the `tools` array.
|
||||
- Always run at least one tool (e.g., `readFile`, `editFile`, `executeCommand`), exept you have finished.
|
||||
- Always just include one yaml in the response with all the tools you want to run in that yaml.
|
||||
- Never do write operations on a file which you have not read before.
|
||||
- The plugin will verify the `project_name` is correct before running any tools.
|
||||
- If the response grows too large, I'll guide you to break it into smaller steps.
|
||||
]],
|
||||
|
||||
@@ -3,14 +3,35 @@ 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 ""
|
||||
updated = updated:gsub(search_str, replace_str)
|
||||
|
||||
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
|
||||
|
||||
return updated, table.concat(info_msgs, "\n")
|
||||
end
|
||||
|
||||
M.run = function(tool_call, conf, prompt_user_tool_accept, is_subpath, read_file)
|
||||
@@ -31,7 +52,8 @@ M.run = function(tool_call, conf, prompt_user_tool_accept, is_subpath, read_file
|
||||
return string.format("[replace_in_file for '%s'] FAILED. Could not read file.", path)
|
||||
end
|
||||
|
||||
local updated_data = search_and_replace(orig_data, replacements)
|
||||
-- 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 = {}
|
||||
@@ -40,6 +62,11 @@ M.run = function(tool_call, conf, prompt_user_tool_accept, is_subpath, read_file
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user