Compare commits

...

2 Commits

3 changed files with 49 additions and 32 deletions

View File

@@ -2,6 +2,7 @@
-- Modified to: -- Modified to:
-- 1) Determine the Git root based on the currently opened file. -- 1) Determine the Git root based on the currently opened file.
-- 2) If no file is open or not in Git repo, fallback to current working directory. -- 2) If no file is open or not in Git repo, fallback to current working directory.
-- 3) Add support for configuring a list of default prompt blocks ("go-development", "typo3-development", "basic-prompt") that can override the initial prompt if provided.
local M = {} local M = {}
local uv = vim.loop local uv = vim.loop
@@ -25,7 +26,6 @@ local function get_project_root()
root_dir = vim.fn.getcwd() root_dir = vim.fn.getcwd()
else else
-- Attempt to find git root from the file's directory -- Attempt to find git root from the file's directory
-- We run git rev-parse with `cd` to the file's directory.
local cmd = string.format("cd %s && git rev-parse --show-toplevel 2>/dev/null", vim.fn.shellescape(file_dir)) 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) local git_root = vim.fn.systemlist(cmd)
if vim.v.shell_error == 0 and git_root and #git_root > 0 then if vim.v.shell_error == 0 and git_root and #git_root > 0 then
@@ -45,34 +45,58 @@ local function get_config_path()
return root .. "/.chatgpt_config.yaml" return root .. "/.chatgpt_config.yaml"
end end
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 projects context and user instructions. The user will provide a prompt, and you will return modifications to the project in a YAML structure. The YAML must have a top-level key named files, which should be a list of file changes. Each element in files must be a mapping with the keys path and content. The path should be the file path relative to the projects root directory, and content should contain the new file content as a multiline string. Do not include additional commentary outside of the YAML."
}
function M.load() function M.load()
local path = get_config_path() local path = get_config_path()
local fd = uv.fs_open(path, "r", 438) local fd = uv.fs_open(path, "r", 438)
if not fd then local config = {
return {
initial_prompt = "", initial_prompt = "",
directories = { "." }, directories = { "." },
default_prompt_blocks = {}
} }
end
if fd then
local stat = uv.fs_fstat(fd) local stat = uv.fs_fstat(fd)
local data = uv.fs_read(fd, stat.size, 0) local data = uv.fs_read(fd, stat.size, 0)
uv.fs_close(fd) uv.fs_close(fd)
if data and ok_yaml then if data and ok_yaml then
local ok, result = pcall(lyaml.load, data) local ok, result = pcall(lyaml.load, data)
if ok and type(result) == "table" then if ok and type(result) == "table" then
local config = result if type(result.initial_prompt) == "string" then
if type(config) == "table" then config.initial_prompt = result.initial_prompt
return { end
initial_prompt = config.initial_prompt or "", if type(result.directories) == "table" then
directories = config.directories or { "." }, config.directories = result.directories
} end
if type(result.default_prompt_blocks) == "table" then
config.default_prompt_blocks = result.default_prompt_blocks
end end
end end
end end
return { else
initial_prompt = "You are a coding assistant who receives a projects context and user instructions. The user will provide a prompt, and you will return modifications to the project in a YAML structure. This YAML must have a top-level key named files, which should be a list of file changes. Each element in files must be a mapping with the keys path and content. The path should be the file path relative to the projects root directory, and content should contain the new file content as a multiline string (using the YAML | literal style). Do not include additional commentary outside of the YAML.\n Here is the structure expected in your final answer:\n files:\n - path: \"relative/path/to/file1.ext\"\n content: |\n <full file content here>\n - path: \"relative/path/to/file2.ext\"\n content: |\n <full file content here>\n Based on the prompt and project context provided, you must only return the YAML structure shown above (with actual file paths and contents substituted in). Any file that should be created or modified must appear as one of the files entries. The content should contain the complete and final code for that file, reflecting all changes requested by the user.", -- Default fallback configuration
directories = { "." }, config.initial_prompt = "You are a coding assistant who receives a projects context and user instructions. The user will provide a prompt, and you will return modifications to the project in a YAML structure. This YAML must have a top-level key named files, which should be a list of file changes. Each element in files must be a mapping with the keys path and content. The path should be the file path relative to the projects root directory, and content should contain the new file content as a multiline string (using the YAML | literal style). Do not include additional commentary outside of the YAML.\n Here is the structure expected in your final answer:\n files:\n - path: \"relative/path/to/file1.ext\"\n content: |\n <full file content here>\n - path: \"relative/path/to/file2.ext\"\n content: |\n <full file content here>\n Based on the prompt and project context provided, you must only return the YAML structure shown above (with actual file paths and contents substituted in). Any file that should be created or modified must appear as one of the files entries. The content should contain the complete and final code for that file, reflecting all changes requested by the user."
} end
-- If default_prompt_blocks are specified, concatenate all matching prompts
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
return config
end end
return M return M

View File

@@ -92,7 +92,7 @@ function M.get_file_contents(files)
local data = uv.fs_read(fd, stat.size, 0) local data = uv.fs_read(fd, stat.size, 0)
uv.fs_close(fd) uv.fs_close(fd)
if data then if data then
table.insert(sections, "\n<<<CGPT Current File\n" .. path .. "\n" .. data .. "\n<<<CGPT Current File END\n") table.insert(sections, "\nFile: `" .. f .. "`\n```\n" .. data .. "\n```\n")
end end
else else
uv.fs_close(fd) uv.fs_close(fd)

View File

@@ -39,18 +39,11 @@ function M.run_chatgpt_command()
local current_file_content, current_file_path = context.get_current_file() local current_file_content, current_file_path = context.get_current_file()
local readme_content = context.get_readme_content() local readme_content = context.get_readme_content()
-- Make the prompt more readable for the O1 model:
-- 1. Include initial prompt and user input at the start.
-- 2. Provide a clear project structure section.
-- 3. Clearly label the files section.
-- 4. The file_sections already include <<<CGPT Current File blocks for each file,
-- we just need to ensure there's a clear intro.
local sections = { local sections = {
conf.initial_prompt .. "\n" .. user_input, conf.initial_prompt .. "\n" .. user_input,
"\n\nProject Structure:\n", "\n\nProject Structure:\n",
project_structure, project_structure,
"\n\nBelow are the files from the project, each enclosed in <<<CGPT Current File ... >>> blocks for clarity.\n" "\n\nBelow are the files from the project, each preceded by its filename in backticks and enclosed in triple backticks.\n"
} }
table.insert(sections, file_sections) table.insert(sections, file_sections)