You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
diff: add a true in-place "inline" overlay (virtual text) as the future layout = "inline" #294
Follow-up to #293 / #195. The diff_opts.layout = "unified" option (renamed from "inline" before v0.4.0) renders a unified diff in a separate vsplit pane — a single read-only buffer with interleaved red/green lines. This issue tracks adding a true in-place inline overlay: the diff shown as virtual text layered onto the file in the same window, the way users typically picture a "VS Code-style inline" diff (cf. mini.diff, gitsigns preview, sidekick NES, Cursor inline edits).
When implemented, this mode is the one that should claim layout = "inline" — which is exactly why we reserved that name in #293.
"unified" vs the proposed "inline"
"unified" (shipped): single read-only buffer in a rightbelow vsplit, deleted (red/strikethrough) + added (green) lines interleaved. Compact, but it's a separate pane and not editable before accept.
"inline" (this issue): no extra window — proposed changes rendered in place over the real file.
Suggested approach (keeps pre-accept editability)
The unified/read-only path forfeits editing the proposal before accepting. A prototype pattern that keeps it (the codecompanion/sidekick model):
Proposed/added lines = real, editable buffer lines, highlighted (e.g. ClaudeCodeInlineDiffAdd) with a + sign.
Deleted lines = virtual text via nvim_buf_set_extmarkvirt_lines (strikethrough/red), so they're visible but not part of the editable content.
On accept, the buffer content already is the new file (deleted lines were never real text), so edits made during review are captured. On reject, clear the extmarks / restore.
A pure-Lua, zero-dependency engine (not mini.diff/diffview — see #169) keeps this aligned with the project's philosophy. Bonus: a single-buffer extmark view sets no &diff windows, which sidesteps the closeAllDiffTabs foreign-diff class (#277) and the stale-diff repaint issues (#205).
Notes
The current "unified" path doesn't fire the ClaudeCodeDiffOpened / ClaudeCodeDiffClosedUser autocmds that the native diff does — worth wiring up for any new mode.
This is a valid follow-up to the current layout = "unified" work rather than a bug in the shipped unified layout. The requested behavior is a new in-place review mode: proposed content is shown in the original file window without opening an extra diff pane, while deleted old content is rendered as virtual lines/extmarks.
What I verified
The current configuration accepts diff_opts.layout = "vertical", "horizontal", or "unified"; "inline" is intentionally rejected right now.
The existing "unified" path dispatches to lua/claudecode/diff_inline.lua, creates a scratch buffer, opens it with rightbelow vsplit, renders additions/deletions in that buffer, and sets it non-modifiable. That matches the issue's description of the current behavior and confirms that a true in-place overlay mode does not exist yet.
The requested design is meaningfully different from the current unified split: to preserve pre-accept editability, added/proposed lines should become real editable buffer lines, while deleted lines should be virtual-only display state such as virt_lines extmarks.
The zero-dependency direction fits the existing implementation style: the current unified path already uses pure Lua plus Neovim APIs rather than adding mini.diff/diffview as dependencies.
Recommendation
Keep this open and implement it as a new layout = "inline" feature, while preserving layout = "unified" for the existing single-buffer split view. A good implementation slice would include:
Extend config/types/docs/tests to accept diff_opts.layout = "inline" with wording that clearly distinguishes it from "unified".
Add a separate in-place engine instead of mutating the current read-only unified split path too much.
For existing-file edits, apply the proposed buffer content into the real target buffer for review, mark added/proposed regions with highlights/signs, and render deleted old lines with virtual lines/extmarks.
On accept, return the current reviewed buffer content so user edits made during review are preserved.
On reject/cleanup, restore the original file content, clear extmarks/signs/autocmds, and avoid leaving modified or hidden buffers behind.
Ensure the inline mode emits the same diff lifecycle events as the native layouts.
Keep foreign-diff safety explicit: the new mode should not set &diff or call diffthis, so it should avoid the class of issues where Claude diffs interact with diffview/vimdiff tabs.
Suggested acceptance criteria
layout = "inline" opens no extra diff window for existing-file edits.
Deleted lines are visible but not part of the editable buffer content.
Added/proposed lines are editable before accept.
Accept preserves any review-time edits made in the buffer.
Reject restores the original content and removes all inline diff UI state.
New-file, delete-only, mixed-change, and no-trailing-newline cases are covered by tests.
ClaudeCodeDiffOpened / ClaudeCodeDiffClosed fire for the inline layout with useful window/buffer metadata.
Existing vertical, horizontal, and unified layouts keep their current behavior.
Adjacent finding
While checking the lifecycle-event requirement, I found that the current layout = "unified" path appears to skip the documented ClaudeCodeDiffOpened / ClaudeCodeDiffClosed events. I created #296 as a separate, narrower bug so this feature request can stay focused on the in-place overlay.
Validation performed
Inspected lua/claudecode/config.lua, lua/claudecode/types.lua, lua/claudecode/diff.lua, lua/claudecode/diff_inline.lua, README.md, and the diff-related unit specs.
Activity
refactor(diff): rename diff_opts.layout "inline" to "unified" (coder#295
ThomasK33 commentedon Jun 25, 2026
Note
This triage report is AI-generated using Mux
Triage report
Classification: feature request.
This is a valid follow-up to the current
layout = "unified"work rather than a bug in the shipped unified layout. The requested behavior is a new in-place review mode: proposed content is shown in the original file window without opening an extra diff pane, while deleted old content is rendered as virtual lines/extmarks.What I verified
diff_opts.layout = "vertical","horizontal", or"unified";"inline"is intentionally rejected right now."unified"path dispatches tolua/claudecode/diff_inline.lua, creates a scratch buffer, opens it withrightbelow vsplit, renders additions/deletions in that buffer, and sets it non-modifiable. That matches the issue's description of the current behavior and confirms that a true in-place overlay mode does not exist yet.virt_linesextmarks.Recommendation
Keep this open and implement it as a new
layout = "inline"feature, while preservinglayout = "unified"for the existing single-buffer split view. A good implementation slice would include:diff_opts.layout = "inline"with wording that clearly distinguishes it from"unified".&diffor calldiffthis, so it should avoid the class of issues where Claude diffs interact with diffview/vimdiff tabs.Suggested acceptance criteria
layout = "inline"opens no extra diff window for existing-file edits.ClaudeCodeDiffOpened/ClaudeCodeDiffClosedfire for the inline layout with useful window/buffer metadata.vertical,horizontal, andunifiedlayouts keep their current behavior.Adjacent finding
While checking the lifecycle-event requirement, I found that the current
layout = "unified"path appears to skip the documentedClaudeCodeDiffOpened/ClaudeCodeDiffClosedevents. I created #296 as a separate, narrower bug so this feature request can stay focused on the in-place overlay.Validation performed
lua/claudecode/config.lua,lua/claudecode/types.lua,lua/claudecode/diff.lua,lua/claudecode/diff_inline.lua,README.md, and the diff-related unit specs.layout = "inline"naming before v0.4.0 (reserve "inline" for a true in-place overlay) #293, [BUG] closeAllDiffTabs closes all diff-mode windows, destroying unrelated diffs (diffview.nvim) #277, and [BUG] Diff panels not cleared when new suggestion is shown — stale diffs accumulate until window focus change #205.mise exec -- busted -v tests/unit/diff_inline_spec.lua tests/unit/diff_auto_resize_events_spec.lua— 39 successes, 0 failures.mise run check— 0 warnings, 0 errors.