Skip to content

Fix split-divider-color Ghostty option in cmux#758

Open
lawrencecchen wants to merge 2 commits intomainfrom
task-split-divider-color-ghostty-option-doesnt-work-in-cmux
Open

Fix split-divider-color Ghostty option in cmux#758
lawrencecchen wants to merge 2 commits intomainfrom
task-split-divider-color-ghostty-option-doesnt-work-in-cmux

Conversation

@lawrencecchen
Copy link
Copy Markdown
Contributor

@lawrencecchen lawrencecchen commented Mar 2, 2026

Summary

  • propagate Ghostty split-divider-color into Bonsplit appearance.chromeColors.borderHex
  • update runtime chrome refresh to compare/apply both backgroundHex and borderHex, so divider-color-only changes are not skipped
  • add a regression test that asserts explicit split divider color is mapped into resolved chrome colors

Testing

  • xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux-unit -configuration Debug -destination 'platform=macOS' -only-testing:cmuxTests/GhosttyConfigTests test (passed)
  • xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux -configuration Debug -destination 'platform=macOS' build (passed)

Issues

  • Related: task-split-divider-color-ghostty-option-doesnt-work-in-cmux

Summary by CodeRabbit

  • New Features

    • Optional customization of split pane divider colors, allowing dividers to be styled independently from backgrounds.
    • Improved color parsing: accepts named colors and explicit "clear"/"transparent" values for configuration inputs.
  • Tests

    • Added tests covering split-divider color parsing (named colors) and resolved chrome/divider color behavior.

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 2, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Mar 2, 2026 10:11pm

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 2, 2026

📝 Walkthrough

Walkthrough

Introduces optional split divider color support across the workspace chrome theming flow and centralizes color parsing. The chrome resolver now accepts an optional splitDividerColor and returns both backgroundHex and borderHex. applyGhosttyChrome and its call sites are updated to thread and apply the new divider color. GhosttyConfig gains a color parser and an X11/CSS-like color name map.

Changes

Cohort / File(s) Summary
Workspace theming
Sources/Workspace.swift
Added splitDividerColor propagation to resolvedChromeColors, bonsplitAppearance(...), and applyGhosttyChrome(...); resolvedChromeColors now returns backgroundHex and borderHex; no-op checks and logs updated to compare/apply both hex values.
Config color parsing & palette
Sources/GhosttyConfig.swift
Replaced direct hex parsing with parseColor(_:); added GhosttyX11ColorMap.hexByName and a parseColor helper that supports named colors and "clear"/"transparent"; palette parsing updated to use the helper (large data map + logic additions).
Tests
cmuxTests/GhosttyConfigTests.swift
Added tests for parsing split-divider-color via named colors (single- and multi-word names) and a test validating resolvedChromeColors uses an explicit splitDividerColor to set borderHex while preserving backgroundHex.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰
I hopped through hex and name,
Splitters now wear color's flame,
Backgrounds kept their gentle tone,
Borders found a shade of their own,
Hooray — the chrome feels less alone! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: fixing the split-divider-color Ghostty option to work in cmux by propagating it to Bonsplit's appearance chrome colors.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch task-split-divider-color-ghostty-option-doesnt-work-in-cmux

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 2, 2026

Greptile Summary

This PR fixes the Ghostty split-divider-color option by propagating it into Bonsplit's chrome configuration and fixing a subtle bug in runtime chrome updates.

Key improvements:

  • Propagates splitDividerColor from GhosttyConfig through the entire chrome color resolution chain to borderHex
  • Fixes critical bug where the no-op check only compared backgroundHex, causing divider-color-only changes to be ignored. Now correctly checks both backgroundHex and borderHex
  • Adds nonisolated to bonsplitChromeHex() to enable calling from nonisolated contexts
  • Includes proper test coverage to prevent regression

Implementation details:

  • Background colors go through GhosttyBackgroundTheme.color() for theming/opacity handling
  • Border colors use explicit user values without theming (intentional design)
  • Both handle alpha transparency correctly (include alpha in hex only when < 0.999)

Confidence Score: 5/5

  • This PR is safe to merge with high confidence
  • The implementation is clean, well-tested, and fixes a real bug. The changes follow existing patterns, maintain backward compatibility through default parameters, and include regression tests. The fix for the no-op check is particularly important as it prevents divider-color-only updates from being silently ignored.
  • No files require special attention

Important Files Changed

Filename Overview
Sources/Workspace.swift Correctly propagates split-divider-color through chrome resolution chain and fixes no-op detection for border-only updates
cmuxTests/GhosttyConfigTests.swift Adds regression test to verify explicit split divider color is correctly mapped to borderHex

Last reviewed commit: bcfa7b8

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
cmuxTests/GhosttyConfigTests.swift (1)

