feat: enable override prompt templates directory (#2387)
This commit is contained in:
28
README.md
28
README.md
@@ -1116,7 +1116,9 @@ By default, `avante.nvim` provides three different modes to interact with: `plan
|
||||
- `suggesting`: Used with `require("avante").get_suggestion():suggest()` on Tab flow.
|
||||
- `cursor-planning`: Used with `require("avante").toggle()` on Tab flow, but only when cursor planning mode is enabled.
|
||||
|
||||
Users can customize the system prompts via `Config.system_prompt`. We recommend calling this in a custom Autocmds depending on your need:
|
||||
Users can customize the system prompts via `Config.system_prompt` or `Config.override_prompt_dir`.
|
||||
|
||||
`Config.system_prompt` allows you to set a global system prompt. We recommend calling this in a custom Autocmds depending on your need:
|
||||
|
||||
```lua
|
||||
vim.api.nvim_create_autocmd("User", {
|
||||
@@ -1127,7 +1129,29 @@ vim.api.nvim_create_autocmd("User", {
|
||||
vim.keymap.set("n", "<leader>am", function() vim.api.nvim_exec_autocmds("User", { pattern = "ToggleMyPrompt" }) end, { desc = "avante: toggle my prompt" })
|
||||
```
|
||||
|
||||
If one wish to custom prompts for each mode, `avante.nvim` will check for project root based on the given buffer whether it contains
|
||||
`Config.override_prompt_dir` allows you to specify a directory containing your own custom prompt templates, which will override the built-in templates. This is useful if you want to maintain a set of custom prompts outside of your Neovim configuration. It can be a string representing the directory path, or a function that returns a string representing the directory path.
|
||||
|
||||
```lua
|
||||
-- Example: Override with prompts from a specific directory
|
||||
require("avante").setup({
|
||||
override_prompt_dir = vim.fn.expand("~/.config/nvim/avante_prompts"),
|
||||
})
|
||||
|
||||
-- Example: Override with prompts from a function (dynamic directory)
|
||||
require("avante").setup({
|
||||
override_prompt_dir = function()
|
||||
-- Your logic to determine the prompt directory
|
||||
return vim.fn.expand("~/.config/nvim/my_dynamic_prompts")
|
||||
end,
|
||||
})
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
>
|
||||
> If you customize `base.avanterules`, please ensure that `{% block custom_prompt %}{% endblock %}` and `{% block extra_prompt %}{% endblock %}` exist, otherwise the entire plugin may become unusable.
|
||||
> If you are unsure about the specific reasons or what you are doing, please do not override the built-in prompts. The built-in prompts work very well.
|
||||
|
||||
If you wish to custom prompts for each mode, `avante.nvim` will check for project root based on the given buffer whether it contains
|
||||
the following patterns: `*.{mode}.avanterules`.
|
||||
|
||||
The rules for root hierarchy:
|
||||
|
||||
26
README_zh.md
26
README_zh.md
@@ -940,7 +940,9 @@ Avante 利用 [Claude 文本编辑器工具](https://docs.anthropic.com/en/docs/
|
||||
- `suggesting`:与 Tab 流上的 `require("avante").get_suggestion():suggest()` 一起使用。
|
||||
- `cursor-planning`:与 Tab 流上的 `require("avante").toggle()` 一起使用,但仅在启用 cursor 规划模式时。
|
||||
|
||||
用户可以通过 `Config.system_prompt` 自定义系统提示。我们建议根据您的需要在自定义 Autocmds 中调用此方法:
|
||||
用户可以通过 `Config.system_prompt` 或 `Config.override_prompt_dir` 自定义系统提示。
|
||||
|
||||
`Config.system_prompt` 允许您设置全局系统提示。我们建议根据您的需要在自定义 Autocmds 中调用此方法:
|
||||
|
||||
```lua
|
||||
vim.api.nvim_create_autocmd("User", {
|
||||
@@ -951,6 +953,28 @@ vim.api.nvim_create_autocmd("User", {
|
||||
vim.keymap.set("n", "<leader>am", function() vim.api.nvim_exec_autocmds("User", { pattern = "ToggleMyPrompt" }) end, { desc = "avante: toggle my prompt" })
|
||||
```
|
||||
|
||||
`Config.override_prompt_dir` 允许您指定一个目录,其中包含您自己的自定义提示模板,这将覆盖内置模板。如果您想在 Neovim 配置之外维护一组自定义提示,这将非常有用。它可以是一个表示目录路径的字符串,也可以是一个返回表示目录路径的字符串的函数。
|
||||
|
||||
```lua
|
||||
-- 示例:使用特定目录中的提示进行覆盖
|
||||
require("avante").setup({
|
||||
override_prompt_dir = vim.fn.expand("~/.config/nvim/avante_prompts"),
|
||||
})
|
||||
|
||||
-- 示例:使用函数(动态目录)中的提示进行覆盖
|
||||
require("avante").setup({
|
||||
override_prompt_dir = function()
|
||||
-- 确定提示目录的逻辑
|
||||
return vim.fn.expand("~/.config/nvim/my_dynamic_prompts")
|
||||
end,
|
||||
})
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
>
|
||||
> 如果您自定 `base.avanterules`,请一定要确保 `{% block custom_prompt %}{% endblock %}` 和 `{% block extra_prompt %}{% endblock %}` 存在,否则可能会导致整个插件无法使用。
|
||||
> 如果您不清楚具体原因或者您不知道自己在干什么,请不要覆盖内置 prompt。内置 prompt 工作得非常好。
|
||||
|
||||
如果希望为每种模式自定义提示,`avante.nvim` 将根据给定缓冲区的项目根目录检查是否包含以下模式:`*.{mode}.avanterules`。
|
||||
|
||||
根目录层次结构的规则:
|
||||
|
||||
@@ -38,8 +38,10 @@ M._defaults = {
|
||||
-- For most providers that we support we will determine this automatically.
|
||||
-- If you wish to use a given implementation, then you can override it here.
|
||||
tokenizer = "tiktoken",
|
||||
---@type string | (fun(): string) | nil
|
||||
---@type string | fun(): string | nil
|
||||
system_prompt = nil,
|
||||
---@type string | fun(): string | nil
|
||||
override_prompt_dir = nil,
|
||||
rules = {
|
||||
project_dir = nil, ---@type string | nil (could be relative dirpath)
|
||||
global_dir = nil, ---@type string | nil (absolute dirpath)
|
||||
|
||||
@@ -7,6 +7,7 @@ local Config = require("avante.config")
|
||||
---@class avante.Path
|
||||
---@field history_path Path
|
||||
---@field cache_path Path
|
||||
---@field data_path Path
|
||||
local P = {}
|
||||
|
||||
---@param bufnr integer | nil
|
||||
@@ -243,6 +244,45 @@ function Prompt.get_templates_dir(project_root)
|
||||
end
|
||||
end
|
||||
|
||||
-- Check for override prompt
|
||||
local override_prompt_dir = Config.override_prompt_dir
|
||||
if override_prompt_dir then
|
||||
-- Handle the case where override_prompt_dir is a function
|
||||
if type(override_prompt_dir) == "function" then
|
||||
local ok, result = pcall(override_prompt_dir)
|
||||
if ok and result then override_prompt_dir = result end
|
||||
end
|
||||
|
||||
if override_prompt_dir then
|
||||
local user_template_path = Path:new(override_prompt_dir)
|
||||
if user_template_path:exists() then
|
||||
local user_scanner = Scan.scan_dir(user_template_path:absolute(), { depth = 1, add_dirs = false })
|
||||
for _, entry in ipairs(user_scanner) do
|
||||
local file = Path:new(entry)
|
||||
if file:is_file() then
|
||||
local pieces = vim.split(entry, "/")
|
||||
local piece = pieces[#pieces]
|
||||
|
||||
if piece == "base.avanterules" then
|
||||
local content = file:read()
|
||||
|
||||
if not content:match("{%% block extra_prompt %%}[%s,\\n]*{%% endblock %%}") then
|
||||
file:write("{% block extra_prompt %}\n", "a")
|
||||
file:write("{% endblock %}\n", "a")
|
||||
end
|
||||
|
||||
if not content:match("{%% block custom_prompt %%}[%s,\\n]*{%% endblock %%}") then
|
||||
file:write("{% block custom_prompt %}\n", "a")
|
||||
file:write("{% endblock %}", "a")
|
||||
end
|
||||
end
|
||||
file:copy({ destination = cache_prompt_dir:joinpath(piece) })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if Config.rules.project_dir then
|
||||
local project_rules_path = Path:new(Config.rules.project_dir)
|
||||
if not project_rules_path:is_absolute() then project_rules_path = directory:joinpath(project_rules_path) end
|
||||
@@ -251,8 +291,12 @@ function Prompt.get_templates_dir(project_root)
|
||||
find_rules(Config.rules.global_dir)
|
||||
find_rules(directory:absolute())
|
||||
|
||||
Path:new(debug.getinfo(1).source:match("@?(.*/)"):gsub("/lua/avante/path.lua$", "") .. "templates")
|
||||
:copy({ destination = cache_prompt_dir, recursive = true })
|
||||
-- Copy built-in templates to cache directory (only if not overridden by user templates)
|
||||
Path:new(debug.getinfo(1).source:match("@?(.*/)"):gsub("/lua/avante/path.lua$", "") .. "templates"):copy({
|
||||
destination = cache_prompt_dir,
|
||||
recursive = true,
|
||||
override = false,
|
||||
})
|
||||
|
||||
vim.iter(Prompt.custom_prompts_contents):filter(function(_, v) return v ~= nil end):each(function(k, v)
|
||||
local orig_file = cache_prompt_dir:joinpath(Prompt.get_builtin_prompts_filepath(k))
|
||||
|
||||
Reference in New Issue
Block a user