Files
chatgpt.vim/lua/chatgpt_nvim/config.lua

125 lines
5.7 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
local M = {}
local uv = vim.loop
local ok_yaml, lyaml = pcall(require, "lyaml")
local prompt_blocks = {
["go-development"] = "You are a coding assistant specialized in Go development. You will receive a projects context and user instructions related to Go code, and you must return the requested modifications or guidance. When returning modifications, follow the specified YAML structure. Keep your suggestions aligned with Go best practices and idiomatic Go.",
["typo3-development"] = "You are a coding assistant specialized in TYPO3 development. You have access to the projects context and the users instructions. Your answers should focus on TYPO3 coding guidelines, extension development best practices, and TSconfig or TypoScript recommendations. When returning modifications, follow the YAML structure given.",
["basic-prompt"] = [[
You are a coding assistant who receives a project's context and user instructions.
The user will provide a prompt, and you will guide them through a workflow:\n
1. First, ask them which files from the project are needed to understand and perform the coding task.\n
2. If file contents is needed provide a yaml which asks for the file contents.\n
For example:\n
project_name: example_project \nfiles:\n - path: \"relative/path/to/file\"\n
3. If more information or context is needed, ask the user (outside of the YAML) to provide that. For example:\n
4. When all necessary information is gathered, provide the final YAML with the project's name and a list of files
to be created or modified.\n\n
The final YAML must have a top-level key named 'project_name' that matches the project's configured name,
and a top-level key named 'files', which is a list of file changes. Each element in 'files' must be a mapping with:\n
- 'path' for the file path relative to the projects root directory.\n
- either 'content' with a multiline string for new content, or 'delete: true' if the file should be deleted.\n\n
If more context is needed at any point before providing the final YAML, request it outside of the YAML.\n\n
Additionally, it is forbidden to change any files which have not been requested or whose source code has not been provided.
]]
}
local function get_project_root()
local current_file = vim.fn.expand("%:p")
local root_dir
if current_file == "" then
root_dir = vim.fn.getcwd()
else
local file_dir = current_file:match("(.*)/")
if not file_dir then
root_dir = vim.fn.getcwd()
else
local cmd = string.format("cd %s && git rev-parse --show-toplevel 2>/dev/null", vim.fn.shellescape(file_dir))
local git_root = vim.fn.systemlist(cmd)
if vim.v.shell_error == 0 and git_root and #git_root > 0 then
root_dir = git_root[1]
else
root_dir = file_dir
end
end
end
return root_dir
end
local function get_config_path()
local root = get_project_root()
return root .. "/.chatgpt_config.yaml"
end
function M.load()
local path = get_config_path()
local fd = uv.fs_open(path, "r", 438)
local config = {
initial_prompt = "",
directories = { "." },
default_prompt_blocks = {},
token_limit = 128000,
project_name = "",
debug = false,
initial_files = {}
}
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
if type(result.initial_prompt) == "string" then
config.initial_prompt = result.initial_prompt
end
if type(result.directories) == "table" then
config.directories = result.directories
end
if type(result.default_prompt_blocks) == "table" then
config.default_prompt_blocks = result.default_prompt_blocks
end
if type(result.token_limit) == "number" then
config.token_limit = result.token_limit
end
if type(result.project_name) == "string" then
config.project_name = result.project_name
end
if type(result.debug) == "boolean" then
config.debug = result.debug
end
if type(result.initial_files) == "table" then
config.initial_files = result.initial_files
end
end
end
else
config.initial_prompt = "You are a coding assistant who receives a project's context and user instructions. You will guide the user through a workflow:\n1. First, ask the user which files are needed from the project to understand and perform the coding task.\n2. If more information or context is needed, ask for it outside of the YAML.\n3. Once all information is obtained, return the final YAML with the project_name and the files to be created/modified or deleted.\n\nThe final YAML must have:\nproject_name: <project_name>\nfiles:\n - path: \"relative/path/to/file\"\n content: |\n <file content>\n - path: \"relative/path/to/other_file\"\n delete: true\n\nIf more context is needed at any step before providing the final YAML, request it outside of the YAML."
end
if type(config.default_prompt_blocks) == "table" and #config.default_prompt_blocks > 0 then
local merged_prompt = {}
for _, block_name in ipairs(config.default_prompt_blocks) do
if prompt_blocks[block_name] then
table.insert(merged_prompt, prompt_blocks[block_name])
end
end
if #merged_prompt > 0 then
config.initial_prompt = table.concat(merged_prompt, "\n\n")
end
end
if config.debug then
vim.api.nvim_out_write("[chatgpt_nvim:config] Loaded config from: " .. path .. "\n")
vim.api.nvim_out_write("[chatgpt_nvim:config] Debug logging is enabled.\n")
end
return config
end
return M