diff --git a/docs/adr/0053-contextual-hint-command-and-keybinding.md b/docs/adr/0053-contextual-hint-command-and-keybinding.md index 9bf6ddf..fdef8b6 100644 --- a/docs/adr/0053-contextual-hint-command-and-keybinding.md +++ b/docs/adr/0053-contextual-hint-command-and-keybinding.md @@ -113,7 +113,7 @@ into the output journal. (It must therefore be handled in `handle_key` | Trigger | Buffer / state | Result | |---|---|---| -| **F1** | non-empty input | tier-3 hint for the command being typed, plus the live "expected next" (from the walker's `tail_expected` / parser `expected`) | +| **F1** | non-empty input | tier-3 hint for the command being typed. (No "expected next" line — the always-on tier-2 ambient panel already shows it live; tier-2 owns position-awareness.) | | **F1** | empty input, a recent error exists | tier-3 expansion of that error | | **F1** | empty input, no recent error | a short "getting started" pointer (press F1 while typing a command; `help` for the full list) | | **`hint`** (submitted) | a recent error exists | tier-3 expansion of that error (primary use) | @@ -205,14 +205,17 @@ mechanics (e.g. `quit`); `what` + `example` are always present. ### D4 — Rendering -Both surfaces render through one new renderer, `App::note_hint*` (sibling -of `note_help`/`note_help_topic`, `src/app.rs`), emitting a small framed -block into the `output` buffer as `OutputKind::System` with -`OutputStyleClass::Hint` on the `what`/`concept` prose and `Neutral` on -the `example` line. The block is **persistent** (scrolls in the journal), -unlike the transient ambient panel — pressing F1 is an explicit request -to *keep* the deeper guidance on screen. The bottom keybinding strip -(ADR-0051) advertises F1 in the editing/typing state. +Both surfaces render through the `App::note_hint*` family (sibling of +`note_help`/`note_help_topic`, `src/app.rs`) via `emit_tier3_block`, +emitting into the `output` buffer as `OutputKind::System`: a **`Hint` +heading** followed by aligned **`What:` / `Example:` / `Concept:`** lines +(labels + heading from `hint.block.*`). The `concept` line is muted +(`OutputStyleClass::Hint`); the rest are plain. The block is +**persistent** (scrolls in the journal), unlike the transient ambient +panel — pressing F1 is an explicit request to *keep* the deeper guidance +on screen. Its rendered shape is locked by an `insta` snapshot +(`hint_block_insert`). The bottom keybinding strip (ADR-0051) advertises +F1 in the editing (leading) and default states. ### D5 — "Most recent (runtime) error" state @@ -278,32 +281,31 @@ maintainer owns, content is produced in two stages: **reviewable batches** (grouped by area: DDL, DML, app commands, error classes), not one monolithic drop. -### Exemplars (the style reference to approve) +### Exemplars (the style reference; shipped as the rendered format) -**Command (F1 live-input), `insert`:** +**Command (F1 live-input), `insert`** (the rendered shape, locked by the +`hint_block_insert` snapshot — a `Hint` heading + aligned labels, no +`Next:` line since tier-2 owns position-awareness): ``` -Hint — insert +Hint What: Add one or more rows to a table. - Example: insert into Customers values ('Ann', 'ann@x.io') + Example: insert into Customers values ('Ann', 'ann@example.io') Concept: A row is one record; each value lines up with a column, in order. Columns typed serial/shortid fill themselves — leave them out. - Next: a value list `(...)`, or `(col, ...) values (...)` to name columns ``` -(The "Next:" line is the live expected-set from the walker, shown only on -the non-empty-input F1 path.) **Error (`hint` command), foreign-key child-side violation:** ``` -Hint — no parent row to point at - What: The value you inserted into Orders.customer_id doesn't match - any Customers row, so the foreign key has nothing to point at. - Example: First insert into Customers values ('Ann', ...) - Then insert into Orders values (..., 'Ann') +Hint + What: The value you gave for the child column doesn't match any + parent row, so the foreign key has nothing to point at. + Example: First insert the parent (insert into Customers …), then the + child that references it. Concept: A foreign key is a promise that every child points at a real - parent. The parent must exist first. To allow orphans on + parent, so the parent must exist first. To allow orphans on delete instead, set the relationship's `on delete` to `set null` or `cascade`. ``` @@ -311,7 +313,7 @@ Hint — no parent row to point at **Command (F1 live-input), `add 1:n relationship`:** ``` -Hint — add relationship +Hint What: Link two tables so a parent row can own many child rows. Example: add 1:n relationship from Customers.id to Orders.customer_id Concept: The "1:n" means one parent, many children. The child column diff --git a/src/app.rs b/src/app.rs index f62da1f..5750535 100644 --- a/src/app.rs +++ b/src/app.rs @@ -3205,17 +3205,32 @@ impl App { /// polish (the framed block) lands with the corpus. fn emit_tier3_block(&mut self, stem: &str) -> bool { let cat = crate::friendly::catalog(); - if cat.get(&format!("{stem}.what")).is_none() { + let what_key = format!("{stem}.what"); + if cat.get(&what_key).is_none() { return false; } - self.note_system(crate::friendly::translate(&format!("{stem}.what"), &[])); + // Labelled block (ADR-0053 D4): a `Hint` heading, then aligned + // `What:` / `Example:` / `Concept:` lines. `concept` renders + // muted (`OutputStyleClass::Hint`); the rest are plain system. + let labelled = |label: &str, value: &str| { + // Pad `