ADR-0022 follow-up r3: identifier colour, NewName hint, "Next:" wording, "type" label
Three fixes from a third round of real testing. 1. **tok_identifier vivid (round-3 #1).** The cool grey-blue from r2 was still too close to theme.fg to register as distinct. Bumped to cyan-teal (#56B6C2 dark / #0F6B76 light) — identifiers are the user's most "special" content and now read that way against keywords (purple), numbers (orange), strings (green), and flags (amber). 2. **"Type a name" hint at NewName slots (round-3 #2).** New `completion::typing_name_at_cursor(input, cursor)` returns `Some(TypingName)` when the cursor sits at — or inside — an `IdentSlot::NewName` position. It probes by substituting a single-letter placeholder identifier and re-parsing to discover what the parser would expect AFTER the name; the hint then reads "Type a name, then `(`" instead of the technical "next: `(`" that surfaces once the partial identifier has been consumed by the live parser. When the probe yields nothing useful (custom errors with empty expected, or a complete-on-substitute case), falls back to "Type a name". New catalog keys hint.ambient_typing_name and hint.ambient_typing_name_then. Wired into ambient_hint between the candidate-list and invalid-ident checks. 3. **"Next:" instead of "expected:" wording.** "Expected" read as a leaked diagnostic; "Next:" is shorter, conversational, and consistent with the action-oriented voice of "Submit with Enter" and "Type a name". Hint sentences now also start capitalised (Submit/Next/Type/No-such), per the user's Capital-T-on- "type a name" preference. 4. **type_keyword labelled "type".** Without a label, the `select_ref!` over an Identifier token produced `RichPattern::SomethingElse`, which rendered as the meaningless "something else" in the hint after `(`. Labelled now: error reads "Next: type" — terse but honest. The label is applied BEFORE try_map (not after, not via as_context) so the existing custom-error wording for unknown types ("unknown type 'varchar' (expected one of: …)") still surfaces unchanged. Tests: 755 passing, 0 failing, 1 ignored (no net change — +5 typing_name cases, -0 net since one test was reworded for capitalisation rather than added). Clippy clean. Smoke probe verifies: "add column to table T: " → "Type a name, then `(`"; "add column to table T: Name (" → "Next: type"; "show data Custp" → "No such table: `Custp`"; valid input → "Submit with Enter". Note for next testing round: parser-side custom errors (e.g. the "tables need at least one column" message that fires for `create table Customers `) still read in lowercase — they're hand-written in parser.rs source rather than via the catalog. If the lowercase "tables need…" intrusion bothers you, easy follow-up.
This commit is contained in:
+13
-2
@@ -188,6 +188,17 @@ pub fn ambient_hint(
|
||||
selected: None,
|
||||
});
|
||||
}
|
||||
// User typing into a NewName slot — show the friendlier
|
||||
// "type a name" hint rather than the technical "next: …"
|
||||
// that the post-consumed-partial parse would otherwise
|
||||
// produce (round-3 follow-up).
|
||||
if let Some(t) = crate::completion::typing_name_at_cursor(input, cursor) {
|
||||
let text = t.next_after_name.map_or_else(
|
||||
|| crate::t!("hint.ambient_typing_name"),
|
||||
|next| crate::t!("hint.ambient_typing_name_then", next = next),
|
||||
);
|
||||
return Some(AmbientHint::Prose(text));
|
||||
}
|
||||
// Invalid identifier: cursor sits in a known-set slot but
|
||||
// the typed prefix matches nothing in the schema. (Stage
|
||||
// 8e / the user's #5.)
|
||||
@@ -567,8 +578,8 @@ mod tests {
|
||||
match ambient_hint("show data Custp", 15, None, &cache) {
|
||||
Some(AmbientHint::Prose(p)) => {
|
||||
assert!(
|
||||
p.contains("no such table"),
|
||||
"expected 'no such table' wording, got {p:?}",
|
||||
p.contains("No such table"),
|
||||
"expected 'No such table' wording, got {p:?}",
|
||||
);
|
||||
assert!(p.contains("Custp"), "should name the bad ident, got {p:?}");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user