Repository navigation
fix(diff): give the user's windows back their sizes when a diff closes - #421
Conversation
A diff that opens in the user's tab runs `wincmd =`, which resizes every window in that tab. Closing the diff's windows then shares their space out by 'equalalways' rules, so the user's windows ended at other sizes: a window resized to 30 columns came back 53 wide, and two editors or the windows of the user's own vimdiff ended with their widths swapped by one column (horizontal and unified layouts). Both layouts now save the sizes of the tab's tiled windows before the diff splits it, and set them again when the diff closes, if that tab still has the same windows in the same order. The Claude terminal's width is handled afterwards as before. The own-diff-tab test's 'diff' loop passed with or without the new-tab fix (the diff never touched the user's windows), so it is removed. The created_new_tab and tab-return assertions keep guarding that case. Part of #416 _Generated with [`xum`](https://github.com/coder/xum) • Model: `anthropic:claude-opus-5-5` • Thinking: `xhigh`_
|
@codex review |
|
@codex security review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
🛡️ Codex Security ReviewSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e050fbaf4e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…reen resizes, or setup fails Review follow-ups for the window size restore: - A diff that opens in a tab another open diff already split shares that diff's sizes, the ones from before the first diff. The last diff to close gives them back, in either close order. Before, closing the first diff first left the user's windows equalized. - Nothing is resized when the screen size changed while the diff was open: sizes taken for the old screen do not fit the new one. - A diff whose setup fails after it split the tab (for example a user's autocmd that errors) gives the sizes back too, in both the split and the unified layouts. Part of #416 _Generated with [`xum`](https://github.com/coder/xum) • Model: `anthropic:claude-opus-5-5` • Thinking: `xhigh`_
|
@codex review |
|
@codex security review |
🛡️ Codex Security ReviewSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5fd6e29936
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…oring sizes Review follow-ups for the window size restore: - The saved sizes now hold the tab's winlayout() tree, and the restore needs the same tree. A layout change that keeps the window handles and their order (A | B turned into A above B with CTRL-W K) no longer gets the old side-by-side sizes. - The tree comes from winlayout(), which leaves out floating and external windows, so an external window (multigrid UI) neither joins the saved sizes nor blocks the restore. - The restore compares the columns and rows the windows fill, counted over the tree, instead of 'columns' and 'lines'. A tab line that appears while the diff is open (a second tab with showtabline=1) takes a row, and the old heights are not forced back into the smaller space. The busted vim mock gets winlayout() and vim.deep_equal(), which the restore now calls. Part of #416 _Generated with [`xum`](https://github.com/coder/xum) • Model: `anthropic:claude-opus-5-5` • Thinking: `xhigh`_
|
@codex review |
|
@codex security review |
|
Codex Review: Didn't find any major issues. Nice work! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
🛡️ Codex Security ReviewSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
Why
We are closing the open follow-up issues in coder/claudecode.nvim one small PR at a time. This one takes item 5 of #416.
A diff that opens in the user's tab runs
wincmd =, which resizes every window in that tab. When the diff closes, Neovim shares the space of the closed windows out by its 'equalalways' rules. The user's windows end at other sizes:main,hello.txtresized to 30 columns came back 53 columns wide afterclose_tab.The fix saves the sizes of the tab's tiled windows before the diff splits the tab, and sets them again when the diff closes.
What changed
lua/claudecode/diff.lua: newsave_window_sizes(tab)andrestore_window_sizes(saved). The diff state gets awindow_sizesfield ({ tab, layout, width, height, windows = { { win, width, height }, ... } }): the tab'swinlayout()tree (no floating or external windows), the columns and rows its windows fill, and each window's size. The split layouts save it when the diff stays in the user's tab, and_cleanup_diff_staterestores it after it closes the diff's windows and before it sets the Claude terminal's idle width. The setup error handler restores it too, when setup fails before the diff is registered.winrestcmd()does.lua/claudecode/diff_inline.lua: the unified layout saves the sizes before its fallback split or its vsplit. It restores them incleanup_inline_diff, before it sets the terminal width back, and incleanup_unregistered_inline_setupwhen setup fails.tests/integration/diff_window_sizes_spec.lua(new, real Neovim): vertical and horizontal diffs next to a resized editor,close_tabwhile the user is in another tab, a split and a unified setup that a user's autocmd stops, no restore after a screen resize, a new tab line or CTRL-W K, a unified diff next to the user's own vimdiff, and two unified diffs in one tab closed first-opened first (unified tests 0.9+ only).tests/mocks/vim.lua: the busted mock getsvim.fn.winlayout()(one row of the tab's tiled windows) andvim.deep_equal(), which the restore calls.tests/integration/diff_current_tab_spec.lua: removed the loop that checked the user's diff windows keep'diff'. It passed with and without the new-tab fix, because the diff never touches those windows. Thecreated_new_taband tab-return assertions keep guarding that case.README.md(auto_resize_terminal section) andlua/claudecode/README.md(Diffs contract): say that closing a diff gives the windows their sizes back.covered.lock: re-recorded. All code facts read TRUE, and the model passes.Scope
open_in_new_tab, or a current tab with the user's diff).close_tabthe cursor is in the right-hand diff window, as onmain. Not part of this item.Blast Radius
diff_opts.auto_resize_terminal = false, the Claude terminal in that tab also gets its width from before the diff back, thenClaudeCodeDiffClosedfires as before, so a handler's resize still wins.Verification
Red/green,
diff_window_sizes_spec.luaon Neovim 0.8.3, 0.9.5 and 0.12.3. With the two Lua files frommain, the first four tests fail (3 on 0.8.3, where the unified one is pending). With the fix, all pass (7 on 0.8.3, 10 on 0.9.5 and 0.12.3). Each review follow-up test fails when its part of the fix is removed (the space check, the shared sizes, the restore in each setup-failure path), and the tab line and CTRL-W K tests fail on the round-2 head 5fd6e29.Window-choice matrix (the fix(diff): skip floating windows, give a user's diff tab a new tab, and keep the other tab's terminal width #410 verifier's harness: 22 layouts × vertical/horizontal/unified ×
open_in_new_tab0/1 × 3 files × accept/deny, on 0.8.3, 0.9.5 and 0.12.3, 2112 runs). Onmain, the current tab's sizes differ afterclose_tabin 24 runs, all of them the two Follow-ups from #410-#415: flaky memory test, WebSocket close code, openFile known gap, lock conflicts #416 layouts. With the fix: 0. Before/after rows differ only inafter_closeof those 24 runs. Layout after open, answers, file texts and tab choice are the same.Resized nested layouts (
a | (c over b)withaat 40 or 50 columns andcat 10 lines, with and without the Claude terminal,auto_resize_terminalon and off, 120 runs on 0.8.3 and 0.12.3):mainloses the sizes in 120 of 120, the fix keeps them in 120 of 120.Live run with
vcn.sh(Neovim in a real terminal, the WebSocket client plays the Claude CLI: openDiff,:w, close_tab):maind9987bahello.txtresized, Claude terminalhello 30 | other 80 | TERM 48hello 53 | other 57 | TERM 48hello 30 | other 80 | TERM 48other 50 | third 109other 79 | third 80other 50 | third 109Horizontal case after
close_tab,mainand then the fix:Unified case after
close_tab,mainand then the fix:Gates on the head:
mise run check(0 warnings),mise run test(1036 successes, 0 failures),scripts/run_integration_tests_individually.shon 0.12.3 (73 passed) and 0.8.3 (59 passed),stylua --check,prettier --check,verify-diff-lifecycle/check.shPASS (all facts TRUE; the one new call site only readswindow_sizesfromactive_diffs). The matrices in steps 2 and 3 were rerun on 7be62ae with the same results.Part of #416
Generated with
xum• Model:anthropic:claude-opus-5-5• Thinking:xhigh