Add opt-in setting to stretch surface tabs to fill pane width (#5091)#5147
Add opt-in setting to stretch surface tabs to fill pane width (#5091)#5147austinywang wants to merge 8 commits into
Conversation
Lets surface tabs stretch to fill their pane's available tab-bar width instead of using a fixed width. Off by default — strictly opt-in. - Bonsplit submodule: bump to the tab-width-mode commit; pass Appearance.tabWidthMode (.fill when enabled, .fixed otherwise). - GhosttyConfig: parse the `surface-tabs-fill-pane-width` boolean key (mirrors the surface-tab-bar-font-size / #2534 pattern). - CmuxGhosttyConfigSettingEditor: key/default + shared bool parse/format helpers used by the parser, settings, and tests. - Workspace: thread the flag into bonsplitAppearance and live-update open panes on config reload (tabWidthModeChanged, mirroring fontSizeChanged). - Settings: discoverable "Stretch Tabs to Fill Pane Width" toggle in the Terminal section (SettingsHostActions API + HostSettingsActions impl), localized (en + ja). - Docs: document the key in the configuration example. - Tests: GhosttyConfig parse + editor round-trip coverage for the flag. Bonsplit PR: manaflow-ai/bonsplit#141 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughAdds a new Ghostty boolean setting ChangesSurface Tabs Fill Pane Width Feature
Sequence Diagram(s)(omitted — changes are a single cohesive feature without a multi-actor sequential protocol that requires diagramming) Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
Caution Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional.
❌ Failed checks (1 error, 1 warning)
✅ Passed checks (16 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThis PR adds an opt-in
Confidence Score: 5/5Safe to merge — the change is strictly additive and opt-in, touching only config parsing, a new Settings toggle, and Bonsplit appearance wiring guarded by a no-op check. The new config key, editor helper, appearance mapping, and Settings toggle all mirror established patterns in the codebase. The generation-based ordered-save logic is sound, localization is complete for all 20 supported locales, the appearance signature is correctly extended, and no actor isolation mistakes or blocking primitives were introduced. No files require special attention. Important Files Changed
Reviews (6): Last reviewed commit: "Merge origin/main into issue-5091-tab-fi..." | Re-trigger Greptile |
There was a problem hiding this comment.
1 issue found across 10 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@Packages/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/TerminalSection.swift`:
- Around line 64-71: The saveTabsFillPaneWidth(_:)'s Task currently drops the
Bool result from hostActions.setSurfaceTabsFillPaneWidth(_:) so failures are
ignored; change the Task to await the Bool result, and if it returns false
revert the optimistic toggle state and surface the same save-failed feedback
used by the tab-bar font-size path (i.e., call the same feedback UI/handler used
there). Keep the existing cancellation behavior on tabsFillSaveTask, but ensure
you check the returned Bool from hostActions.setSurfaceTabsFillPaneWidth, revert
the UI model when it fails, and invoke the existing save-failure feedback
routine.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: e6586b14-36f5-40e4-a025-1efc17abf6fd
📒 Files selected for processing (10)
Packages/CmuxSettingsUI/Sources/CmuxSettingsUI/Environment/SettingsHostActions.swiftPackages/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/TerminalSection.swiftResources/Localizable.xcstringsSources/CmuxApplicationSupportDirectories.swiftSources/GhosttyConfig.swiftSources/HostSettingsActions.swiftSources/Workspace.swiftcmuxTests/GhosttyConfigTests.swiftvendor/bonsplitweb/app/[locale]/docs/configuration/page.tsx
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@Packages/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/TerminalSection.swift`:
- Around line 74-81: The current saveTabsFillPaneWidth(_:) awaits
hostActions.setSurfaceTabsFillPaneWidth(enabled) then bails out early on
Task.isCancelled, which prevents updating tabsFillPaneWidthLastSaved when the
disk write actually succeeded; move the cancellation check below the saved
handling so that when saved == true you always set tabsFillPaneWidthLastSaved =
enabled and tabsFillSaveFailed = false (so model matches disk), and only skip
UI-only work (like reverting tabsFillPaneWidth) when the task is cancelled;
specifically update the logic around hostActions.setSurfaceTabsFillPaneWidth,
tabsFillPaneWidthLastSaved, tabsFillPaneWidth, and tabsFillSaveFailed so saved
results are applied even if Task.isCancelled immediately after the await.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 0453534f-2de9-4967-b6c3-54e7d03aec75
📒 Files selected for processing (3)
Packages/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/TerminalSection.swiftResources/Localizable.xcstringsSources/HostSettingsActions.swift
💤 Files with no reviewable changes (2)
- Resources/Localizable.xcstrings
- Sources/HostSettingsActions.swift
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 3cb346a. Configure here.
There was a problem hiding this comment.
1 issue found across 5 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
Stale automated review: the actionable CodeRabbit thread was resolved after follow-up fixes, and the CodeRabbit status check is passing on the current PR head.

Closes #5091
Summary
Adds an opt-in setting so surface tabs can stretch to fill their pane's available tab-bar width instead of sitting at a fixed width. The headline case: when a pane has a single tab, that lone tab now spans the full pane width. The current fixed-width behavior remains the default — this is strictly opt-in, exactly as the reporter framed it.
When enabled:
When disabled (default): the tab strip is byte-for-byte unchanged.
How it's exposed (mirrors the #2534
surface-tab-bar-font-sizepattern)surface-tabs-fill-pane-width = true(defaultfalse).fontSizeChangeddetection inWorkspace.applyGhosttyChrome).Cross-repo
The tab strip is rendered by Bonsplit (
vendor/bonsplitsubmodule). The layout capability lives there:Appearance.tabWidthMode(.fixed/.fill).This cmux PR bumps the submodule pointer to the bonsplit branch commit (
887ece7, pushed to that PR's branch) and wires the config key/Settings toggle through toAppearance.tabWidthMode.Changes
vendor/bonsplit→ tab-width-mode commit.Sources/GhosttyConfig.swift— parsesurface-tabs-fill-pane-width.Sources/CmuxApplicationSupportDirectories.swift— key/default + shared bool parse/format helpers.Sources/Workspace.swift— thread the flag intobonsplitAppearance+ live-update on reload.Sources/HostSettingsActions.swift+Packages/CmuxSettingsUI/...— Settings toggle.Resources/Localizable.xcstrings— en + ja strings.web/app/[locale]/docs/configuration/page.tsx— document the key.cmuxTests/GhosttyConfigTests.swift— parse + editor round-trip coverage.Testing
testTabWidthModeDefaultsToFixed,testTabWidthModeFillIsSettableAndDistinct.SurfaceTabsFillPaneWidthConfigTests(default off, parse truthy/falsy forms, clamp/ignore invalid, loader, editor round-trip).🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmithwith what you need. Autofix is disabled.Note
Low Risk
UI and tab-bar layout preference only; follows existing Ghostty config + reload patterns with tests and no auth or data-path changes.
Overview
Adds an opt-in way to stretch surface tabs across each pane’s tab bar (default stays fixed-width). The new Ghostty key
surface-tabs-fill-pane-widthis parsed intoGhosttyConfig, persisted via shared bool helpers, and exposed in Terminal settings throughSettingsHostActionswith ordered async saves, rollback, and save-failure messaging.Open workspaces map the flag to Bonsplit
tabWidthMode(.fill/.fixed), including on config reload viaapplyGhosttyChromeand in the appearance signature so live updates apply. Config disk writes share the renamedGhosttyConfigWriteractor (formerly font-only). Docs, broad localization, and parse/persistence tests are included.Reviewed by Cursor Bugbot for commit 705f264. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by cubic
Adds an opt‑in setting to stretch surface tabs to fill each pane’s tab bar, with fixed‑width tabs remaining the default. Includes a Terminal Settings toggle with live updates and a localized UI.
New Features
surface-tabs-fill-pane-width(defaultfalse, accepts common truthy/falsy forms).SettingsHostActions.setSurfaceTabsFillPaneWidth; cancels superseded writes, rolls back on failure, and uses cached reads for initial state.BonsplitConfiguration.Appearance.tabWidthMode(.fill/.fixed) with change detection and live updates; appearance signature includes the flag for reliable reloads.Dependencies
vendor/bonsplitto addAppearance.tabWidthModeand wire.fillvs.fixed.Written for commit 705f264. Summary will update on new commits.
Summary by CodeRabbit
New Features
Documentation
Tests
Chores