fix: mode_style matches AppMode exhaustively (improvise-zx8t)

The repo map promises of `AppMode` that "add a variant and the compiler names
every one you must fill in". That was true of the five enum methods and false
of `src/draw.rs::mode_style`, which swept eleven variants into a `_ =>`
wildcard — so `SavePrompt` took `ExportPrompt`'s DarkGray by accident rather
than by decision, and the next person adding a variant would have trusted the
sentence.

Of the ticket's two options, the first: `mode_style` is now exhaustive and
stays in `draw.rs`, because `Style` is a ratatui type (gotcha 26). The second —
a semantic colour method on `AppMode` in `improvise-protocol`, the
`AxisColor`/`MinibufColor` shape — is NOT taken here, and deliberately: the
ticket says to decide it together with improvise-k099, which asks the same
question of `hint_text`/`label` and is not in this unit. The repo map's promise
needed exhaustiveness; the semantic enum is a separate, larger answer and stays
open.

No colour changes. The fourteen default-chrome variants are spelled out with
the DarkGray they already had, so this is the wildcard becoming a list.

The guard is the compiler, not a test — a test enumerating today's variants
would not fail when a fifteenth is added. Verified by deleting the
`AppMode::Help` arm:

    error[E0004]: non-exhaustive patterns: `&AppMode::Help` not covered

Also removes the doc comment calling the wildcard "a known defect", which this
commit makes false, and updates `context/code/tui.md`, which said the same.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FC2jVn8Au7E9JPkw6bwXXH
This commit is contained in:
Edward Langley
2026-09-20 20:40:28 -07:00
parent 17e59335eb
commit fc059c7ce1
2 changed files with 49 additions and 15 deletions
+28 -5
View File
@@ -121,11 +121,34 @@ enum, and only the last translation is local.**
`mode_style(&AppMode) -> Style` stays here for the same reason (`Style` and
`Color` are ratatui types and `improvise-command`, where `AppMode` lives,
carries no rendering-framework dependency) — **but it is not the same shape.**
It matches on `AppMode` directly with a `_ =>` wildcard for "the default chrome
for every non-highlighted mode", so a new `AppMode` variant silently inherits
that chrome instead of failing to compile, and there is no semantic enum in the
shared layer to decide it. That is `improvise-zx8t`, filed and not fixed.
carries no rendering-framework dependency), and since `improvise-zx8t` it is
**exhaustive**: the fourteen variants that take the default chrome are spelled
out rather than swept up by a `_ =>` wildcard, so adding an `AppMode` fails the
build here until someone chooses its colour.
It is still not quite the same shape as `axis_fg` and its two siblings, and the
difference is deliberate rather than pending. Those three map a *semantic enum*
the shared layer owns; `mode_style` matches `AppMode` itself, because there is
no `ModeColor`. `improvise-zx8t` offered making one, and it was declined here
for two reasons: the colour is the only thing at stake, and the ticket says to
decide it together with `improvise-k099`, which asks the same question of
`hint_text`/`label` and is not in this unit. Exhaustiveness is what the
repo map's "the compiler names every one you must fill in" promise needed; a
semantic enum is a separate, larger answer and is still open.
**The guard is the compiler, not a test.** Nothing asserts the colours, and a
test enumerating the variants would not fail when a fifteenth is added — only
the missing match arm does. Verified by deleting the `AppMode::Help` arm:
`error[E0004]: non-exhaustive patterns: `&AppMode::Help` not covered`.
### The minibuffer shares the bottom row with the status line
`draw_bottom_bar` used to render the minibuffer *instead of* `draw_status`, so a
status message written while any text-entry mode was open was never drawn
(`improvise-mai9`, and the stranding gotcha 21 describes). `minibuffer_line`
composes both: the prompt and buffer on the left, any pending `status_msg`
right-aligned. The alternatives and why they lost are in
`context/test-evidence/tui.md`.
### The caches are built here, per frame