Skip to content

TUI: the contextual key line is too dense, mode-blind, and mixes three label formats - #114

Merged
MJohnson459 merged 1 commit into
mainfrom
feat/keymap-overlay
Aug 1, 2026
Merged

TUI: the contextual key line is too dense, mode-blind, and mixes three label formats#114
MJohnson459 merged 1 commit into
mainfrom
feat/keymap-overlay

Conversation

@MJohnson459

Copy link
Copy Markdown
Contributor

Settle one label convention for the TUI's contextual key line, and add the ?
key map that lets the line get shorter without making keys undiscoverable.

One convention. d/D, r/R and n/N are each a lowercase default
and an uppercase variant of one action, and the line rendered that three
different ways. They now take a single slot keyed on the pair and labelled with
the base verb — d/D dispatch, r/R refine, n/N new. The projects screen's
a/A and the Config screen's a/A stay apart: unrelated actions that
happen to share a letter. No key is rebound.

A ? key map. A new Mode::KeyMap, opened by ? and dismissed by any key,
renders the current screen's complete bindings in a popup — actions in one
column, navigation over screen switching in the other, so the cockpit's map fits
80x24 without clipping. It is bound in key_normal's shared navigation block
rather than the trailing match, so it also reaches the projects and Config
screens, which intercept before that match. It documents every key that had no
hint at all (o, g, a, l, J/K, PageUp/PageDown, ctrl-r, j/k,
1-4, ?) and the three uppercase glosses the line no longer carries; those
glosses live together in DISPATCH_KEYS/REFINE_KEYS/NEW_KEYS, worded to one
shape, so the follow-up below can rewrite them in one place.

A shorter line. With the map in place the line keeps only what changes a
task's state or destiny. x score, h history and c docs come off it as the
task specified, and so does l log: paging a log in $PAGER is a browsing
convenience by the same rule, and without dropping it a review row carrying a
session log reached eleven slots. The worst case is now exactly ten, on both the
proposal row and the review row.

Drift guard. key_hints is now a filter over a new hint_candidates, which
lists every slot a screen can show together with whether the selection earns it.
That is what makes the guard test total: it checks every candidate — gated slots
included — against that screen's key_map, splitting combined slots so d/D is
checked as d and D. A future trim of the line fails the test if it drops a
key the map does not carry.

Docs. DESIGN.md §9 gains a paragraph on the convention, on which pairs
combine and which do not, and on the ? overlay as the full map. The
ui-redesign §2 citation on key_hints — a document that does not exist in
this repo — now points at §9, and the doc comment that had drifted onto
selection_is_proposed is back on key_hints. CHANGELOG entries added under
Added and Changed.

Also. App::selected_session_log went with the l hint it existed to gate;
view_session_log never used it, and the two tests that called it assert the
same thing a line away.

Verified. cargo test --workspace (556 tests) and cargo clippy --workspace --all-targets -- -D warnings are clean. New tests: the overlay opens on ?
from a screen whose own handler intercepts (projects), renders that screen's map
including the keys the line dropped, and closes on a key the screen binds; the
line stays at ten slots or fewer on every row of a queue holding a proposal, a
ready task and a review task; and every hintable key appears in its screen's
map. Beyond the tests I rendered all four screens' overlays through the real
draw path at 80x24 and read them.

Follow-up filed as #333 — decide what lowercase and uppercase actually mean
and audit every uppercase binding against it, carrying the exceptions (d
spawns agents while lowercase; r's accidental backgrounded session from #325;
#315's proposed n/N flip; the non-spawning uppercase keys). It may rebind
keys, which this task deliberately did not.

Branch feat/keymap-overlay is local and unpushed.

The contextual key line had grown to fourteen slots on the cockpit and
rendered the same idea three ways: `d dispatch · D agent`, `n new · N
plan`, and `r/R refine`. Settle on the combined form — one slot per
lowercase/uppercase pair of a single action, labelled with the base verb
— and give the uppercase glosses somewhere to live, since the line
cannot carry them.

`?` opens a per-screen key map: a peek-style overlay dismissed by any
key, listing every binding that screen has, grouped into actions,
navigation, and screen switching. It documents the keys no hint has ever
carried (`o`, `g`, `a`, `l`, `J`/`K`, the page keys, `ctrl-r`, `1`-`4`)
and the three uppercase variants, each worded to say what the shifted
key does differently from its sibling. `?` is bound in the shared
navigation block so it also reaches the projects and Config screens,
which intercept before the trailing match.

With the map in place the line keeps only what changes a task's state or
destiny: `x` score, `h` history, `c` docs and `l` log come off it. No
key is rebound, and the worst-case cockpit line is now ten slots.

`key_hints` is now a filter over `hint_candidates`, which lists every
slot a screen can show with a flag for whether the selection earns it —
that is what lets the drift test check the whole set, gated slots
included, against the screen's key map from a single App.
@MJohnson459
MJohnson459 force-pushed the feat/keymap-overlay branch from eea7717 to 7e489ba Compare August 1, 2026 20:07
@MJohnson459
MJohnson459 merged commit a1ce3ee into main Aug 1, 2026
6 checks passed
@MJohnson459
MJohnson459 deleted the feat/keymap-overlay branch August 1, 2026 20:10
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