Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/codecompanion.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1966,6 +1966,7 @@ ADDING PROMPTS ~
There are two ways to add prompts to the prompt library. You can either define
them directly in your configuration file as Lua tables, or you can store them
as markdown files in your filesystem and reference them in your configuration.
The files can be nested and symlinked.



Expand Down
2 changes: 1 addition & 1 deletion doc/configuration/prompt-library.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ CodeCompanion enables you to leverage prompt templates to quickly interact with
> [!NOTE]
> See the [Creating Prompts](#creating-prompts) section to learn how to create your own.

There are two ways to add prompts to the prompt library. You can either define them directly in your configuration file as Lua tables, or you can store them as markdown files in your filesystem and reference them in your configuration.
There are two ways to add prompts to the prompt library. You can either define them directly in your configuration file as Lua tables, or you can store them as markdown files in your filesystem and reference them in your configuration. The files can be nested and symlinked.

::: code-group

Expand Down
24 changes: 6 additions & 18 deletions lua/codecompanion/actions/markdown.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,14 @@ function M.load_from_dir(dir, context)
end

-- Scan directory for .md files
local handle = vim.uv.fs_scandir(dir)
if not handle then
return prompts
end

while true do
local name, type = vim.uv.fs_scandir_next(handle)
if not name then
break
end
local md_files = file_utils.scan_directory(dir, { patterns = "*.md", max_depth = 5 })

-- Only process .md files (including symlinks)
if (type == "file" or type == "link") and name:match("%.md$") then
local path = vim.fs.joinpath(dir, name)
local ok, prompt = pcall(M.parse_file, path, context)
for _, path in ipairs(md_files) do
local ok, prompt = pcall(M.parse_file, path, context)

if ok and prompt then
prompt.name = prompt.name or vim.fn.fnamemodify(path, ":t:r")
table.insert(prompts, prompt)
end
if ok and prompt then
prompt.name = prompt.name or vim.fn.fnamemodify(path, ":t:r")
table.insert(prompts, prompt)
end
end

Expand Down
15 changes: 10 additions & 5 deletions lua/codecompanion/utils/files.lua
Original file line number Diff line number Diff line change
Expand Up @@ -392,13 +392,18 @@ end

---Recursively scan a directory and return all file paths
---@param dir_path string The directory path to scan
---@param opts? { patterns?: string|string[] } Optional patterns to filter files
---@param opts? { patterns?: string|string[], max_depth?: number } Optional patterns to filter files and max recursion depth
---@return string[] files List of absolute file paths
function M.scan_directory(dir_path, opts)
opts = opts or {}
local files = {}
local max_depth = opts.max_depth

local function scan_recursively(path, depth)
if max_depth and depth > max_depth then
return
end

local function scan_recursively(path)
local handle = uv.fs_scandir(path)
if not handle then
return
Expand All @@ -413,8 +418,8 @@ function M.scan_directory(dir_path, opts)
local full_path = vim.fs.joinpath(path, name)

if type == "directory" then
scan_recursively(full_path)
elseif type == "file" then
scan_recursively(full_path, depth + 1)
elseif type == "file" or type == "link" then
if opts.patterns then
if M.match_patterns(name, opts.patterns) then
table.insert(files, full_path)
Expand All @@ -426,7 +431,7 @@ function M.scan_directory(dir_path, opts)
end
end

scan_recursively(dir_path)
scan_recursively(dir_path, 0)
return files
end

Expand Down