Skip to content

[feat] tui: flexoki and flexoki-light themes - #177

Closed
gogoout wants to merge 5 commits into
fix/157-stock-palettesfrom
feat/flexoki
Closed

gogoout wants to merge 5 commits into
fix/157-stock-palettesfrom
feat/flexoki

Conversation

@gogoout

@gogoout gogoout commented Sep 26, 2026

Copy link
Copy Markdown
Member

Stacked on #176, which is stacked on #175. Retarget this PR to main before merging it, after #176 is merged. A squash merge into the Monokai branch would strand it there.

What changes

  • Two new themes: flexoki and flexoki-light, Steph Ango's Flexoki (MIT). There are now thirteen themes.
  • Bundled syntax themes. two-face does not ship Flexoki, so both syntax themes are bundled .tmTheme files, the mechanism from ADR 0040. They are written here from Flexoki's published palette and generated from one table, so both use the same token colours. Both credit Flexoki in their headers.
  • Seeds: Flexoki's 400 accents on the dark ground (#100F0F), and its 600 accents on paper (#FFFCF0).
  • Five inks moved to pass the legibility tests. Each seed file records the number that forced it:
    • Dark: the red #D14D41 (4.42:1) and the blue #4385BE are lifted, with hue kept. The blue fell to 2.81:1 when muted for a foreign hunk.
    • Light: the green #66800B (4.39:1) and the yellow #AD8301 (3.39:1) are darkened.
    • The light green also turns 4° toward green. The reviewed mark is this green made 0.10 darker, and Flexoki's own hue cannot reach the 0.10 chroma floor in sRGB at that lightness.
  • Search fill: Flexoki's orange on dark and its 400 yellow on light, so the fill differs from the skim tier's colour.

Docs

  • Every theme list is updated: both READMEs, docs/cli.md, spec/tui.md and spec/consumers.md.
  • Gallery entries are added, and ADR 0040 notes the two Flexoki themes.
  • assets/themes.sh records them. assets/themes/flexoki.png and flexoki-light.png are new.

Tests

  • cargo test, clippy -D warnings and fmt are clean.
  • The legibility, chroma, distinctness and own-colour tests run over both new themes.
  • The config tests and the theme dropdown test cover the two new names; the G key now lands on flexoki-light.
  • Privacy sweep of the diff and commit message: clean.

@gogoout

gogoout commented Sep 26, 2026

Copy link
Copy Markdown
Member Author

@claude review

@claude

claude Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Claude finished @gogoout's task in 2m 11s —— View job


Review of flexoki / flexoki-light themes

  • Gather context (diff vs origin/feat/monokai-pro, read CLAUDE.md rules)
  • Read changed files (theme seeds, config, docs, ADR, tests)
  • Check legibility/contrast claims and test coverage
  • Check docs/spec/ADR consistency
  • Post review feedback

Verification limitation: this sandbox required approval for every non-trivial shell command (cargo test, cargo clippy, even python3), and none was granted, so I could not execute the test suite, clippy/fmt, or independently recompute the contrast numbers. The review below is from reading the diff and the existing derive/test machinery in crates/tui/src/theme/mod.rs. Please confirm CI is green before merging.

Overall

Clean, well-scoped addition that follows the established seed/derive pattern exactly (compare flexoki.rs/flexoki_light.rs against the existing monokai.rs). Nothing here reaches for a new abstraction, and the bundled-.tmTheme mechanism is exactly ADR 0040's escape hatch, used the way monokai already uses it.

  • crates/tui/src/theme/flexoki.rs / flexoki_light.rs: seeds are commented with the same discipline as the rest of the palette set — each ink shift states the measured contrast that forced it and that hue/chroma were kept, which is exactly what derive's test suite (every_theme_is_legible_on_its_own_ground, a_semantic_ink_is_tellable_from_ordinary_text, a_search_hit_is_readable_and_unmistakable) checks for every theme in ALL. Since both new variants are folded into that array via ThemeName::Flexoki/FlexokiLight, they get the full legibility/chroma/distinctness battery for free — no bespoke tests needed.
  • crates/tui/src/theme/mod.rs: Flexoki/FlexokiLight are appended after Monokai (not alphabetically inserted), matching the "adding a theme is adding a variant" convention elsewhere — and crates/tui/tests/tui.rs was correctly updated so the G-key-cycles-to-last-theme test now expects FlexokiLight instead of Monokai.
  • crates/engine/src/config.rs: ThemeName enum and its round-trip/name tests were extended consistently; the "list every valid name in the error message" test (user_config_parses_the_theme_and_names_the_valid_ones) already includes flexoki/flexoki-light.
  • Docs (README.md, crates/tui/README.md, docs/cli.md, spec/tui.md, spec/consumers.md) and adr/0040...md are all bumped from "eleven" to "thirteen" and list the two new names — I didn't find a stale "eleven" or missing mention anywhere in the diff.
  • assets/themes.sh / assets/theme.vhs: theme list and comments updated in step; new flexoki.png/flexoki-light.png screenshots added.

