# Build an application console
`std::terminal::readline` exposes Reedline to scripts. It edits text; it does not
interpret entered lines as Shelly code. An application supplies its own dispatch.
## A console with explicit lifetime
This defines a function to call from an interactive terminal. The definition
itself neither opens an editor nor waits for input.
```shy
import std::terminal::{ readline }
fn notes_console(): () | ErrorValue
{
let $editor = readline::Editor(prompt: "notes> ")
try
{
for $line in $editor.lines
{
if $line == "quit" { break }
echo "note: ${line}"
}
}
finally { $editor.close }
}
```
`lines` yields Strings, including an empty String for an empty submission.
Ctrl+C discards the draft and reprompts; Ctrl+D on an empty buffer ends the stream.
A break closes the stream's editor lease while leaving the editor reusable.
For explicit interrupt handling, use `read_event`: its event kind is `Line`,
`Interrupt`, or `End`. `read` returns a String or `()` at end and handles interrupts
by continuing. The terminal is restored before application code processes a line.
## Configure the editor
Editor options include a prompt, history policy, completion, validation,
highlighting, Emacs/Vi mode, and limits. Copies share the editor handle. A script
editor defaults to isolated in-memory history and does not inherit the shell's
prompt, history file, or completion symbol list.
A Prompt supports left, right, and continuation content; these may be text or
callbacks. ReadOptions can override a prompt and provide an initial draft/cursor.
Text and Style objects express styling without treating every ANSI escape as
printable width.
## Completion, validation, and highlighting
Callbacks receive an Edit snapshot containing text, cursor, revision, before/after
text, and word information. Complete returns Strings or Completion records;
Validate returns ready/more/reject; Highlight returns styled spans.
Spans and cursors use **UTF-8 byte offsets**, validated at character boundaries.
They are not Unicode character indexes. This differs from language String
indexing. Callback results cannot replace or rewrite the input implicitly.
Limits bound input sizes, completions, highlight spans, and callback work.
History can be submitted automatically or recorded manually, with explicit
persistent-storage failure policy. `history_status` exposes degraded history.
Call `close` in cleanup even if a callback or application command fails.
---
Related: [REPL and history](REPL-and-History) · [Terminal formatting](Terminal-Formatting) · [Errors](Errors-and-Cleanup)