I made a plugin to copy multiple files/directories at once. Helpful for generating LLM input

I often copy code to input into an LLM chat, but I have some issues with this, firstly, I often want to copy code from multiple files, secondly I want to show the relative path from my project root to each files, and third, I want to hide code that is not significant to my current issue/feature.

Enter nvim-copy, a plugin I wrote to copy code from one or more files to clipboard, while preserving the folded code from opened buffers.

This plugin exposes commands to copy code from different sources:
Opened buffers, current buffer, git-modified files, files within a given directory, quickfix list files, or harpoon marked files and directories.

This proves very helpful to quickly copy the exact needed code to share with an LLM across files while giving the LLM an understanding of where the code is through relative file paths.

Example code copied to clipboard. (example from code of the plugin itself)

File: lua/nvim_copy/clipboard.lua
local utils = require("nvim_copy.utils")
local buffer_utils = require("nvim_copy.buffer_utils")

local M = {}

function M.build_content_buffer(files, opts)
  opts = opts or {}
  local result = {}
  local seen_files = {}
  for _, file_path in ipairs(files) do
    if file_path and not seen_files[file_path] then
      seen_files[file_path] = true
      local relative_path = utils.get_relative_path(file_path)
      table.insert(result, "File: " .. relative_path .. "\n")
      if opts.preserve_folds == false then
        table.insert(result, buffer_utils.read_visible_file_content_without_folds(file_path) .. "\n\n")
      else
        table.insert(result, buffer_utils.read_visible_file_content_with_folds(file_path) .. "\n\n")
      end
    end
  end
  return result
end

function M.copy_to_clipboard_from_files(files, source, opts) ... (15 folded lines)

return M

File: lua/nvim_copy/utils.lua
local M = {}

-- Utility function to compute relative paths
function M.get_relative_path(file_path)
  local project_root = vim.loop.cwd()
  local relative_path = vim.fn.fnamemodify(file_path, ":.")
  return vim.fn.substitute(relative_path, "^" .. vim.fn.escape(project_root, "/"), "", "")
end

-- Utility function to read file content
function M.read_file_content(file_path) ... (12 folded lines)

return M