feat: give column data types a dedicated syntax-highlight colour

Both Node::Ident and Word carried a highlight_override field, and
both were dead — the walker driver discarded the Ident's and
walk_word hardcoded Keyword. So column types (int, serial, …)
rendered identically to table/column names.

Wire both overrides through, and add a dedicated HighlightClass::Type
with its own theme colour (tok_type), distinct from keyword-purple
and identifier-teal. The three type Ident slots opt in, so canonical
types and the advanced-mode single-word SQL aliases (float, varchar,
…) render as types; the two-word `double precision` alias opts in via
a new Word::type_keyword constructor. ADR-0022 Amendment 4.
This commit is contained in:
claude@clouddev1
2026-05-29 22:07:18 +00:00
parent 46a31284c5
commit d20f765325
10 changed files with 195 additions and 13 deletions
@@ -587,6 +587,61 @@ guard above, and three re-baselined `typing_surface` snapshots
(`form_a_in_progress_one_value`, `form_b_too_few_values`,
`form_c_wrong_count`).
## Amendment 4 — Column types get a dedicated highlight class (2026-05-29)
§3 introduced **seven** token-class colour fields and the matching
`HighlightClass` enum. Column data-type keywords (`int`, `serial`,
`text`, …) had no class of their own: the walker driver hardcoded
`HighlightClass::Identifier` for every matched `Node::Ident`, so a
type rendered identical to a table/column name (clause keywords were
already distinct, in `tok_keyword`). A user-reported bug (issue #8)
noted that in `create table Orders (count int, id serial PRIMARY KEY)`
the identifiers and the type keywords were indistinguishably teal.
Both terminal kinds already carried a `highlight_override:
Option<HighlightClass>` field — `Node::Ident` and the `Word` struct
alike — but **both were dead**: the driver destructured the Ident's to
`_`, and `walk_word` hardcoded `Keyword`, neither ever consulting the
field. This amendment wires both through.
**Change:**
1. **New class.** `HighlightClass::Type` (the eighth variant) and a
matching eighth `Theme` field `tok_type`, populated in both
`dark()` and `light()` with a tone deliberately distinct from both
`tok_keyword` and `tok_identifier` (a pink / deep-magenta in the
red-purple range — the only free slot in the existing palette).
`highlight_class_color` maps the new variant.
2. **Overrides are now live.** `walk_ident` emits
`override.unwrap_or(Identifier)` and `walk_word` emits
`override.unwrap_or(Keyword)` for the matched byte range. Every
slot that leaves the field `None` is unchanged.
3. **Type slots opt in.** The three `IdentSource::Types` slots —
`shared::TYPE_SLOT` (`add column` / `change column`), the inline
create-table column-type Ident (`ddl.rs`), and `sql_create_table::
SQL_TYPE_NAME` (advanced) — set `highlight_override: Some(Type)`.
In advanced mode, every single-word SQL type-name *alias*
(`float`, `varchar`, `integer`, … — ADR-0035 §3) flows through
`SQL_TYPE_NAME` and so is type-coloured for free.
4. **`double precision` too.** The lone two-word alias (ADR-0035 §3)
is matched as keyword tokens, not an `IdentSource::Types` Ident, so
it cannot ride rule 3. Its `double` / `precision` grammar nodes use
the new `Word::type_keyword` constructor (`highlight_override:
Some(Type)`) so the spelling renders type-coloured like its
single-word synonyms `float` / `real`.
**Pedagogy:** a dedicated colour (over the lighter option of reusing
`tok_keyword`) lets a learner tell *"this is a type"* from a clause
keyword and from a name they invented — three distinct roles, three
distinct colours.
**Coverage:** `dsl_type_keyword_classified_as_type`,
`advanced_type_keywords_classified_as_type` (the ticket's exact
example), `advanced_double_precision_classified_as_type`,
`type_colour_is_distinct_from_keyword_and_identifier`, and the
extended theme mapping/contrast tests. Text snapshots are colour-blind
(`render_to_string` strips style), so none churned.
## Out of scope
Deliberately deferred to keep this ADR shippable as a single