Hint: pedagogical Form-A pointer at Form B's first value slot

Handoff-12 §2.2: Form B `insert into T values (…)` silently skips
auto-generated columns from the value list, so a user who wants to
set a serial/shortid column explicitly could only discover Form A by
reading help. Now the hint at the first Form B value slot appends a
note naming the skipped column(s) and pointing at the explicit-column
form.

hint_resolution_at_input derives the skipped columns from the
post-walk WalkContext (Form B = no user_listed_columns + table has
serial/shortid columns) and reports them on HintResolution; the note
fires only at the first slot so it doesn't repeat at every comma.
ambient_hint composes it onto the per-column prose.
This commit is contained in:
claude@clouddev1
2026-05-15 21:30:03 +00:00
parent bcc5ad2f20
commit f1ff5970bf
12 changed files with 366 additions and 33 deletions
@@ -0,0 +1,33 @@
---
source: tests/typing_surface/insert_form_b.rs
description: "input=\"insert into Customers (Name) values (\" cursor=37"
expression: "& a"
---
Assessment {
input: "insert into Customers (Name) values (",
cursor: 37,
state: IncompleteAtEof,
hint: Some(
Prose(
"for `Name`: Type a quoted string (e.g. 'Alice') or null",
),
),
completion: Some(
Completion {
replaced_range: (
37,
37,
),
partial_prefix: "",
candidates: [
Candidate {
text: "null",
kind: Keyword,
},
],
},
),
parse_result: Err(
"Invalid(at_eof)",
),
}
@@ -0,0 +1,33 @@
---
source: tests/typing_surface/insert_form_b.rs
description: "input=\"insert into Customers values (\" cursor=30"
expression: "& a"
---
Assessment {
input: "insert into Customers values (",
cursor: 30,
state: IncompleteAtEof,
hint: Some(
Prose(
"for `Name`: Type a quoted string (e.g. 'Alice') or null (`id` auto-generated — skipped here; list columns explicitly, e.g. `insert into T (...) values (...)`, to set it.)",
),
),
completion: Some(
Completion {
replaced_range: (
30,
30,
),
partial_prefix: "",
candidates: [
Candidate {
text: "null",
kind: Keyword,
},
],
},
),
parse_result: Err(
"Invalid(at_eof)",
),
}
@@ -9,7 +9,7 @@ Assessment {
state: IncompleteAtEof,
hint: Some(
Prose(
"for `k`: Type an integer (e.g. 42, -7) or null",
"for `k`: Type an integer (e.g. 42, -7) or null (`sid`, `auto` auto-generated — skipped here; list columns explicitly, e.g. `insert into T (...) values (...)`, to set it.)",
),
),
completion: Some(
@@ -9,7 +9,7 @@ Assessment {
state: IncompleteAtEof,
hint: Some(
Prose(
"for `Name`: Type a quoted string (e.g. 'Alice') or null",
"for `Name`: Type a quoted string (e.g. 'Alice') or null (`id` auto-generated — skipped here; list columns explicitly, e.g. `insert into T (...) values (...)`, to set it.)",
),
),
completion: Some(
@@ -0,0 +1,33 @@
---
source: tests/typing_surface/insert_form_b.rs
description: "input=\"insert into Customers values ('Alice', \" cursor=39"
expression: "& a"
---
Assessment {
input: "insert into Customers values ('Alice', ",
cursor: 39,
state: IncompleteAtEof,
hint: Some(
Prose(
"for `Email`: Type a quoted string (e.g. 'Alice') or null",
),
),
completion: Some(
Completion {
replaced_range: (
39,
39,
),
partial_prefix: "",
candidates: [
Candidate {
text: "null",
kind: Keyword,
},
],
},
),
parse_result: Err(
"Invalid(at_eof)",
),
}
@@ -0,0 +1,33 @@
---
source: tests/typing_surface/insert_form_b.rs
description: "input=\"insert into Items values (\" cursor=26"
expression: "& a"
---
Assessment {
input: "insert into Items values (",
cursor: 26,
state: IncompleteAtEof,
hint: Some(
Prose(
"for `Code`: Type a quoted string (e.g. 'Alice') or null",
),
),
completion: Some(
Completion {
replaced_range: (
26,
26,
),
partial_prefix: "",
candidates: [
Candidate {
text: "null",
kind: Keyword,
},
],
},
),
parse_result: Err(
"Invalid(at_eof)",
),
}
@@ -11,7 +11,7 @@ Assessment {
),
hint: Some(
Prose(
"for `Name`: Type a quoted string (e.g. 'Alice') or null",
"for `Name`: Type a quoted string (e.g. 'Alice') or null (`id` auto-generated — skipped here; list columns explicitly, e.g. `insert into T (...) values (...)`, to set it.)",
),
),
completion: Some(