improve: support to customize the avanterules directories for project/global (#2392)

This commit is contained in:
guanghechen
2025-07-02 12:17:13 +08:00
committed by GitHub
parent d4f3224bf6
commit 30604304ba
4 changed files with 63 additions and 12 deletions

View File

@@ -1137,6 +1137,23 @@ The rules for root hierarchy:
- root pattern of filename of the current buffer
- root pattern of cwd
You can also configure custom directories for your `avanterules` files using the `rules` option:
```lua
require('avante').setup({
rules = {
project_dir = '.avante/rules', -- relative to project root, can also be an absolute path
global_dir = '~/.config/avante/rules', -- absolute path
},
})
```
The loading priority is as follows:
1. `rules.project_dir`
2. `rules.global_dir`
3. Project root
<details>
<summary>Example folder structure for custom prompt</summary>

View File

@@ -960,6 +960,23 @@ vim.keymap.set("n", "<leader>am", function() vim.api.nvim_exec_autocmds("User",
- 当前缓冲区的文件名的根模式
- cwd 的根模式
您还可以使用 `rules` 选项为您的 `avanterules` 文件配置自定义目录:
```lua
require('avante').setup({
rules = {
project_dir = '.avante/rules', -- 相对于项目根目录,也可以是绝对路径
global_dir = '~/.config/avante/rules', -- 绝对路径
},
})
```
加载优先级如下:
1. `rules.project_dir`
2. `rules.global_dir`
3. 项目根目录
<details>
<summary>自定义提示的示例文件夹结构</summary>

View File

@@ -40,6 +40,10 @@ M._defaults = {
tokenizer = "tiktoken",
---@type string | (fun(): string) | nil
system_prompt = nil,
rules = {
project_dir = nil, ---@type string | nil (could be relative dirpath)
global_dir = nil, ---@type string | nil (absolute dirpath)
},
rag_service = { -- RAG service configuration
enabled = false, -- Enables the RAG service
host_mount = os.getenv("HOME"), -- Host mount path for the RAG service (Docker will mount this path)

View File

@@ -222,22 +222,35 @@ function Prompt.get_templates_dir(project_root)
local cache_prompt_dir = P.cache_path:joinpath(directory)
if not cache_prompt_dir:exists() then cache_prompt_dir:mkdir({ parents = true }) end
local scanner = Scan.scan_dir(directory:absolute(), { depth = 1, add_dirs = true })
for _, entry in ipairs(scanner) do
local file = Path:new(entry)
if file:is_file() then
local pieces = vim.split(entry, "/")
local piece = pieces[#pieces]
local mode = piece:match("([^.]+)%.avanterules$")
if not mode or not Prompt.custom_modes[mode] then goto continue end
if Prompt.custom_prompts_contents[mode] == nil then
Utils.info(string.format("Using %s as %s system prompt", entry, mode))
Prompt.custom_prompts_contents[mode] = file:read()
local function find_rules(dir)
if not dir then return end
if vim.fn.isdirectory(dir) ~= 1 then return end
local scanner = Scan.scan_dir(dir, { depth = 1, add_dirs = true })
for _, entry in ipairs(scanner) do
local file = Path:new(entry)
if file:is_file() then
local pieces = vim.split(entry, "/")
local piece = pieces[#pieces]
local mode = piece:match("([^.]+)%.avanterules$")
if not mode or not Prompt.custom_modes[mode] then goto continue end
if Prompt.custom_prompts_contents[mode] == nil then
Utils.info(string.format("Using %s as %s system prompt", entry, mode))
Prompt.custom_prompts_contents[mode] = file:read()
end
end
::continue::
end
::continue::
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
find_rules(tostring(project_rules_path))
end
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 })