fix: advanced CREATE TABLE completion cluster

Three completion / hint bugs in the same advanced-mode grammar
+ walker path:

1. `create table T ` offered only `with` (the DSL fallback) — the
   `(` continuation for the SQL column-def list (ADR-0035 §4) was
   missing because the shared-entry-word completion merge in
   `completion_probe_in_mode` only fired at the entry-word boundary.
   Broadened to fire at any cursor depth and to handle
   `Expectation::Punct` continuations alongside `Word`/`Literal`. A
   shared-entry-word candidate whose grammar has already diverged
   (e.g. SQL `CREATE INDEX` past `create table …`) returns
   Mismatch and is naturally skipped — the viability check stays the
   gate, not the cursor depth.

2. `create table T (` showed only the table-level constraint
   keywords (`primary`, `unique`, `check`, `constraint`, `foreign`)
   in the ambient hint, leaving the column-name role invisible
   because COLUMN_DEF starts with an `Ident::NewName` slot that
   produces no concrete candidate. Added a new `HintMode::IntroProse(
   &'static str)` variant that surfaces catalog prose at slot entry
   without suppressing Tab completion (unlike `ProseOnly`) and
   without requiring `typing_name_at_cursor` to fire (unlike
   `ForceProse`). Wrapped ELEMENT in `Node::Hinted { mode: IntroProse(
   "hint.create_table_element"), … }`, with prose "Type a column
   name, or a table-level constraint: `primary`, `unique`, `check`,
   `constraint`, `foreign`". Tab still cycles every keyword.

3. The SQL_TYPE position leaked the bare keyword `double` (the
   first token of the dedicated `double precision` Choice branch
   per ADR-0035 §6.3) alongside the playground's regular type list.
   Added `("double", "double precision")` to `COMPOSITE_CANDIDATES`
   and extended the keyword filter to drop composite openers so the
   composite phrase replaces the bare opener instead of appearing
   alongside it. Tab now offers `double precision` as a single
   coherent candidate; the partial-typing prose at the same slot is
   subsumed by item 2's IntroProse (the user reads "Type a column
   name…" while mid-typing, then advances to the clean type list).

Tests added (4): pinning each behavioural promise above plus the
no-leakage assertion at the partial-typing prose position. Full
suite 2035 passed / 0 failed / 0 unexpected skips. Clippy clean.

The new `HintMode::IntroProse` variant is an additive extension to
the ADR-0024 HintMode-per-node model; no behaviour change to
existing modes. An ADR-0024 amendment recording it can follow later
if desired — flagged but not written.
This commit is contained in:
claude@clouddev1
2026-05-28 18:56:13 +00:00
parent c12ed1da9a
commit 6f87ad1842
7 changed files with 259 additions and 35 deletions
+4
View File
@@ -211,6 +211,10 @@ pub const KEYS_AND_PLACEHOLDERS: &[(&str, &[&str])] = &[
&["kind", "found"],
),
("hint.ambient_typing_name", &[]),
// Issue #4: introduce the advanced-mode CREATE TABLE element
// slot (`create table T (`) so the otherwise-invisible
// column-name role reads as the dominant first move.
("hint.create_table_element", &[]),
("hint.value_literal_slot", &[]),
(
"hint.ambient_typing_name_then",
+4
View File
@@ -357,6 +357,10 @@ hint:
# falls through to `ambient_typing_name` instead.
ambient_typing_name: "Type a name"
ambient_typing_name_then: "Type a name, then {next}"
# Issue #4 — advanced-mode CREATE TABLE element slot. Surfaced
# at `create table T (` so the column-name role is visible
# alongside the table-level constraint keywords.
create_table_element: "Type a column name, or a table-level constraint: `primary`, `unique`, `check`, `constraint`, `foreign`"
# Value-literal slot — `insert ... values (`, `update ... set
# col=`, `where col=`. Replaces the misleading "null true
# false" keyword candidate list with format guidance for all