492-505: Add a regression for the runtime apply path, not just color resolution.

Lines 492-505 validate resolvedChromeColors, but the runtime fix in this PR is the no-op/apply behavior in Workspace.applyGhosttyChrome. Please add a test where backgroundHex stays the same and only splitDividerColor changes, then assert borderHex is applied.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmuxTests/GhosttyConfigTests.swift` around lines 492 - 505, Add a regression
test that exercises the runtime apply path by using Workspace.applyGhosttyChrome
rather than only Workspace.resolvedChromeColors: create initial colors where
backgroundHex is "#272822" and splitDividerColor is some value, create a
Workspace (or the object that has applyGhosttyChrome) with those initial chrome
values, then call applyGhosttyChrome with a new chrome where backgroundHex
remains "#272822" but splitDividerColor changes (e.g., "#45475A"), and finally
assert that the workspace's applied borderHex (or equivalent property) equals
the new splitDividerColor while the backgroundHex remains unchanged; reference
Workspace.applyGhosttyChrome and Workspace.resolvedChromeColors to locate
related code.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@cmuxTests/GhosttyConfigTests.swift`:
- Around line 492-505: Add a regression test that exercises the runtime apply
path by using Workspace.applyGhosttyChrome rather than only
Workspace.resolvedChromeColors: create initial colors where backgroundHex is
"#272822" and splitDividerColor is some value, create a Workspace (or the object
that has applyGhosttyChrome) with those initial chrome values, then call
applyGhosttyChrome with a new chrome where backgroundHex remains "#272822" but
splitDividerColor changes (e.g., "#45475A"), and finally assert that the
workspace's applied borderHex (or equivalent property) equals the new
splitDividerColor while the backgroundHex remains unchanged; reference
Workspace.applyGhosttyChrome and Workspace.resolvedChromeColors to locate
related code.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4d9587c and bcfa7b8.

📒 Files selected for processing (2)
  • Sources/Workspace.swift
  • cmuxTests/GhosttyConfigTests.swift

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
Sources/GhosttyConfig.swift (1)

495-1281: Consider moving the generated X11 map out of GhosttyConfig.swift.

This is correct functionally, but extracting GhosttyX11ColorMap to a dedicated generated file (or resource-backed loader) would keep parsing logic focused and reduce churn in this core config file.

Possible lightweight refactor
- // Generated from ghostty/src/terminal/res/rgb.txt.
- private enum GhosttyX11ColorMap {
-     static let hexByName: [String: String] = [ ... ]
- }
+ // Keep in a dedicated generated file:
+ // Sources/Generated/GhosttyX11ColorMap.swift
+ private enum GhosttyX11ColorMap {
+     static let hexByName: [String: String] = [ ... ]
+ }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Sources/GhosttyConfig.swift` around lines 495 - 1281, The large generated
GhosttyX11ColorMap enum (type GhosttyX11ColorMap with static hexByName) should
be extracted into its own generated source (e.g.,
GhosttyX11ColorMap.generated.swift) or a resource-backed loader; move the enum
and its hexByName dictionary out of GhosttyConfig.swift, keep the same type name
and access level, update any references in GhosttyConfig to use
GhosttyX11ColorMap.hexByName, and ensure the new file is included in the build
so compilation and visibility remain identical.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@Sources/GhosttyConfig.swift`:
- Around line 495-1281: The large generated GhosttyX11ColorMap enum (type
GhosttyX11ColorMap with static hexByName) should be extracted into its own
generated source (e.g., GhosttyX11ColorMap.generated.swift) or a resource-backed
loader; move the enum and its hexByName dictionary out of GhosttyConfig.swift,
keep the same type name and access level, update any references in GhosttyConfig
to use GhosttyX11ColorMap.hexByName, and ensure the new file is included in the
build so compilation and visibility remain identical.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bcfa7b8 and 3e5e018.

📒 Files selected for processing (2)
  • Sources/GhosttyConfig.swift
  • cmuxTests/GhosttyConfigTests.swift
🚧 Files skipped from review as they are similar to previous changes (1)
  • cmuxTests/GhosttyConfigTests.swift

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3e5e0185d9

ℹ️ 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".

Comment on lines +205 to +206
if let hex = NSColor(hex: normalized) {
return hex
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Resolve X11 color names before attempting hex parsing

parseColor tries NSColor(hex:) before looking up GhosttyX11ColorMap, but NSColor(hex:) currently accepts partial scans as long as the input length is 6. That means valid X11 names like bisque, brown1, or coral1 are interpreted as tiny hex values (e.g. bisque becomes #00000B) and never reach the name map, so the new named-color support silently returns incorrect colors for a non-trivial subset of names.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant