Extract Ghostty config-file discovery from GhosttyTerminalView into CmuxGhosttyConfigLoader
Pulls the pure Ghostty config-file discovery + scanning domain out of GhosttyApp (inside the ~12k-line Sources/GhosttyTerminalView.swift god file) into a new leaf package CmuxGhosttyConfigLoader, as a constructor-injected value type GhosttyConfigDiscovery.
What moved
Now a real type with inverted seams instead of statics welded onto GhosttyApp:
- CJK font fallback:
cjkFontMappings,autoInjectedCJKFontMappings,shouldInjectCJKFontFallback,resolvedInjectedCJKFontName, glyph-coverage probing. - User font-config scanning:
userFontConfigSummary,config-fileinclude following,parsedConfigEntry/applyConfigFileDirective,UserFontConfigSummary. - Scan-path resolution:
loadedGhosttyConfigScanPaths/loadedCJKScanPaths,cmuxAppSupportConfigURLs. - Legacy-config decisions:
shouldLoadLegacyGhosttyConfig,shouldIncludeLegacyGhosttyConfigInScanPaths,shouldIgnoreNativeLegacyBaselineForUnparsedAppearance. - Conditional-theme override + managed-default-appearance decisions.
Seams (inverted, constructor-injected; defaults reproduce prior behavior)
GhosttyConfigFileReading(defaultFileManagerGhosttyConfigFileReader) inverts every config file size/contents read that usedFileManager.default/String(contentsOfFile:).GhosttyFontProbing(defaultCoreTextGhosttyFontProbe) inverts the CoreTextCTFontfamily-name discovery and glyph-coverage probing.CmuxGhosttyConfigPathResolver(fromCmuxFoundation) injected for app-support URL resolution.
One major public type per file; /// DocC on every public symbol; no caseless-enum namespace, no free functions, no lint:allow.
Byte-identical
Every directive key, scan-path ordering, legacy-fallback size rule, config-file include semantics, CJK range set, and theme-override text is preserved exactly. The C-API config-load instance methods (loadDefaultConfigFilesWithLegacyFallback, loadCJKFontFallbackIfNeeded, reloadConfiguration, synchronizeThemeWithAppearance) stay in the app target and now call the new type to decide what to load while still issuing the ghostty_config_load_* calls themselves. The former GhosttyApp statics remain as thin one-line forwards, so all call sites (including cmuxTests) are unchanged.
Left in the app target on purpose: everything that mutates ghostty_config_t, GhosttyApp instance state, or reaches AppDelegate.shared / NotificationCenter — not pure, not part of this clean subset.
The seam is a synchronous value type (not an actor) because discovery runs inside the synchronous launch-path config-load sequence; an async actor would reorder the C-API calls. Principled over the actor shape the audit suggested.
Tests
17 behavior unit tests with in-memory fakes for both seams (CJK mapping, font-config scanning incl. config-file includes, legacy-config rules, scan-path composition, theme override).
Stats / wiring
- Giant
GhosttyTerminalView.swiftshrinks 12093 → 11691 lines (−402);.github/swift-file-length-budget.tsvreconciled. - Wired into
cmux.xcodeproj(6 pbxproj entries) + app-target dependency.
NOTE: full app build is validated by GitHub CI; local app xcodebuild was skipped intentionally (parallel refactor agents). The new package builds and tests pass locally, and scripts/lint-ios-package-conventions.sh is clean with zero new lint:allow.
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.
Summary by cubic
Extracted Ghostty config discovery/scanning into a new leaf package CmuxGhosttyConfigLoader with GhosttyConfigDiscovery, reducing GhosttyTerminalView.swift by 402 lines and keeping behavior identical. Improves testability and isolates pure logic from app state.
- Refactors
- Moved: CJK font fallback, user font-config scanning (with includes), scan-path resolution, legacy-config decisions, and theme override/managed default appearance into
GhosttyConfigDiscovery. - Added seams:
GhosttyConfigFileReading(defaultFileManagerGhosttyConfigFileReader),GhosttyFontProbing(defaultCoreTextGhosttyFontProbe); injectsCmuxGhosttyConfigPathResolver. - App’s C-API config-loaders remain and now delegate to the new type while performing
ghostty_config_*calls. - Preserves behavior: same scan-path ordering, legacy size rule, include semantics, CJK ranges, and theme override text.
- Added 17 unit tests with in-memory fakes and small C stubs; wired
CmuxGhosttyConfigLoaderintocmux.xcodeproj.
- Moved: CJK font fallback, user font-config scanning (with includes), scan-path resolution, legacy-config decisions, and theme override/managed default appearance into