Skip to content

feat(themes): apply color themes in regular (non-powerline) mode (fg-only) - #607

Open
axisrow wants to merge 3 commits into
sirmalloc:mainfrom
axisrow:feat/regular-mode-themes
Open

axisrow wants to merge 3 commits into
sirmalloc:mainfrom
axisrow:feat/regular-mode-themes

Conversation

@axisrow

@axisrow axisrow commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Addresses the feature half of #604 — applying the built-in theme catalog in regular (non-powerline) mode. The U+E0B0 separator-font fallback (the bug half) is deliberately left for a separate change, so the issue stays open.

The same diff is merged and live-verified in our fork: axisrow#12.

What

Makes the built-in theme catalog usable in regular (non-powerline) mode: a new top-level theme setting cycles the chosen theme's segment palette across widgets as foreground colors.

Semantics

  • theme: "dracula" (any POWERLINE_THEMES name) cycles theme[level].bg[] as widget foregrounds — bg[] is the vivid segment palette, while fg[] holds the dark text colors meant to sit on those segments. ansi16-level bg* names are converted through the existing bgToFg() helper.
  • Explicit per-widget colors win over the theme; the theme beats widget default colors (Feature: use the built-in color themes in non-powerline mode (+ font-safe separator fallback) #604's proposed override semantics). Explicit colors keep their palette slot, so adding one accent doesn't shift the rhythm of the surrounding widgets.
  • Separators and flex separators are not themed and consume no slot (powerline filters them out before indexing — same rule).
  • Merged widgets share one slot; preserves-colors widgets keep their intrinsic ANSI output and still advance the slot — both mirror the powerline renderer.
  • Unset / 'custom' / unknown name → no theming. The level follows colorLevel, using the 16/256/truecolor calibrations already shipped with each theme.
  • Additive optional schema key: old configs parse unchanged, no version bump. ccstatusline set theme <name> / get work through the existing generic allowlist — zero CLI code changes.

Rework: uniform coverage across all themes

  • Tests: a parametrized matrix now covers every POWERLINE_THEMES entry (custom excluded) at every color level 1/2/3 — each theme cycles its bg[] palette through the identical slot rule — plus a guard that every theme ships a non-empty palette at all levels.
  • TUI parity: the theme selector now serves regular mode too (new mode prop): the main menu gains a "Theme" entry (hidden while powerline mode is enabled — powerline has its own picker), with a None entry that clears the setting. The powerline-only "copy theme to widget colors" flow remains powerline-only.
  • CLI validation: validate reports unknown theme names as warnings (valid stays true; warnings array in the --json payload); set theme <name> warns on unknown names while still writing them, so a typo never invalidates a config. No schema change — unknown names keep rendering as a silent no-op.

Verification

  • bun test: all theme/menu/CLI tests green (see note below). Covers cycle order, explicit-wins + slot rhythm, separators unthemed, preserves-colors, merged widgets sharing a slot, unset/'custom'/unknown names, the all-themes × all-levels matrix, the regular-mode selector writes (settings.theme set/clear), and the CLI warning paths.
  • bun run lint clean; bun run build OK.
  • Render check through the built binary with a theme: "dracula", colorLevel: 3 config: uncolored widgets emit exact truecolor codes (38;2;189;147;249, 38;2;248;248;242, …), separators stay unthemed; a theme: "nord" config renders the Nord palette the same way.
  • CLI: validate with an unknown theme → exit 0, OK … (with warnings), machine-readable warnings array listing the known themes; set theme nord → get --json reports "theme":"nord".
  • Live run as the active Claude Code status line (theme set, per-widget colors temporarily removed): all widgets picked up the cycled palette in the real render path; config restored afterwards.

Note: the repo's ink-based TUI tests have pre-existing timing flakiness on a loaded machine — the same tests (ItemsEditor, TerminalWidthMenu, ImportPreviewDialog, UsageLocaleEditor) fail intermittently on a clean checkout too. All tests touched by this PR are deterministic and green.

🤖 Generated with Claude Code

axisrow and others added 2 commits October 11, 2026 22:38
…only

Add a top-level `theme` setting that cycles a POWERLINE_THEMES segment
palette across widgets as foreground colors when powerline is disabled.
The theme's bg[] array is the vivid palette (fg[] holds the dark
text-on-segment colors); ansi16-level bg* names are converted with the
existing bgToFg() helper.

Semantics: explicit per-widget colors win over the theme, theme beats
widget defaults; explicit colors keep their palette slot so the rhythm
of the surrounding widgets is stable. Separators and flex separators
are neither themed nor consume slots; merged widgets share one slot;
preserves-colors widgets keep their intrinsic ANSI output and still
advance the slot - both mirroring the powerline renderer. Unset,
'custom', or unknown names disable theming. Additive optional schema
key - configs written before it parse unchanged (no version bump);
`ccstatusline set theme <name>` works through the existing generic
`set` allowlist with zero CLI changes.

Closes the feature half of sirmalloc#604.

Co-Authored-By: Claude Code <[email protected]>
…CLI warnings

Follow-up to the regular-mode theme feature:

- Parametrized tests: every POWERLINE_THEMES entry (custom excluded)
  cycles its bg[] palette identically at color levels 1/2/3, plus a
  guard that every theme ships a non-empty palette at every level.
- TUI: the theme selector now also serves regular (non-powerline) mode
  via a new mode prop - the main menu gains a Theme entry (hidden while
  powerline is enabled, which has its own picker); None clears the
  setting; the powerline-only "copy theme to widget colors" flow stays
  powerline-only.
- CLI: validate reports unknown theme names as warnings (valid stays
  true, warnings array in --json output), set theme warns on unknown
  names while still writing them - a typo must not invalidate a config.

Co-Authored-By: Claude Code <[email protected]>
Union: the regular-mode theme palette rides on upstream's background
override helper; the fork Theme menu entry survives upstream's
TerminalWidthMenu removal (width screen deleted upstream, Theme kept —
it is this PR's feature); install state joins upstream's
installationState memo with the fork's index-free mainMenuIndex back
navigation; the merged upstream hooks-warning test learns the fork
menu's Theme entry (one extra down on the way in, one extra up on the
way out).

Co-Authored-By: Claude Code <[email protected]>
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