Skip to content

[BUG] closeAllDiffTabs closes all diff-mode windows, destroying unrelated diffs (diffview.nvim) #277

@tibbe

Description

@tibbe

Bug Description

claudecode.nvim closes/overwrites diff windows it doesn't own. If you have a diff open from diffview.nvim (or native :diffthis/vimdiff/fugitive) while the Claude Code integration is active, the side-by-side diff windows get closed, leaving the review "blank." Plain (non-diff) buffers are unaffected.

Two independent defects in the source:

  1. lua/claudecode/tools/close_all_diff_tabs.lua closes every &diff window, not just claudecode's own. The handler marks any window with diff set for closing (and force-deletes buffers matching %.diff$ / diff:// / ^fugitive://), with no check that claudecode created them:

    local diff_mode = vim.api.nvim_win_get_option(win, "diff")   -- ~L30
    if diff_mode then
      should_close = true                                        -- ~L34-36
    end
    ...
    pcall(vim.api.nvim_win_close, win, false)                    -- ~L56-58

    diffview's side-by-side windows have &diff set, so they're closed; its diffview:// file panel isn't a diff window, so it survives — which exactly matches the symptom.

  2. find_main_editor_window does not exclude &diff windows (in both lua/claudecode/tools/open_file.lua ~L53 and lua/claudecode/diff.lua ~L124). It skips floats, terminals, nofile/prompt, and known sidebar filetypes, but a diffview working-tree window is an ordinary file buffer, so it's chosen as the "main editor window" and openFile/openDiff then :edits into it, corrupting the layout.

To Reproduce

  1. Open Neovim in a git repo with uncommitted changes and run :DiffviewOpen — the side-by-side diff appears.
  2. Start/connect the Claude Code integration against that Neovim (--ide).
  3. Use Claude normally (it reads/edits files / cleans up diffs over the course of a turn).
  4. The side-by-side diff windows are closed/blanked; only the Diffview file panel remains. Normal file buffers are never affected.

(The handler behavior in defect #1 is deterministic: any window with &diff set is closed when closeAllDiffTabs runs.)

Expected Behavior

claudecode should only close or replace diffs it created (it already tracks these via diff.close_all_diffs()). It must not close or delete windows/buffers belonging to other diff tools (diffview.nvim, :diffthis, fugitive). Likewise, find_main_editor_window should not select a window that is currently in diff mode.

Environment

  • Neovim version: 0.11.6
  • Claude Code CLI version: 2.1.175
  • OS: macOS 26.3.1 (Darwin 25.3.0)
  • Plugin version: v0.3.0-35-g7b8b709 (commit 7b8b709)

Error Messages

No error is emitted — the diff windows are closed silently. MCP-message logging during the affected flow showed only the connection handshake plus read-only getDiagnostics calls, so I was unable to capture the exact client→server RPC that invokes closeAllDiffTabs; I'm therefore reporting defect #1 as an independent handler bug rather than asserting the precise call site.

(no error output)

Additional Context

  • Suggested fixes: scope closeAllDiffTabs to claudecode-tracked diffs only (or, at minimum, skip windows in a tab that contains a diffview:// buffer); add a vim.wo[win].diff guard to find_main_editor_window in both files.
  • Workaround that helps the edit-time path only: setting diff_opts.open_in_new_tab = true keeps openDiff from reusing the current tab — but it does not address closeAllDiffTabs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions