From 0d5ed2c52a462463c2c9e9b8c47c0dce9c8dc581 Mon Sep 17 00:00:00 2001 From: Dominik Polakovics Date: Thu, 12 Dec 2024 21:25:28 +0100 Subject: [PATCH] feat: add default prompt blocks and the possibility to specify them in the config --- lua/chatgpt_nvim/config.lua | 70 +++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/lua/chatgpt_nvim/config.lua b/lua/chatgpt_nvim/config.lua index ba71ef9..4745a58 100644 --- a/lua/chatgpt_nvim/config.lua +++ b/lua/chatgpt_nvim/config.lua @@ -2,6 +2,7 @@ -- Modified to: -- 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. +-- 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 uv = vim.loop @@ -25,7 +26,6 @@ local function get_project_root() root_dir = vim.fn.getcwd() else -- 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 git_root = vim.fn.systemlist(cmd) 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" end +local prompt_blocks = { + ["go-development"] = "You are a coding assistant specialized in Go development. You will receive a project’s 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 project’s context and the user’s 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 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 project’s 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() local path = get_config_path() local fd = uv.fs_open(path, "r", 438) - if not fd then - return { - initial_prompt = "", - directories = { "." }, - } - end - 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 - local config = result - if type(config) == "table" then - return { - initial_prompt = config.initial_prompt or "", - directories = config.directories or { "." }, - } + local config = { + initial_prompt = "", + directories = { "." }, + default_prompt_blocks = {} + } + + 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 end end + else + -- Default fallback configuration + config.initial_prompt = "You are a coding assistant who receives a project’s 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 project’s 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 \n - path: \"relative/path/to/file2.ext\"\n content: |\n \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 - return { - initial_prompt = "You are a coding assistant who receives a project’s 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 project’s 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 \n - path: \"relative/path/to/file2.ext\"\n content: |\n \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.", - directories = { "." }, - } + + -- 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 return M