Skip to content

Repository files navigation

scratch-comments.nvim

Commenting on this README and exporting the comment as Markdown

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.

why

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.

install

With lazy.nvim:

{ "eleith/scratch-comments.nvim" }

With vim.pack:

vim.pack.add({ { src = "https://git.eleith.com/eleith/scratch-comments.nvim" } })

use

comment on the current line:

:Comment

comment 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
:'<,'>Comment

a 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:

:CommentShow

browse every comment, then copy them all:

:CommentList
:CommentExport         " markdown, to the clipboard
:CommentExport json    " json, to the clipboard

add ! 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

commands

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

mappings

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" })

browsing

: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 typo

any quickfix viewer works:

:copen                       " built in, no plugins
:Trouble qflist toggle       " trouble.nvim
:lua Snacks.picker.qflist()  " snacks.nvim
:Telescope quickfix          " telescope.nvim

retention

comments 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.

colors

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" })

lua API

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")

requirements

  • Neovim 0.12 or newer.
  • No plugin dependencies.
  • A clipboard provider. in tmux you may need vim.g.clipboard = "osc52".

development

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/

credit

forked from annotator.nvim by chpeters.

license

MIT. See LICENSE.

About

leave comments across multiple buffers in a nvim session, then handoff those comments to an LLM, a scratch buffer or a teammate

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages