ADR-0024 HintMode dispatch via walker_hint_mode_at_input
Adds the `HintMode` dispatch layer the ADR specified: the
ambient-hint resolver now consults a single
`walker::hint_mode_at_input(source) -> Option<HintMode>` to
decide between the prose / candidates ladder, rather than
discovering each slot kind through three separate post-hoc
helpers (`value_literal_hint_at_cursor`,
`typing_name_at_cursor`, and so on).
Behaviour at slot positions today:
- **Value-literal slot** (`null`/`true`/`false`/number/string
all in the expected set) → `HintMode::ProseOnly
("hint.value_literal_slot")`. The ambient-hint ladder
emits the catalog prose at empty prefix; once the user types
a partial (`n`, `tr`, `fa`) the partial check declines and
normal candidate completion takes over.
- **NewName ident slot** → `HintMode::ForceProse
("hint.ambient_typing_name")`. The ladder still consults
`typing_name_at_cursor` to learn what comes after the name
(the post-name probe is unchanged); `ForceProse` is the
declarative tag telling the resolver *that* we're in this
mode.
`HintMode` itself gains `PartialEq + Eq` for tests, and
its docstring is rewritten to describe the live semantics.
This is the structural shape ADR-0024 §HintMode-per-node
describes: one slot → one hint mode → one dispatch arm. The
detection inside `hint_mode_at_input` is transitional — it
pattern-matches the walker's expected-set today, which is
exactly what the previous ad-hoc detectors did. Phase D will
replace the signature match with node-attached `HintMode`
annotations on the typed value slots (so `date_slot`,
`int_slot`, etc. each carry a type-specific catalog key).
Two helpers move into `input_render.rs`:
- `hint_leading_slice(input, cursor)` mirrors the look-back
used by `candidates_at_cursor` so the hint resolver sees the
same token-boundary view of the world.
- `cursor_partial_is_empty(input, cursor)` distinguishes
empty-prefix from in-progress identifier shapes.
8 new walker tests pin the hint-mode resolver across
value-literal-after-paren, value-literal-after-set-assign,
value-literal-in-where, two NewName-slot cases, the
entry-keyword position, the complete-command position, and
the schema-ident position.
Tests: 817 passing, 0 failing, 1 ignored. Clippy clean.
This commit is contained in:
+18
-6
@@ -119,13 +119,25 @@ impl IdentSource {
|
||||
}
|
||||
}
|
||||
|
||||
/// Hint-panel mode for an expected node.
|
||||
/// Hint-panel mode for an expected node (ADR-0024 §HintMode-per-node).
|
||||
///
|
||||
/// Phase A defaults to `Default`; the `ProseOnly` variant
|
||||
/// attaches to typed value slots in Phase D so the hint reads
|
||||
/// "Type a date as 'YYYY-MM-DD'" rather than candidate-cycling.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[allow(dead_code)]
|
||||
/// `Default` (today's behaviour) shows candidates if any, falls
|
||||
/// back to a prose ladder otherwise. The other variants
|
||||
/// override at slot positions where the candidate list would be
|
||||
/// actively misleading or where the user benefits from format
|
||||
/// guidance:
|
||||
///
|
||||
/// - `ProseOnly(catalog_key)` — show only prose from the
|
||||
/// catalog; suppress Tab candidates. Used today by the
|
||||
/// value-literal slot at empty prefix (the "null/true/false"
|
||||
/// candidate trio is misleading at a slot that more often
|
||||
/// takes a number / quoted text / date).
|
||||
/// - `ForceProse(catalog_key)` — force this prose at the
|
||||
/// catalog key regardless of candidates. Used today by
|
||||
/// `NewName` ident slots ("Type a name, then `(`").
|
||||
/// - `SuppressProse` — show only candidates; never fall back
|
||||
/// to a prose ladder.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum HintMode {
|
||||
Default,
|
||||
ForceProse(&'static str),
|
||||
|
||||
Reference in New Issue
Block a user