Skip to content

feat(colors): replace palette roles under [colors] - #105

Merged
backnotprop merged 2 commits into
plannotator:mainfrom
nxxxsooo:feat/colors
Oct 23, 2026
Merged

backnotprop merged 2 commits into
plannotator:mainfrom
nxxxsooo:feat/colors

Conversation

@nxxxsooo

Copy link
Copy Markdown
Contributor

Implements the colors half of #58, building on the theme.rs palette from #85 as suggested there.

[colors]
heading = "#89b4fa"
accent = "light-blue"
block = "236"
selection = "#45475a"
  • [colors] in config.toml: a role replaces that colour in whichever palette is in force (light or dark, after PLANNOTATOR_TUI_THEME, [ui] theme and detection have picked one). Roles left out keep today's values, so an empty table changes nothing.
  • Roles: accent, heading, comment, looks-good, delete, comment-bg, looks-good-bg, block, toolbar, cursor, selection. block covers the focused block and the focused tree row, per @alesch's notes.
  • Colour strings are ratatui's: names (yellow, light-cyan), indexes (238), #rrggbb.
  • Strict: an unknown role or an unreadable colour is an error that names it (unknown color "chartreuse"; expected a name like yellow, an index 0-255, or #rrggbb).
  • plannotator-tui config prints the roles that are set.
  • README: a [colors] block listing every role with its dark default.

Shape

  • Palette gains the foreground roles that were inline Color::Cyan / Yellow / Green / Red constants in draw.rs, layout.rs, header.rs, menu.rs, pick.rs and archive_view.rs. Both palettes share them, since ANSI colours already follow the terminal.
  • Palette::with(&Colors) applies overrides; install stores the result in the OnceLock (an owned Palette now, not &'static).
  • run_ui loads the config once for both theme and colours. A config that fails to parse still falls back to defaults, as before.

For review

  • heading sets every level. Today h1/h2 are Cyan and h3+ LightCyan, so internally they're heading/subheading; I left subheading out of the config to keep the role list small. Happy to expose it.
  • A configured cursor or selection is a plain background. The dark selection's REVERSED and the light cursor's white glyph would otherwise fight a colour picked to match a theme.
  • The header's send/sent/blocked buttons set their own fg and bg, so I left them alone.
  • This touches config.rs and cli.rs, as feat(keys): rebind every key under [keys] #104 does. The overlap is small: one field each, and the run_ui config load.

Motivation: I maintain an OpenCode plugin that opens plannotator-tui for /annotate. It already passes PLANNOTATOR_TUI_THEME from OpenCode's light/dark mode. With [colors] and PLANNOTATOR_TUI_CONFIG it can pass the active OpenCode theme's colours too.

Testing: cargo test --workspace (320 pass; new unit tests in theme.rs and config.rs, plus an integration test that config prints the set roles), cargo clippy --workspace --all-targets clean, cargo fmt --all --check. Checked by hand in tmux: headings at every level and the focused block render in the configured truecolor values.

nxxxsooo and others added 2 commits October 23, 2026 14:30
… spells them

- heading = 238 reads like heading = "238"
- plannotator-tui config prints light-blue, 238 and #rrggbb instead of ratatui's names
- the archive's selected row reverses the accent so its text stays readable
@backnotprop
backnotprop added this pull request to the merge queue Oct 23, 2026
@backnotprop

Copy link
Copy Markdown
Contributor

Thanks @nxxxsooo, nice work. I rebased it onto [keys] and pushed a small follow-up: a bare index like heading = 238 now parses, plannotator-tui config prints colors as the config spells them (light-blue, 238, #rrggbb), and the archive's selected row stays readable with a custom accent.

Merged via the queue into plannotator:main with commit b46fd91 Oct 23, 2026
3 checks passed
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.

2 participants