Minor observations (non-blocking)

  • Both bundled .tmTheme files set findHighlight/findHighlightForeground (e.g. flexoki.tmTheme:32-35), but nothing in derive() reads those keys — the reviewer's own highlight_bg/highlight_fg come from the seed's highlight field, not the syntect theme's find-highlight. This matches monokai.tmTheme's existing shape, so it's not a regression, just metadata carried for .tmTheme-format completeness rather than something consumed. Worth double-checking it wasn't meant to line up with seed.highlight (dark seed uses Flexoki's orange #DA702C, while the bundled file's findHighlight is the yellow #D0A215) — but since it's inert, it's cosmetic at most.
  • The PR body's own note stands out and matters: this branch targets feat/monokai-pro, not main — it must be retargeted after [feat] tui: monokai wears Monokai Pro's palette #176 merges, or a squash merge would strand it on that intermediate branch per the stacking note.

Nothing else jumped out as incorrect. The contrast/chroma deltas described in the seed comments (e.g. red 4.42:1 → lifted, green 4.39:1 → darkened, yellow 3.39:1 → darkened) are internally consistent with the direction deepen/mix push things in derive, and the pattern of "measure, then justify the literal in a comment" matches how every other theme in this file already documents its exceptions.

@gogoout

gogoout commented Sep 26, 2026

Copy link
Copy Markdown
Member Author

The findHighlight note is fixed: the two Flexoki files (and monokai.tmTheme, on #176) now name the seed's own search fill. The key stays inert, since derive() reads the fill from the seed. Rebased onto #176.

* [fix] tui: themes take their stock editor colours

The themes felt off beside the stock ones they are named after. An audit
against each theme's official VS Code port found the seeds mostly fine and
three other causes, all fixed here.

- One Dark painted its code with One Half Dark (text #DCDFE4) and Monokai
  with MonokaiExtended (ground #222222). They now use TwoDark and
  MonokaiExtendedOrigin, whose ground and text are the stock ones.
- derive() read only the syntax theme's ground and text. It now takes the
  theme's own selection, line numbers and comment colour, each only where it
  clears the bar the legibility tests hold that field to, with the mix as
  the fallback. The cursor row stays the stronger end of a selection: no
  shipped theme's line highlight is stronger than its selection, so the
  cursor row is the selection one step further from the ground.
- The remaining fractions are fitted to the ports: word emphasis 0.58 ->
  0.80, and the status bar a shade towards black instead of towards the
  text. The line-number fallback is 0.46, the quietest that passes 3:1.

ADR 0039 amends ADR 0024. Two tests hold the new rules. The theme
screenshots are regenerated.

Closes #157

* [fix] tui: derive keeps its doc comment, and noise is held to its own colour

Review follow-up. `derive()`'s doc comment sat above `const WHITE`, and
then above the new `SEEN` too, so rustdoc gave it to a constant. It now
sits directly on `derive`, updated for the theme's own colours.

`a_theme_keeps_its_own_colours_where_they_pass` checked the selection and
the line numbers but not the noise tier, which takes the comment colour on
the same terms. It checks all three now.
@gogoout
gogoout added this pull request to stack #178 September 26, 2026 23:49
Base automatically changed from feat/monokai-pro to fix/157-stock-palettes September 26, 2026 23:49
Classic Monokai, matched to its stock olive ground, reads as green: every
grey mixed from that ground takes the olive, and the yellow-green addition
tint sits right beside it. The `monokai` theme now wears Monokai Pro's
warm-grey palette instead, under the same name, so existing configs keep
working. Classic Monokai is no longer shipped.

two-face does not ship Monokai Pro, so a seed's syntax theme is now a
`Syntax`: a two-face name as before, or a `.tmTheme` compiled into the
crate and parsed by syntect. `monokai.tmTheme` is written here from Monokai
Pro's published palette values alone; no official or ported theme file is
copied, and the crate is not affiliated with Monokai Pro (ADR 0040). Its
blue is lifted to clear the chroma floor, as Dracula's cyan was, and its
orange is the search fill so the fill and the skim tier are two colours.
Review follow-up. derive() takes the search fill from the seed, so the
file's findHighlight is inert, but it said yellow where the seed says
orange. They agree now.
Steph Ango's Flexoki, dark and light. two-face does not ship it, so both
syntax themes are bundled .tmTheme files (ADR 0040), written here from
Flexoki's published palette (MIT) and generated from one table so the
scope mapping is the same in both.

The seeds take Flexoki's 400 accents on the dark ground and its 600
accents on paper. Five inks moved to clear the legibility tests, each
with the number that forced it in the seed file: the dark red and blue
are lifted, and the light green and yellow are darkened. The light green
also turns 4 degrees towards green, because the reviewed mark derived
from it cannot reach the chroma floor in Flexoki's own hue at that
lightness.
Review follow-up, as for monokai.tmTheme: the inert findHighlight key now
names the colour each seed actually fills a search hit with.
@gogoout

gogoout commented Sep 26, 2026

Copy link
Copy Markdown
Member Author

Superseded: GitHub cannot change the base of a stacked PR, and this one targeted the branch #176 was merged into. The same commits are rebased onto #179 in the replacement PR.

@gogoout

gogoout commented Sep 26, 2026

Copy link
Copy Markdown
Member Author

Replacement: #180.

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