Repository navigation
Releases: odiumuniverse/claudecode.nvim
Release list
claudecode.nvim 1.4.0
claudecode-nvim-demo.mp4
Fixes from a UX review: changes from outside Claude stay out of Claude's hunks, the changed words show, the hint stays in sight, and a part of a hunk can be kept or reverted.
Upgrading
- With LazyVim set to fzf-lua (
vim.g.lazyvim_picker = "fzf") the lists of files and notes open in fzf-lua, as LazyVim's other lists do.review.picker = "snacks"keeps snacks.picker. - The list no longer reverts a file whose buffer holds unsaved edits, also when the file is under review: it used to write those edits with the revert. Save or drop them first.
- In Visual mode in a buffer under review
<leader>akkeeps and<leader>axreverts the selected lines. In Normal mode<leader>aklists the files as before. - Messages begin with "claudecode:"; some said "claudecode review:".
Added
- A part of a hunk. Select lines of a hunk and press
<leader>akto keep what Claude changed there, or<leader>axto revert it; the rest of the hunk keeps waiting. As in gitsigns, the selected added lines go with the deleted lines at the same places. A rename and a new method that Claude wrote one after the other, one hunk, can now be decided one by one. The options arereview.keymaps.keep_rangeandreview.keymaps.revert_range; both work in a proposal too. review.hint_overflow. A hint that does not fit at the end of the line goes on a line of its own above the hunk ("above", the default) or in front ofcontroller.status()in the statusline ("statusline").:checkhealth claudecodenames a mapping of another plugin on a review key, such ascsof nvim-surround orcrsof vim-abolish, which the review's key hides in a buffer under review.
Fixed
- A change from outside Claude became one of Claude's hunks, and a revert threw it away. A formatter or a generator in another terminal,
git stash popor another editor changed a file under review, and the change joined Claude's hunks: reverting them erased it. Now the plugin keeps the file as Claude's last tool call left it, next to the base, and carries what changed since into the base, in Neovim and before Claude's next edit or Bash call; reverting Claude's hunks leaves that change alone. A change that overlaps one of Claude's hunks joins it, as your own edit does. Bases from 1.3.0 learn the file the first time the plugin sees them. - The changed words of an added line did not light up. Added lines were painted with
line_hl_group, which Neovim draws over the background of every other highlight on the line, whatever its priority. Now they are painted with a range highlight, and the changed words show inClaudeCodeReviewAddText; the cursor line keeps the green, and so do an empty added line and the last line of the file. - The hint was cut off in a narrow window. At the end of a long line, with Claude's terminal beside the code, the hint and its keys went past the edge of the window. Now it moves above the hunk, or to the statusline, when it does not fit in the narrowest window that shows the file.
- The list deleted a file Claude created without a word, and left its empty folder. Now it says "removed …, you reverted the whole new file", as
cXin the buffer does, and removes the folders the file leaves empty, up to its repository or the project. - A proposal opened at the top of the file, with the hunk and its hint out of sight. Now the cursor goes to the first hunk, as Enter in the list does, and the hint of a proposal says what
crdoes there:cs keep · cx revert · cr revert with reason.
claudecode.nvim 1.3.0
Review that keeps up with git and with worktrees, Neovim that follows Claude into a worktree, and a list of files that shows what matters first.
Upgrading
- A file under review now follows git's HEAD: once you commit it, it leaves the list as after
cs, and after a partial commit only the hunks you did not commit wait. Bases made by an earlier version are taken to match HEAD as it is when this one first sees them. - When Claude works in a worktree, Neovim changes its directory there and shows the worktree's copies of the files you look at, and goes back once Claude leaves.
worktree.follow = falseturns this off. - The list of files puts the path last:
+12 -3 3 hunks · 1 note 14:58 lua/cart.lua. "(new)" after the path became "new file" in the column of what waits. - The hint names the note key:
2/5 cs keep · cx revert · cr note. Withreview.hint = trueand notes off it stays as it was. - In snacks.picker the lists of files and notes sit over their preview, both full width. A layout you set for the sources
claudecode_reviewandclaudecode_review_notesin snacks.picker wins.
Added
- Neovim follows Claude into a worktree. Once a Claude session started from Neovim works in a linked worktree (EnterWorktree,
claude --worktree), Neovim runs:cdthere, and each window that shows a file of the main checkout shows the worktree's copy, at the same line. A buffer with unsaved edits stays, and so do a file the worktree does not have and a file of another worktree. When Claude leaves the worktree, or its terminal closes, Neovim goes back, and so do the windows it moved, unless you changed the directory yourself meanwhile. The review hooks now run after EnterWorktree and ExitWorktree too. - Several files at once in the list. In snacks.picker and fzf-lua
<Tab>picks files, and<A-o>keeps and<A-x>reverts each of them; reverting more than one file asks first. The snacks list names its keys at the bottom. - When a file came under review, and where. Each line of the list shows the time the file came under review today, or the date before that, and, when the files lie in more than one work tree, the branch of each. "deleted" marks a file Claude removed. The highlight group is
ClaudeCodeReviewMeta.
Fixed
- Files you committed stayed on the list for good. A base moved only along Claude's own Bash calls, so after your commit, branch switch, rebase or pull it kept the text from before Claude's edit, and the list showed the whole difference between that and the file now: in one project 66 files of a finished task, one of them
+5714. Now a base moves along any change of HEAD, the way it moves along Claude's checkout, and Neovim reads HEAD from the git directory, running git only once it moved. The files of a removed worktree leave the list as well. - Bash in a worktree outside the project escaped review. Claude Code puts its shell back into the project after a
cdthat leaves it, socd ~/project-worktrees/api-feat && make generateran with the hooks standing in the project, and the snapshot never saw the worktree. Now every Bash call also snapshots the worktrees of the project's repositories, those the command names first. - A worktree inside the repository came up as a file.
git ls-files --othersnames.claude/worktrees/x/as a directory, and the hook took a base for it. Now the hook leaves such directories out and snapshots the worktree as one of its own. - The counts fell off the list. A long path came first and pushed
-12 3 hunks · 1 notepast the edge of snacks.picker's list, leaving+461 -. Now the counts come first, and the path last shortens to the room left: the directory gives way first, from the left and at a slash, then the file name, from the left, so its end and extension stay. snacks.picker's own shortening kept a long name whole and lost its end at the edge. - A message to Neovim at a hit-enter prompt was lost. Neovim at "Press ENTER" runs no message until you leave the prompt, and the hook hung up after half a second, which dropped it: the buffers Claude changed did not reload, and Neovim did not follow Claude into a worktree. Now the hook hands its connection to a small
head -c 1process that holds it until Neovim answers, and goes on at once as before. - A proposal with nothing to review was rejected. In Manual mode a proposal with no hunk, the same text or one that changes only the final newline, came back rejected, and Claude stopped its turn for a change you never saw. Now it goes back accepted at once.
- Reverting a deleted file whose folder is gone raised a Lua error from the list. Now the folder comes back with the file.
- The list found a buffer by a pattern.
bufnr()takes a name for a pattern, soapp/[id]/page.tsxcould stand for another buffer; now the list finds a buffer by its resolved path, as the rest of the review does.
claudecode.nvim 1.2.0
claudecode-nvim-demo.mp4
Notes you can read over before they go and that go as a diff, review that keeps up with git and with folders of repositories, Claude's notifications in Neovim, and fewer upstream commands that did nothing in this flow.
Upgrading
- Ten upstream commands are gone (see Removed). A mapping of your own to one of them now fails with "Not an editor command"; the list below names what to use instead.
- In a buffer under review
cnow waits for its next key without'timeoutlen'. A key that is not one of the review keys changes text as before:cw,ciw,cc,2cw,"acw. - Shift+Enter in Normal mode, in a file under review or with a note, sends your notes; where no note waits it is Enter.
review.notes.local_send_keymap = falseturns this off. - Claude started from Neovim no longer sends its own desktop notification or bell: its notifications come as
vim.notify. The plugin's settings file setspreferredNotifChannel = "notifications_disabled"for that Claude only; Claude outside Neovim keeps yours. - The highlight group
ClaudeCodeReviewNoteSignis nowClaudeCodeReviewNoteBorder, and the lists useClaudeCodeReviewAddedandClaudeCodeReviewRemoved.
Removed
- Upstream commands the review replaces, or whose work the plugin does on its own. In a proposal
cStakes it all,cXrefuses it and:wanswers with what is there, instead of:ClaudeCodeDiffAccept,:ClaudeCodeDiffDenyand:ClaudeCodeCloseAllDiffs.:ClaudeCodetoggles instead of:ClaudeCodeOpenand:ClaudeCodeClose. The server starts with the plugin and:checkhealth claudecodeshows its state, instead of:ClaudeCodeStart,:ClaudeCodeStopand:ClaudeCodeStatus.:ClaudeCode --modelor Claude's/modelpicks the model instead of:ClaudeCodeSelectModel, and notes send text instead of:ClaudeCodeSendText. The LazyVim spec drops<leader>aaand<leader>ad, anddiff_opts.providerlosesaccept_command.
Added
- Shift+Enter sends your notes from the file, not only from the box. In Normal mode, in a file under review or with a note, Shift+Enter sends every note, as
cRdoes; where no note waits it is Enter, and in neo-tree, quickfix and other lists it stays theirs.review.notes.local_send_keymapsets the key. - A list of your notes.
<leader>anin Normal mode, or:ClaudeCodeReviewNotes, lists every note by file and line before you send them, with the code and the note under it in the preview. Enter opens a note in its box to edit it, and the cursor stays on it after you save;<A-d>deletes it,<C-s>sends them all.review.notes.list_keymapsets the key. - Reject with a reason in Manual mode.
crin a proposal reverts the hunk with what you type, and Claude reworks the place in the same turn. With other hunks kept, the reason goes with the note about your reverts. With every hunk reverted, the plugin answers "No, and tell Claude what to do differently" in Claude's own permission dialog in the terminal, since a rejection over the IDE connection carries no text; if the dialog is not there as expected, the proposal is rejected plainly and the reason goes to the clipboard. - Hunks and notes in the list of files.
<leader>akshows how many hunks and notes wait in each file,+12 -3 3 hunks · 1 note, in columns. A file whose hunks are all decided stays on the list while it has notes and opens at the first one.
Changed
- Claude sees the code of a note as a diff. The message marks what Claude removed with
-, above the line it was removed at, and what it added with+, in adiffblock, so Claude's terminal shows the lines as they are and not as a Markdown list. It used to send only the lines there now, so a note under a deleted comment never told Claude which comment it meant. - Green and red in the lists.
+12is green and-3red in<leader>ak, in snacks.picker and fzf-lua alike.<leader>anshows the same for the hunk under each note, and its preview shows the hunks as the review does. The highlight groups areClaudeCodeReviewAddedandClaudeCodeReviewRemoved. - A saved note stays where you typed it. It used to turn into one gray line,
▎ note: …, cut at the window's edge, and the box you had typed in was gone. Now the box stays, dimmed and without the key hints, up to its ten lines, and fits the window again when a split narrows it. The highlight groupClaudeCodeReviewNoteSigngave way toClaudeCodeReviewNoteBorder.
Fixed
- A change thrown away outside review leaves no notes behind. After
git checkoutor a discard in lazygit the file left the list only at the next hook, and its notes stayed in both lists and the statusline. Now the notes of a file go once Claude's change there is gone, and the lists look at the disk again when a terminal such as lazygit's closes, when Neovim gets the focus back and after a:!command. Aftercsthe notes stay, as before. - A note keeps its line after you save and close its file. The line was written once, when you saved the note, so lines added above it and saved sent the list,
cRand Claude to the old line once the file was closed. Now it follows the file on disk. c, a pause, thensno longer starts Flash. Neovim gave up oncsafter'timeoutlen'(300 ms in LazyVim) and ran the change operator, sosstarted Flash andrRemote Flash, under which-key's "+Change" window. In a buffer under reviewcnow waits for its next key as long as you like; any key other than ours changes text as always.- No escape-sequence garbage over Claude's prompt, and Claude's notifications in Neovim. Under some multiplexers or Kitty, Claude Code sent its "waiting for your input" notification as Kitty's OSC 99, and the outer terminal printed it as text such as
99;i=3352:d=1:a=focus;. Claude started from Neovim now sends nothing to the terminal (preferredNotifChannel = "notifications_disabled"in its settings file); aNotificationhook shows "Claude is waiting for your input" and "Claude needs your permission" withvim.notifyinstead, except while the cursor is in Claude's terminal. ]kand[kwork in any file. In a file that is not under review they did nothing, though files waited for review. Now they open the next or previous one, or say that none waits.- Bash in a folder of repositories. When the project folder is not a git repository but holds several, Bash edits in any of them now come up for review. Before, a Bash call that started in such a folder escaped review entirely, and so did one that went
cd ../webfrom a neighbor. The plugin snapshots up to 32 repositories one level below the folder, all at once: with 22 that takes about 0.3 s per Bash call. - An untracked file Bash rewrote or deleted comes up for review even when Neovim does not have it open, as a file Claude created and you kept but have not committed yet does when a formatter rewrites it. Before each Bash call the plugin copies untracked files up to 2 MB, 200 files and 20 MB at most; on APFS a copy is a clone.
- Review no longer fights your git over
index.lock. The Bash snapshot took the lock on a tree with uncommitted changes, so a commit you made in lazygit while Claude ran Bash could fail, and the snapshot dropped out when your git held the lock. It now works on a copy of the index. - Bash snapshots run their git commands at once: in a repository of 6 000 files a Bash call waits about 50 ms for review instead of 140.
claudecode.nvim 1.1.0
Review without leaving Neovim and with fewer keystrokes: notes that send Claude back to rework a change, a cursor that moves on by itself, and review keys that no longer slow down k.
Upgrading
- The review keys moved from
ko,kx,KOandKXtocs,cx,cSandcX. To keep the old ones, setreview.keymaps = { keep = "ko", revert = "kx", keep_all = "KO", revert_all = "KX" };kandKthen wait for'timeoutlen'in buffers under review again. - After
csorcxthe cursor now moves to the next hunk.review.advance = falsekeeps it where it is.
Added
- Notes for Claude.
cron a line, or<leader>anon a selection, opens a box right under it; the code below moves down instead of hiding. Enter saves the note, which shows as one gray line under the code and survives a restart; the cursor moves on to the next hunk. Shift+Enter in the box,<C-s>, orcRanywhere send every note from every file to Claude in one message, typed into the Claude terminal in Neovim.review.notes.send = "enter"sends each note on Enter;review.notes.advance = falsekeeps the cursor still. The statusline counts the notes not sent yet. - Review moves on by itself. After
csorcxthe cursor goes to the next hunk, and from the last one back to the first (review.advance = "hunk"). Withadvance = "file"the next file waiting for review opens once a file is done, by its last hunk or bycSorcX;falsekeeps the cursor where it is. ]kand[kcross files. Past the last hunk]kopens the next file waiting for review at its first hunk, and[kbefore the first one opens the previous file at its last hunk. The list wraps around.review.cross_files = falsekeeps them inside the file.- Progress at a glance. The hint at a hunk starts with its number in the file,
2/5 cs keep · cx revert. The statusline shows how many files wait,review: 4 files, and nothing once they are done: the LazyVim spec adds it to lualine, andrequire("claudecode.review.controller").status()gives it to any statusline. Zen's counter says the same, on the right and in a calmer color.
Changed
- Review keys are
csandcxnow,cSandcXfor the whole file.koandkxmade everykin a buffer under review wait for'timeoutlen'before the cursor moved, andKOandKXdid the same toK(LSP hover). Neovim waits for a motion aftercanyway, so the new keys delay nothing. Your ownreview.keymapsstill win.
Fixed
- A branch switch no longer floods review. When Claude ran
git switch,pull,rebaseorreset, every file git checked out came up as Claude's edit, compared with the old branch. Now only Claude's own edits on top of the new HEAD, and your uncommitted work the command threw away, come up for review.
Install
With lazy.nvim:
{
"odiumuniverse/claudecode.nvim",
version = "*", -- the latest release
dependencies = { "folke/snacks.nvim" },
event = "VeryLazy",
opts = {},
}LazyVim users can copy lazyvim/claudecode.lua instead of the ai.claudecode extra; it now also adds the review counter to lualine. The demo video is attached below.
claudecode.nvim 1.0.0
The first release of claudecode.nvim as a product of its own. It is built on coder/claudecode.nvim at 2390c6e (2026-06-25); upstream's IDE connection, commands, keymaps and options work as before.
Added
- Hunk review. Claude's edits show up as hunks on top of the code: deleted lines in red above the change, added lines in green, changed words highlighted, and a hint at the hunk under the cursor.
kokeeps a hunk,kxreverts it and writes the file,KOandKXact on the whole file,]kand[kmove between hunks.<leader>ak(:ClaudeCodeReview) lists the files waiting for review. - Review covers Edit, Write, MultiEdit and NotebookEdit, and every file Bash changes, creates or deletes in a git repository. It survives a restart of Neovim.
- Claude learns what you reverted. A short note goes into Claude's context with its next tool call or your next message. Each Claude session hears only of the reverts of its own edits.
- Review before write. In Manual mode Claude's proposal opens in place of the file, with the same hunks and keys, and Claude writes only what you kept.
- Modes follow Claude's permission mode. Manual reviews before write, auto and bypass after write, accept edits and plan without review.
<leader>amin the LazyVim spec starts Claude in Manual mode. - Zen mode.
<M-z>(:ClaudeCodeZen) runs Claude full screen in a tab of its own and brings you back to the code;bin/czopens Neovim straight into zen. - Accounts.
:ClaudeCode run [account]runs Claude as a cswap account and keeps it for later launches. diff_opts.provider, a seam for a diff UI of your own.:help claudecode, sections in:checkhealth claudecodefor review, zen and cswap, and a LazyVim spec inlazyvim/claudecode.lua.
Requirements
- Neovim 0.11 or newer. On older versions the plugin behaves as upstream.
- Claude started from Neovim, for review after write and the modes. Checked with Claude Code 2.1.304.
git, to review edits made through Bash; cswap only for:ClaudeCode run.
Install
With lazy.nvim:
{
"odiumuniverse/claudecode.nvim",
version = "*", -- the latest release
dependencies = { "folke/snacks.nvim" },
event = "VeryLazy",
opts = {},
}LazyVim users can copy lazyvim/claudecode.lua instead of the ai.claudecode extra. The demo video is attached below.