Problem
When using {remote_url} in format strings, the plugin makes 4 separate subprocess calls on every copy operation:
git rev-parse --is-inside-work-tree - check if git repo
git remote -v - get remote URL
git rev-parse HEAD - get current commit SHA
git ls-files --full-name <file> - get repo-relative path
Subprocess spawning is expensive (~10-50ms each depending on system), resulting in 40-200ms of overhead per copy when using remote URLs.
Location: lua/copy_with_context/git.lua - get_git_info() function
Proposed Solution
Implement a caching layer with appropriate invalidation triggers.
What Can Be Cached
| Data |
Cacheable? |
Invalidation Trigger |
is_git_repo |
Yes |
CWD change |
remote_url |
Yes |
Almost never changes |
parsed_remote (provider/owner/repo) |
Yes |
Same as above |
current_commit |
Tricky |
Git operations (commit, pull, checkout) |
file_git_path |
Per-buffer |
Buffer changes / new file |
Implementation Approach
1. Repository-level cache (clear on DirChanged)
local repo_cache = {
is_git_repo = nil, -- bool
remote_url = nil, -- string
parsed_remote = nil, -- {provider, owner, repo}
commit_sha = nil, -- string (with staleness caveat)
}
2. Buffer-level cache (clear on BufEnter/BufFilePost)
local buffer_cache = {} -- bufnr -> {git_path = "..."}
3. Autocmds for cache invalidation
vim.api.nvim_create_autocmd("DirChanged", {
callback = function()
-- Clear repo cache
end
})
vim.api.nvim_create_autocmd("BufEnter", {
callback = function()
-- Clear/populate buffer cache entry lazily
end
})
Commit SHA Staleness
The commit SHA is tricky because it changes on git operations. Two options:
Option A (Simple): Cache at startup/DirChanged, accept staleness
- Pro: Fast, simple
- Con: URL might point to wrong commit after committing
Option B (Smarter): Watch .git/HEAD with vim.loop.fs_event or invalidate on ShellCmdPost for git commands
Recommendation: Start with Option A and add a manual refresh command (:CopyWithContextRefresh) for users who need accurate commit refs.
Acceptance Criteria
Notes
- Non-git operations (
vim.fn.expand("%"), line extraction) are already fast and don't need caching
- This optimization primarily benefits users who use
{remote_url} in their formats
- Consider whether the complexity is worth it based on actual user feedback
Problem
When using
{remote_url}in format strings, the plugin makes 4 separate subprocess calls on every copy operation:git rev-parse --is-inside-work-tree- check if git repogit remote -v- get remote URLgit rev-parse HEAD- get current commit SHAgit ls-files --full-name <file>- get repo-relative pathSubprocess spawning is expensive (~10-50ms each depending on system), resulting in 40-200ms of overhead per copy when using remote URLs.
Location:
lua/copy_with_context/git.lua-get_git_info()functionProposed Solution
Implement a caching layer with appropriate invalidation triggers.
What Can Be Cached
is_git_reporemote_urlparsed_remote(provider/owner/repo)current_commitfile_git_pathImplementation Approach
1. Repository-level cache (clear on
DirChanged)2. Buffer-level cache (clear on
BufEnter/BufFilePost)3. Autocmds for cache invalidation
Commit SHA Staleness
The commit SHA is tricky because it changes on git operations. Two options:
Option A (Simple): Cache at startup/DirChanged, accept staleness
Option B (Smarter): Watch
.git/HEADwithvim.loop.fs_eventor invalidate onShellCmdPostfor git commandsRecommendation: Start with Option A and add a manual refresh command (
:CopyWithContextRefresh) for users who need accurate commit refs.Acceptance Criteria
DirChangedautocmdNotes
vim.fn.expand("%"), line extraction) are already fast and don't need caching{remote_url}in their formats