Interactive Line Editor
Introduction
erbsland::cterm::ReadLine provides styled interactive text editing on a full-control terminal.
It supports blocking and polling lifecycles, multiline input, history, inactivity timeouts, and deterministic cleanup.
See Input for complete usage and behavior.
Usage
Create the editor with erbsland::cterm::ReadLine::create(), a
erbsland::cterm::TerminalPtr, and
erbsland::cterm::ReadLineOptions.
Use erbsland::cterm::ReadLine::waitForInput() for a blocking
prompt, or combine
erbsland::cterm::ReadLine::start(), erbsland::cterm::ReadLine::update(), and
erbsland::cterm::ReadLine::stop() with an application loop.
Only erbsland::cterm::ReadLineStatus::Committed is successful and carries entered text.
The polling-only erbsland::cterm::ReadLineStatus::Idle, cancellation, and timeout statuses carry an empty
string.
An active editor exclusively owns terminal output until it stops.
Horizontal input padding is represented by erbsland::block::MarginPair;
negative leading or trailing values are clamped to zero.
Protected Secret Entry
erbsland::cterm::ReadSecret is the parallel API for passwords and tokens.
It accepts the appearance and lifecycle parts of ReadLineOptions, forces one logical and display line, rejects
history and initial text, and caps input at 1024 Unicode code points.
It renders a fixed bullet mask and transports a marked String through
ReadLineResult.
Interface
-
class ReadLine
An interactive terminal line editor.
A read-line operation exclusively owns terminal output between
start()andstop().See: Input
Subclassed by erbsland::cterm::impl::ReadLine
Public Functions
-
virtual void start() = 0
Start a non-blocking read-line operation.
- Throws:
err::RuntimeError – if already active or interactive full-control output is unavailable.
-
virtual ReadLineResult update() = 0
Poll and update an active read-line operation.
Terminal results remain latched until
stop()is called.- Throws:
err::RuntimeError – if no operation is active.
- Returns:
Idle,Committed,Cancelled, orTimeout.
-
virtual ReadLineResult waitForInput() = 0
Run a complete blocking read-line operation.
This method never returns
Idleand always stops the operation before returning or propagating an exception.- Throws:
err::RuntimeError – if already active or interactive full-control output is unavailable.
- Returns:
Committed,Cancelled, orTimeout.
-
virtual void stop() noexcept = 0
Stop the operation and restore or retain the rendered input area according to the cleanup option.
Calling this method while inactive has no effect.
-
virtual bool isActive() const noexcept = 0
Test if an operation is active.
Public Static Functions
-
static ReadLinePtr create(TerminalPtr terminal, ReadLineOptions options = {})
Create an interactive terminal line editor.
Text and history are copied and normalized to the configured limits.
- Parameters:
terminal – The terminal retained for the lifetime of this object.
options – The appearance and editing options.
- Throws:
err::ParameterError – if
terminalis null oroptionsis structurally invalid.- Returns:
The new line editor.
-
virtual void start() = 0
-
using erbsland::cterm::ReadLinePtr = std::shared_ptr<ReadLine>
A shared pointer to an interactive terminal line editor.
-
enum class erbsland::cterm::ReadLineDisplayStyle : std::uint8_t
The layout used to display an interactive read-line area.
Values:
-
enumerator Compact
Title and input rows without trailing spacing or a frame.
-
enumerator HorizontalSpace
Compact layout followed by one empty row.
-
enumerator HorizontalFrame
Title in a top horizontal border and a bottom horizontal border.
-
enumerator Frame
A complete frame around the title and input rows.
-
enumerator Compact
-
class ReadLineOptions
Options for an interactive read-line operation.
Text limits are applied to private copies when a
ReadLineis constructed, making setter order irrelevant.Public Functions
-
ReadLineOptions()
Create options with the standard interactive read-line appearance.
-
inline const BlockStyle &backgroundStyle() const noexcept
Get the input-area background style.
-
ReadLineOptions &setBackgroundStyle(BlockStyle style) noexcept
Set the input-area background style.
-
inline const BlockStyle &titleStyle() const noexcept
Get the title style.
-
ReadLineOptions &setTitleStyle(BlockStyle style) noexcept
Set the title style.
-
inline const BlockStyle &promptStyle() const noexcept
Get the prompt style.
-
ReadLineOptions &setPromptStyle(BlockStyle style) noexcept
Set the prompt style.
-
inline const BlockStyle &placeholderStyle() const noexcept
Get the placeholder style.
-
ReadLineOptions &setPlaceholderStyle(BlockStyle style) noexcept
Set the placeholder style.
-
inline const BlockStyle &textStyle() const noexcept
Get the entered-text style.
-
ReadLineOptions &setTextStyle(BlockStyle style) noexcept
Set the entered-text style.
-
inline const BlockStyle &cursorStyle() const noexcept
Get the cursor style used over visible text.
-
ReadLineOptions &setCursorStyle(BlockStyle style) noexcept
Set the cursor style used over visible text.
-
inline ReadLineDisplayStyle displayStyle() const noexcept
Get the display layout.
-
ReadLineOptions &setDisplayStyle(ReadLineDisplayStyle style) noexcept
Set the display layout.
-
inline const FrameBorder &frameBorder() const noexcept
Get the frame border.
-
ReadLineOptions &setFrameBorder(FrameBorder border) noexcept
Set the frame border.
-
inline const block::MarginPair &padding() const noexcept
Get the horizontal input padding.
-
ReadLineOptions &setPadding(block::MarginPair padding) noexcept
Set the input padding.
Negative values are clamped to zero.
-
inline const BlockString &title() const noexcept
Get the title.
-
ReadLineOptions &setTitle(BlockString title) noexcept
Set the title.
-
ReadLineOptions &setTitle(const text::String &title)
Set the title from plain text.
-
inline const BlockString &prompt() const noexcept
Get the prompt.
-
ReadLineOptions &setPrompt(BlockString prompt) noexcept
Set the prompt.
-
ReadLineOptions &setPrompt(const text::String &prompt)
Set the prompt from plain text.
-
inline const BlockString &placeholder() const noexcept
Get the placeholder.
-
ReadLineOptions &setPlaceholder(BlockString placeholder) noexcept
Set the placeholder.
-
ReadLineOptions &setPlaceholder(const text::String &placeholder)
Set the placeholder from plain text.
-
inline unit::CpLength maximumLength() const noexcept
Get the maximum entered-text length in code points.
-
ReadLineOptions &setMaximumLength(unit::CpLength maximumLength) noexcept
Set the maximum entered-text length in code points.
-
ReadLineOptions &setMaximumLines(unit::LineCount maximumLines)
Set the maximum logical line count.
- Throws:
err::ParameterError – if the count is zero.
-
inline unit::LineCount maximumDisplayLines() const noexcept
Get the maximum displayed edit-row count.
-
ReadLineOptions &setMaximumDisplayLines(unit::LineCount maximumDisplayLines)
Set the maximum displayed edit-row count.
- Throws:
err::ParameterError – if the count is zero.
-
inline const text::StringList &history() const noexcept
Get the history entries.
-
ReadLineOptions &setHistory(text::StringList history) noexcept
Replace the history entries.
-
ReadLineOptions &setCurrentText(text::String currentText) noexcept
Set the initial text.
-
inline time::Seconds timeout() const noexcept
Get the inactivity timeout.
Zero disables the timeout.
-
ReadLineOptions &setTimeout(time::Seconds timeout)
Set the inactivity timeout.
- Throws:
err::ParameterError – if the timeout is negative.
-
inline time::Seconds timeoutDisplayThreshold() const noexcept
Get the remaining-time threshold for displaying the timeout countdown.
Zero disables the countdown display.
-
ReadLineOptions &setTimeoutDisplayThreshold(time::Seconds timeoutDisplayThreshold)
Set the remaining-time threshold for displaying the timeout countdown.
- Parameters:
timeoutDisplayThreshold – The non-negative display threshold.
- Throws:
err::ParameterError – if the threshold is negative.
- Returns:
This options object.
-
inline time::Milliseconds blinkInterval() const noexcept
Get the cursor blink interval.
-
ReadLineOptions &setBlinkInterval(time::Milliseconds blinkInterval)
Set the cursor blink interval.
- Throws:
err::ParameterError – if the interval is not positive.
-
ReadLineOptions &setCursorBlock(Block cursorBlock)
Set the cursor block used over empty space.
- Throws:
err::ParameterError – if the block does not occupy exactly one terminal cell.
-
ReadLineOptions &setCommitKey(Key commitKey) noexcept
Set the key that commits entered text.
-
ReadLineOptions &setNewLineKey(Key newLineKey) noexcept
Set the key that inserts a logical line break.
-
ReadLineOptions &setCancelKey(Key cancelKey) noexcept
Set the key that cancels input.
-
inline bool cleanupEnabled() const noexcept
Test if the input area is removed when the operation stops.
-
ReadLineOptions &setCleanupEnabled(bool cleanupEnabled) noexcept
Enable or disable removal of the input area when the operation stops.
-
ReadLineOptions()
-
using erbsland::cterm::ReadLineResult = util::ResultWithData<text::String, ReadLineStatus>
An interactive read-line result with committed text.
Only
ReadLineStatus::Committedtransports text; all other states transport an empty string.
-
class ReadLineStatus : public erbsland::util::Result
The status of an interactive read-line operation.
Only
Committedis a successfulutil::Result; all other states carry no caller-visible text.Public Functions
-
inline constexpr bool operator==(const ReadLineStatus &other) const noexcept
Compare two read-line status values.
-
inline constexpr bool isCommitted() const noexcept
Test if text was committed.
-
inline constexpr bool isIdle() const noexcept
Test if a non-blocking update found no terminal result.
-
inline constexpr bool isCancelled() const noexcept
Test if the user cancelled the operation.
-
inline constexpr bool isTimeout() const noexcept
Test if the inactivity timeout expired.
-
inline constexpr Result(const Value value)
Create a new result.
- Parameters:
value – The value of the result.
Public Static Attributes
-
static const ReadLineStatus Committed = Value::success<0>()
The user committed the entered text.
-
static const ReadLineStatus Idle = Value::failure<0>()
No terminal result is available yet.
-
static const ReadLineStatus Cancelled = Value::failure<1>()
The user cancelled the operation.
-
static const ReadLineStatus Timeout = Value::failure<2>()
The inactivity timeout expired.
-
inline constexpr bool operator==(const ReadLineStatus &other) const noexcept
-
class ReadSecret
An interactive, securely erased single-line secret editor.
Entered code points are retained in fixed protected storage and only a fixed bullet mask is rendered.
See: Input
Subclassed by erbsland::cterm::impl::ReadSecret
Public Functions
-
virtual void start() = 0
Start interactive secret input.
-
virtual ReadLineResult update() = 0
Process available terminal input and return its result.
-
virtual ReadLineResult waitForInput() = 0
Wait for input, process it, and return its result.
-
virtual void stop() noexcept = 0
Stop interactive secret input.
-
virtual bool isActive() const noexcept = 0
Test if secret input is active.
Public Static Functions
-
static ReadSecretPtr create(TerminalPtr terminal, ReadLineOptions options = {})
Create a protected single-line terminal editor.
The requested maximum length is capped at 1024 code points. History and initial text must be empty.
- Throws:
err::ParameterError – If the terminal is null or unsupported options contain history or initial text.
-
virtual void start() = 0