comment on any line(s) in any file, then copy them all out as Markdown (or JSON) to paste into an LLM or hand to a person.
when reading a file in neovim, sometimes i want to leave comments as i go without interruption (no second app, no extra buffer). this plugin keeps track of each comment associated to the right location.
afterwards, i can export all the comments to my clipboard (or a file) and handoff to an LLM or teammate.
i've found it useful in reviewing plans, code diffs and more. no extra fluff, no coordination with a custom agent, format, or process.
just text.
With lazy.nvim:
{ "eleith/scratch-comments.nvim" }With vim.pack:
vim.pack.add({ { src = "https://git.eleith.com/eleith/scratch-comments.nvim" } })comment on the current line:
:Commentcomment on a range, or select text and type :Comment. select whole lines to
comment on them, or just a word or phrase to comment on only that:
:12,16Comment
:'<,'>Commenta window opens in the middle of the screen, with the lines you're commenting on
at the top and your comment below. a new comment opens in insert mode, and the
title shows the mode you're in. write as many lines as you like, then :wq to
save. :q or <Esc> closes it if you haven't changed anything, and :q!
throws your changes away. <C-w>w moves between the two parts, or scroll them with the
mouse.
commented lines get a mark in the sign column: │ for one line, and ╭ │ ╰
down a range. to read the comment on the cursor line:
:CommentShowbrowse every comment, then copy them all:
:CommentList
:CommentExport " markdown, to the clipboard
:CommentExport json " json, to the clipboardadd ! to open the export in a scratch buffer instead. from there you can save
it, pipe it to a command, or edit it:
:CommentExport! " then :w review.md, :w !some-cmd, :%!jq ., ...
:CommentExport! json| Command | Does |
|---|---|
:Comment |
Comment on the current line or command range |
:CommentShow |
Show the comment at the cursor, with the lines it's on. Edit it there and :w to save |
:CommentNext |
Go to the next comment in the file |
:CommentPrev |
Go to the previous comment in the file |
:CommentDelete |
Delete the comment at the cursor, or pick an orphaned one |
:CommentList [filter] |
Put comments in the quickfix list and open it, fuzzy matching filter |
:CommentExport[!] [format] |
Copy all comments to the clipboard as markdown (default) or json. ! opens them in a scratch buffer |
:CommentToggle [on|off] |
Show or hide the comment signs |
:CommentClear |
Delete every comment |
add your own, for example:
vim.keymap.set("n", "<leader>ca", "<Cmd>Comment<CR>", { desc = "Comment on line" })
vim.keymap.set("x", "<leader>ca", ":Comment<CR>", { desc = "Comment on selection" })
vim.keymap.set("n", "<leader>cs", "<Cmd>CommentShow<CR>", { desc = "Show comments" })
vim.keymap.set("n", "<leader>cn", "<Cmd>CommentNext<CR>", { desc = "Next comment" })
vim.keymap.set("n", "<leader>cp", "<Cmd>CommentPrev<CR>", { desc = "Previous comment" })
vim.keymap.set("n", "<leader>cl", "<Cmd>CommentList<CR>", { desc = "List comments" })
vim.keymap.set("n", "<leader>cx", "<Cmd>CommentExport<CR>", { desc = "Copy comments" }):CommentNext and :CommentPrev move between comments in the current file,
wrapping at the ends. with a comment open, they show the next or previous
comment in that window instead. save or discard your changes first.
:CommentList puts all your comments in the quickfix list, so ]q and [q
move between them across files. while the list is open, the comment under the
cursor is shown in a card above it. give it an argument to list only the
comments that fuzzy match it, in their text, snippet or path:
:CommentList typoany quickfix viewer works:
:copen " built in, no plugins
:Trouble qflist toggle " trouble.nvim
:lua Snacks.picker.qflist() " snacks.nvim
:Telescope quickfix " telescope.nvimcomments go away when you close the buffer (:bd, :bw) or run
:CommentClear. to keep them, export them to a file.
the signs share the sign column with plugins like gitsigns, and can cover their
signs. :CommentToggle hides ours when you need to see theirs.
if you delete all the lines a comment is on, the comment becomes an orphan.
orphans are listed last in :CommentList and in an "Orphaned" section of the
export, and undo restores them. to delete one, run :CommentDelete on a line
with no comment.
ScratchCommentSign colors the signs (linked to Todo by default).
ScratchCommentBackdrop dims the editor behind comments and :CommentList
(black at 60% blend by default).
set them in your colorscheme's highlight callback to follow light and dark
modes. for example, inside Modus's on_highlights:
hl.ScratchCommentSign = { fg = c.fg_main, bg = c.bg_yellow_intense, bold = true }
hl.ScratchCommentBackdrop = { bg = c.bg_dim }for fixed colors, use vim.api.nvim_set_hl. to turn off the dim:
vim.api.nvim_set_hl(0, "ScratchCommentBackdrop", { bg = "NONE" })local scratch = require("scratch_comments")
scratch.add(start_line, end_line) -- default: the cursor line
scratch.show()
scratch.next()
scratch.prev()
scratch.delete()
scratch.list()
scratch.render(format) -- "markdown" (default) or "json"
scratch.export(format, in_buffer) -- copy, or open in a scratch buffer
scratch.toggle(on) -- true, false, or nil to toggle
scratch.clear()scratch.render() returns the export as a string. to write it to a file:
vim.fn.writefile(vim.split(scratch.render(), "\n"), "review.md")- Neovim 0.12 or newer.
- No plugin dependencies.
- A clipboard provider. in tmux you may need
vim.g.clipboard = "osc52".
plugin/scratch-comments.lua the commands
lua/scratch_comments/
init.lua the lua API
actions.lua comment, show, delete, toggle, clear
navigate.lua next and prev
comments.lua changes comments and keeps the signs in sync
location.lua "line 3", "lines 3–5", "line 3, col 5–12"
paths.lua git root and relative paths
model/ the comments and where they are
ui/ the comment window, signs, quickfix, notifications
export/ markdown, json and the clipboard
tests/
unit/ tests for single modules
features/ tests that run the commands
mise install gets the pinned tools. then:
make check # lint, format check and tests, like CI
make test # tests only. the first run clones mini.test into deps/forked from annotator.nvim by chpeters.
MIT. See LICENSE.
