Skip to content

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

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

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions