Skip to content

Feat/color scheme switcher#60

Merged
mabd-dev merged 31 commits into
mainfrom
feat/colorSchemeSwitcher
Jun 20, 2026
Merged

Feat/color scheme switcher#60
mabd-dev merged 31 commits into
mainfrom
feat/colorSchemeSwitcher

Conversation

@mabd-dev

@mabd-dev mabd-dev commented Jun 20, 2026

Copy link
Copy Markdown
Owner

Pull Request

Description

Introducing colorScheme switcher popup

Changes Made

  • Added new tui/colorschemeswitcher package
  • Launch colorScheme switcher using ctrl+t command
  • Switch colorScheme and save to config.toml

Testing

  • Tested locally with example workflows
  • Added new tests (if applicable)
  • Tested with different filters, output, etc...

Screenshots (if applicable)

Screenshot 2026-06-20 at 06-39-46

Checklist

  • I have starred the repository
  • My code follows the project's code style
  • I have updated the documentation (README, cli-flags, etc...)
  • My changes generate no new warnings
  • I have tested my changes in a real workflow
  • All tests pass locally

Greptile Summary

This PR adds a color scheme switcher popup (ctrl+t) that lets users browse base24 schemes, filter by name, and persist the selection to config.toml. It also refactors path resolution — home-directory joining now lives exclusively in GetConfigFullPath — and propagates UpdateTheme calls to all sub-models when a scheme is changed at runtime.

  • Color scheme switcher (internal/render/tui/colorschemeswitcher): new Bubble Tea sub-model with text-input filtering, table display with color swatches, and selectedSchemeID (slug-based) state, backed by a comprehensive test suite.
  • Config path fix: CreateOrReadConfigs now accepts a full absolute path; callers resolve it via GetConfigFullPath(), eliminating the previous implicit home-dir prepend.
  • Theme propagation: repostable, repodetails, and alerts all gain UpdateTheme methods called by the parent on scheme change; the previously-flagged repeated-write bug is fixed by comparing slug IDs on both sides of the schemeID != m.theme.Colors.ID guard.

Confidence Score: 4/5

Safe to merge with one display correctness fix: the "[current]" marker in the scheme list compares display names instead of slugs, which can highlight the wrong row when multiple variants of a theme share a display name.

The repeated-config-write bug from the prior review is resolved, path resolution is cleaner, and the tests are thorough. One issue remains in createRows: the active-scheme indicator uses name == t.Colors.Name (display name) rather than s.id == t.Colors.ID (slug). Base24 scheme collections commonly include dark/light variants of the same scheme name, so this can mark two rows as "[current]" simultaneously, misleading the user about which theme is actually loaded.

internal/render/tui/colorschemeswitcher/ui.go — the createRows function's current-scheme detection logic.

Important Files Changed

Filename Overview
internal/render/tui/colorschemeswitcher/ui.go New file implementing table rows and color swatches; the "[current]" marker uses display-name equality instead of scheme ID, which can produce false positives for schemes that share a name but differ only by variant.
internal/render/tui/update.go Adds updateColorSchemeSwitcher; previously-flagged repeated-write bug is now fixed by comparing IDs (selectedSchemeID vs m.theme.Colors.ID) on both sides of the check.
internal/render/tui/colorschemeswitcher/main.go New package entrypoint; initialises model with selectedSchemeID = t.Colors.ID (slug-based), aligns correctly with the rest of the selection logic.
internal/render/tui/colorschemeswitcher/update.go Handles keyboard routing between table and text-input focus modes; selection stores scheme ID directly from colorSchemeData, not a name string.
internal/theme/loader.go Adds LoadBase24Schema (raw struct), splits LoadBase24 (mapped ColorScheme with ID/Name fields), no functional regressions.
internal/config/loader.go Adds public UpdateConfigs wrapper; CreateOrReadConfigs now accepts a full absolute path, home-dir joining moved to GetConfigFullPath in paths.go — cleaner separation of concerns.
internal/config/paths.go Adds GetConfigFullPath() which performs the home-dir join once; removes implicit home-dir prepending from CreateOrReadConfigs.
internal/render/tui/colorschemeswitcher/colorschemeswitcher_test.go Comprehensive test suite covering New, Init, Reset, UpdateTheme, table navigation, text-input filtering, row creation, and View rendering.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant User
    participant TUI as tui.Model
    participant CSS as colorSchemeSwitcher.Model
    participant ThemePkg as theme package
    participant Config as config package

    User->>TUI: ctrl+t
    TUI->>TUI: pushFocus(FocusThemeSwitcher)

    User->>TUI: keypress (nav / filter / enter)
    TUI->>CSS: Update(msg)
    CSS-->>TUI: (updatedModel, cmd)

    alt WantsClose()
        TUI->>TUI: popFocus(true)
    else "selectedSchemeID != m.theme.Colors.ID"
        TUI->>ThemePkg: CreateColors(schemeID)
        ThemePkg-->>TUI: newColors
        TUI->>Config: UpdateConfigs(configs, fullPath)
        Config-->>TUI: err
        TUI->>TUI: "m.theme = Theme{newColors, CreateStyles}"
        TUI->>CSS: UpdateTheme(newTheme)
        TUI->>TUI: reposTable.UpdateTheme / repoDetails.UpdateTheme / alerts.UpdateTheme
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant User
    participant TUI as tui.Model
    participant CSS as colorSchemeSwitcher.Model
    participant ThemePkg as theme package
    participant Config as config package

    User->>TUI: ctrl+t
    TUI->>TUI: pushFocus(FocusThemeSwitcher)

    User->>TUI: keypress (nav / filter / enter)
    TUI->>CSS: Update(msg)
    CSS-->>TUI: (updatedModel, cmd)

    alt WantsClose()
        TUI->>TUI: popFocus(true)
    else "selectedSchemeID != m.theme.Colors.ID"
        TUI->>ThemePkg: CreateColors(schemeID)
        ThemePkg-->>TUI: newColors
        TUI->>Config: UpdateConfigs(configs, fullPath)
        Config-->>TUI: err
        TUI->>TUI: "m.theme = Theme{newColors, CreateStyles}"
        TUI->>CSS: UpdateTheme(newTheme)
        TUI->>TUI: reposTable.UpdateTheme / repoDetails.UpdateTheme / alerts.UpdateTheme
    end
Loading

Comments Outside Diff (1)

  1. internal/render/tui/update.go, line 1283 (link)

    P1 Slug vs. display-name mismatch causes repeated config writes

    m.colorSchemeSwitcher.SelectedSchemeName() returns the scheme slug (e.g., "catppuccin-mocha", sourced from theme.Schemes), while m.theme.Colors.Name holds the display name parsed from the YAML name field (e.g., "Catppuccin Mocha"). These two strings are never equal, so after a user selects a theme the condition schemeName != m.theme.Colors.Name remains permanently true. On every subsequent keypress while the switcher is open, theme.CreateColors, config.DefaultPaths().GetConfigFullPath(), and config.UpdateConfigs are all called again, causing repeated config-file writes.

    The fix is to compare against the same domain: either update selectedSchemeName inside UpdateTheme to the new newTheme.Colors.Name, or compare against m.configs.Output.ColorSchemeName (which is already the slug).

Reviews (3): Last reviewed commit: "add ID to ColorScheme struct" | Re-trigger Greptile

@mabd-dev mabd-dev added this to the V 1.5.0 milestone Jun 20, 2026
@mabd-dev mabd-dev added enhancement New feature or request ui labels Jun 20, 2026
Comment thread internal/render/tui/colorschemeswitcher/update.go
Comment thread README.md Outdated
Comment thread internal/render/tui/colorschemeswitcher/types.go Outdated
Comment thread internal/config/loader.go Outdated
@mabd-dev

Copy link
Copy Markdown
Owner Author

@greptile-ai

@mabd-dev

Copy link
Copy Markdown
Owner Author

@greptile-ai

@mabd-dev mabd-dev merged commit da1ad1f into main Jun 20, 2026
4 checks passed
@mabd-dev mabd-dev deleted the feat/colorSchemeSwitcher branch June 20, 2026 05:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request ui

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant