Lift `dsl::ECHO_PREFIX = "running: "` as a public const,
with a unit test asserting `t!("dsl.running", input = "")`
matches it. The catalog template is now contracted to equal
`format!("{ECHO_PREFIX}{input}")` — a translator changing
the prefix breaks the test.
Add `input_render::lex_to_runs(input, theme)` — a
cursor-less variant of `render_input_runs` for use cases
(echo lines, future hint panel) that need token-class
colouring without an inverted cursor.
ui::render_output_line: when the line is an Echo submitted
in Simple mode, peel the prefix and re-tokenise the rest
through lex_to_runs, rendering each token at its class
colour. Advanced-mode echoes and any echo whose body
unexpectedly lacks the prefix fall through to the plain
rendering.
Tests: 683 passing, 0 failing, 1 ignored (682 baseline →
+1 echo_prefix_matches_catalog_template). Clippy clean
(uses let-chain to keep the if condition flat).
Stage 4 adds render-time parse + error overlay so the
failing token in mid-typed input lights up in the error
colour.
New `input_render` module with `render_input_runs(input,
cursor_byte, theme) -> Vec<StyledRun>`. Lexes the input,
assigns each token its `theme.token_color`, preserves
whitespace gaps as `theme.fg` runs, and injects the cursor
by splitting the run that contains it into before/under/after
sub-spans (under marked Modifier::REVERSED). End-of-input
cursor is an empty-range sentinel rendered as an inverted
space.
ui::render_input_panel switches over EffectiveMode: simple
mode goes through render_input_runs + a small runs_to_spans
helper that borrows from the input string; advanced modes
(persistent + one-shot `:`) keep the previous plain
before/under/after rendering since the DSL lexer doesn't
speak SQL (ADR-0022 §12).
Multi-byte UTF-8 in string literals is handled by walking
to the next char boundary when splitting the cursor run,
mirroring the previous renderer.
Tests: 682 passing, 0 failing, 1 ignored (672 baseline →
+10: 9 input_render unit tests covering each token class,
cursor placements, multi-byte, full-command shape; +1 new
"all token classes" UI snapshot). Clippy clean.
Caveat (noted inline in the new snapshot test): the
TestBackend/render_to_string path records text symbols
only, not ratatui style. The new snapshot is therefore a
text-layout regression net; the unit tests in
input_render::tests are the authoritative regression net
for colour mappings.
Stage 3 wires the same colouring into simple-mode echo
lines in the output panel.