Stage code references — each with its own prompt — into a review, then copy the whole thing to your clipboard formatted for pasting into an LLM.
Instead of copying a snippet, switching to your chat, typing "in foo.lua lines
40-52, …", and repeating for every place you want to touch, you build up a
review: select some code, jot the instruction for it, repeat across files, and
copy it all at once as one structured message.
Select code → type a prompt → repeat → open the review → copy the whole bundle.
Selecting two regions and adding a prompt to each, then copying, yields (XML style):
<item>
<file path="src/auth.lua" lines="40-52" language="lua">
local function verify(token)
...
end
</file>
<prompt>
This doesn't handle expired tokens — add an expiry check.
</prompt>
</item>
<item>
<file path="src/routes.lua" lines="8" language="lua">
router:get("/me", require("auth").verify)
</file>
<prompt>
Make sure this route returns 401 when verify fails.
</prompt>
</item>Or, with output_style = "markdown":
src/auth.lua:40-52
```lua
local function verify(token)
...
end
```
This doesn't handle expired tokens — add an expiry check.{
"r10a/prompt-reference.nvim",
-- opt-in default keymaps (see Configuration); omit to bind your own
opts = { keymaps = true },
}use({
"r10a/prompt-reference.nvim",
config = function()
require("prompt-reference").setup({ keymaps = true })
end,
})Requires Neovim 0.10+ (uses vim.fn.getregion).
- Select code in visual mode and add it — a prompt window opens; type
the instruction for that selection and press
<CR>. - Repeat across as many files/regions as you like. A small review panel appears at the bottom-right showing what's staged.
- Open the review, then press
<CR>to copy the whole bundle to your clipboard and clear it. Paste into your LLM.
Always available, no setup() required:
| Command | Description |
|---|---|
:PromptReferenceAdd |
Add the visual selection (prompts for text) |
:PromptReferenceReview |
Open the review window |
:PromptReferenceCopy |
Copy the review to the clipboard and clear it |
| Key | Action |
|---|---|
<CR> |
Copy the whole review to the clipboard & clear |
dd |
Delete the item under the cursor |
r |
Re-enter the prompt for the item (shows its code as context) |
? |
Show this help |
<Tab><Tab> / <Esc> |
Close the review |
Defaults:
require("prompt-reference").setup({
sink = "clipboard", -- where a finished review goes: "clipboard" or "tmux"
register = "+", -- register to copy into (default: system clipboard)
use_git_root = true, -- paths relative to the git root; else cwd-relative
include_code = true, -- include the selected code, not just the reference
output_style = "markdown", -- "markdown" or "xml" (xml parses more reliably for Claude)
-- Only used when sink = "tmux".
tmux = {
command = "claude", -- foreground command of the pane to auto-detect
submit = true, -- press Enter after pasting so the review is sent
select = false, -- switch focus to that pane after sending
},
-- Opt-in keymaps. `keymaps = true` uses these defaults; a table merges over
-- them; `false` (the default) binds nothing so you can map the functions yourself.
keymaps = {
add = "<CR>", -- (visual) add selection to the review
review = "<Tab><Tab>", -- (normal) open the review
copy = false, -- (normal) copy the review without opening it
},
})With sink = "tmux", finishing a review (the review window's <CR>, or
copy_all) pastes the whole bundle into the tmux pane running Claude Code and
presses Enter, instead of copying to a register. Run Neovim and claude in the
same tmux session (any windows/panes); the target pane is found automatically by
matching tmux.command (default "claude") against each pane's foreground
command, so no window numbers are hard-coded.
The paste goes through tmux load-buffer (payload via stdin, never
shell-quoted) and paste-buffer -p (bracketed paste), so multi-line reviews and
any backticks/quotes/XML in your prompts arrive intact as one block. If Neovim
isn't inside tmux, or no matching pane is found, the review falls back to the
clipboard with a warning so it's never lost.
This is a one-way hand-off: it types the review into your existing interactive session; it does not read Claude's response back.
To bind your own keys instead of the defaults:
local pr = require("prompt-reference")
vim.keymap.set("x", "ga", pr.add_selection, { desc = "Add to review" })
vim.keymap.set("n", "gr", pr.review, { desc = "Open review" })
vim.keymap.set("n", "gc", pr.copy_all, { desc = "Copy review" })require("prompt-reference").add_selection()— stage the current visual selectionrequire("prompt-reference").review()— open the review windowrequire("prompt-reference").copy_all()— copy the review and clear it
The demo GIF is generated with VHS
from demo/demo.tape, recorded against the two sample files (demo/auth.lua
and demo/routes.lua) to show the multi-file review path:
cd demo
vhs demo.tape # writes demo/demo.gifThe tape sets FontFamily "JetBrainsMono Nerd Font" so file-type icons render
(install any Nerd Font and adjust the name to match if you don't have it).
On macOS, if VHS can't reach its headless browser, point it at a real Chrome:
ROD_BROWSER_BIN="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" vhs demo.tapeMIT
