Leave line comments on any file, then export them as a prompt for a coding agent. Not tied to a diff — it works in whatever buffer you are in.
Comments follow the code when it moves, persist per project, and survive restarts.
Built for my own use. There may well be plugins that do this better; I did not look very hard. No support, no roadmap, no promises about the API.
lazy.nvim
{
"DaniilSinitsyn/annotate.nvim",
opts = {},
}vim-plug
Plug 'DaniilSinitsyn/annotate.nvim'require("annotate").setup({})Neovim 0.10+, git, and a clipboard provider (xclip or wl-clipboard on
Linux; macOS has one built in). setup() must run — nothing binds until it
does.
Forgot them?
<leader>c?opens a help window showing every key as you actually press it.qcloses it.
| key | |
|---|---|
<leader>cc |
comment on this line, or the visual selection |
<leader>cn |
note |
<leader>cs |
suggestion |
<leader>ci |
issue |
<leader>cp |
praise |
<leader>cf |
comment on the file, not a line |
<leader>ce |
edit the comment under the cursor |
<leader>cd |
delete it |
<leader>cc asks which type in the popup; the four shortcuts skip that.
| key | |
|---|---|
<C-s> |
save — works straight from insert mode |
<Tab> |
change type while writing |
q or <Esc> |
discard |
| key | |
|---|---|
]n [n |
next / previous comment |
]h [h |
next / previous git change |
]f [f |
next / previous changed file |
]h and ]f work whether or not the diff overlay is showing.
| key | |
|---|---|
<leader>cg |
inline diff on/off — added lines green, removed lines above in red |
One window. Still the real file, so you comment on it exactly as anywhere else.
To diff against something other than HEAD:
:Annotate diff v1.2.0
:Annotate diff main
:Annotate diff HEAD~3
| key | |
|---|---|
<leader>cC |
export every comment to the clipboard |
<leader>cl |
list them in the quickfix window |
<leader>cx |
delete them all |
<leader>cr makes the buffer readonly, which frees the bare keys:
i add e edit d delete F file c list C export R off
I reviewed your code and have the following comments. Please address them.
Comment types: ISSUE (problems to fix), SUGGESTION (improvements), NOTE (observations), PRAISE (positive feedback)
1. **[ISSUE]** `src/cache.py:16` - evicting the whole cache on overflow
2. **[NOTE]** `src/parse.py:12-14` - no bounds check here
Paste that at a coding agent.
:Annotate export | list | clear | review | help
:Annotate diff [rev] rev defaults to HEAD
Pass a different key, or false to leave it unbound:
require("annotate").setup({
keymaps = {
add_comment = "<leader>C",
add_praise = false,
},
})Anything you do not mention keeps its default.
| group | links to |
|---|---|
AnnotateNote |
Comment |
AnnotateSuggestion |
DiagnosticHint |
AnnotateIssue |
DiagnosticWarn |
AnnotatePraise |
DiagnosticOk |
vim.api.nvim_set_hl(0, "AnnotateIssue", { fg = "#ff5555", bold = true })The inline diff uses your existing DiffAdd and DiffDelete.
<leader>cx deletes every comment in the project, including the file on disk.
No undo.
State is one JSON file per project:
:echo stdpath("state") . "/annotate"
Delete a file to reset one project, the directory to reset everything.
If a buffer is stuck readonly, you left review mode on — <leader>cr.
Internals, the Lua API and design notes are in AGENTS.md.
MIT.