Input

The input classes provide access to keyboard input from the terminal. They are designed for interactive applications such as dashboards, tools, and terminal games that need immediate key handling.

Usage

Polling for Keys in a Redraw Loop

For interactive applications, switch the input backend to key mode and poll for input with a timeout. This allows your application to update the screen regularly while still reacting to keyboard events.

using namespace std::chrono_literals;

terminal.input().setMode(Input::Mode::Key);
auto quitRequested = false;

while (!quitRequested) {
    if (const auto key = terminal.input().read(90ms); key.valid()) {
        if (key == Key{Key::Character, U'q'}) {
            quitRequested = true;
        } else if (key == Key{Key::Left}) {
            // Move selection.
        }
    }
}

Using a timeout keeps the redraw loop responsive without busy waiting.

Switching Between Key and Line Input

Input::Mode controls whether the terminal reads raw key presses or full lines of text. Mode::Key is the right choice for interactive applications with a redraw loop, while Mode::ReadLine fits prompts, configuration tools, and simple command-driven interfaces.

terminal.input().setMode(Input::Mode::ReadLine);
terminal.print("Name: ");
const auto name = terminal.input().readLine();

terminal.input().setMode(Input::Mode::Key);
terminal.printLine("Press any key to continue...");
const auto key = terminal.input().read();

Switching modes on the same terminal makes it easy to combine menu-driven screens with occasional free-form text input.

Describing Key Bindings

InputDefinition represents a key binding together with the input mode it applies to. It is useful when describing configurable shortcuts or when displaying the currently active bindings.

auto quitKey = InputDefinition{Key{Key::Character, U'q'}, InputDefinition::ForMode::Key};
auto helpKey = InputDefinition{Key{Key::F1}, InputDefinition::ForMode::Key};

std::cout << "Quit: " << quitKey.toDisplayText() << "\n";
std::cout << "Help: " << helpKey.toString() << "\n";

The helper functions toDisplayText() and toString() make it easy to present key bindings in help screens or configuration output.

Matching Decoded Key Types

When you only care about the general kind of a key event, inspect Key::Type instead of comparing against a long list of individual keys. For character comparisons, prefer Unicode code points such as U'q' and use Key::unicode() or Key::combined() instead of the deprecated ASCII accessor.

using namespace std::chrono_literals;

if (const auto key = terminal.input().read(50ms); key.valid()) {
    if (key.type() == Key::Character || key.type() == Key::Combined) {
        terminal.printLine("Typed: ", String{key.combined()});
    } else if (key.type() == Key::Escape) {
        terminal.printLine("Leaving key mode.");
    }
}

This is especially handy when the application wants to distinguish between text entry, navigation keys, and control keys before it decides how to handle the event.

../../_images/retro-plasma.jpg

The animated demos use Input in key mode so screen redraws and keyboard handling remain responsive.

Interface

class Input

The input interface.

Public Types

enum class Mode : uint8_t

Supported reading modes for the input backend.

Values:

enumerator ReadLine

Read one full line from standard input.

enumerator Key

Read raw key presses from the terminal backend.

Public Functions

virtual ~Input() = default

Destroy the input object.

virtual Mode mode() const noexcept = 0

Get the current reading mode.

virtual void setMode(Mode mode) = 0

Set the current reading mode.

Parameters:

mode – The new input mode.

inline Key read(std::chrono::milliseconds timeout = {}) const

Read one key event.

Parameters:

timeout – Maximum wait time in Mode::Key; ignored in Mode::ReadLine.

Returns:

The parsed key event, or an invalid key if no supported input was read.

virtual std::string readLine() = 0

Read a line of text from the terminal.

class InputDefinition

Definition of a single key mapping for a specific input mode.

Public Types

enum class ForMode : uint8_t

The input modes to which a key definition can apply.

Values:

enumerator Both

The key can be used in both input modes.

enumerator ReadLine

The key only applies when reading a full line.

enumerator Key

The key only applies when reading single key presses.

Public Functions

InputDefinition() = default

Create an invalid input definition.

InputDefinition(Key keyPress, ForMode forMode) noexcept

Create a definition for the given key and input mode.

Parameters:
  • keyPress – The key to match.

  • forMode – The input mode in which the definition is valid.

inline const Key &keyPress() const noexcept

Return the represented key press.

inline ForMode forMode() const noexcept

Return the mode for which this definition is valid.

inline bool valid() const noexcept

Check whether this definition contains a valid key press.

std::string toString() const

Convert the key definition to its configuration text.

The serialized configuration text includes the optional mode prefix.

Returns:

The serialized configuration text.

std::string toDisplayText(bool useBrackets = true) const

Return a display label for prompts and help texts.

Parameters:

useBrackets – If true, wrap the text in [ and ].

Returns:

A human-readable key label.

inline std::string displayText() const

Compatibility wrapper for older code that used displayText().

Returns:

A human-readable key label with stylized brackets.

Public Static Functions

static InputDefinition fromString(std::string text) noexcept

Parse the textual representation of a key definition.

Parameters:

text – The configuration text, optionally prefixed with > or + for the input mode.

Returns:

The parsed input definition.

using erbsland::cterm::InputDefinitionList = std::vector<InputDefinition>

A list of input definitions.

class Key

A simple representation of a key press.

Supports Unicode text input and common special keys.

Public Types

enum Type

Supported key kinds.

Values:

enumerator None

No supported key was decoded.

enumerator Character

A single Unicode code point.

enumerator Combined

Multiple code points that form one combined text input.

enumerator Enter

The Enter/Return key.

enumerator Tab

The tab key.

enumerator BackTab

Reverse tab / Shift+Tab.

enumerator Space

The space key.

enumerator Escape

The escape key.

enumerator Backspace

The backspace key.

enumerator Insert

The insert key.

enumerator Delete

The delete key.

enumerator Home

The home key.

enumerator End

The end key.

enumerator PageUp

The page up key.

enumerator PageDown

The page down key.

enumerator Left

The left cursor key.

enumerator Right

The right cursor key.

enumerator Up

The up cursor key.

enumerator Down

The down cursor key.

enumerator F1

The function key F1.

enumerator F2

The function key F2.

enumerator F3

The function key F3.

enumerator F4

The function key F4.

enumerator F5

The function key F5.

enumerator F6

The function key F6.

enumerator F7

The function key F7.

enumerator F8

The function key F8.

enumerator F9

The function key F9.

enumerator F10

The function key F10.

enumerator F11

The function key F11.

enumerator F12

The function key F12.

Public Functions

Key() = default

Create an invalid key.

Key(Type type, char32_t codePoint = 0) noexcept

Create a key with explicit type and optional Unicode payload.

Parameters:
  • type – The key type.

  • codePoint – The Unicode value for Type::Character.

Key(Type type, std::u32string_view character)

Create a key with explicit combined Unicode payload.

Parameters:
Throws:

std::invalid_argument – If character is not a supported Unicode character sequence.

bool operator==(const Key &other) const noexcept = default

Compare two key events for equality.

inline Type type() const noexcept

Get the key type.

char character() const noexcept

Legacy ASCII accessor for Type::Character.

Deprecated:

Use unicode() or combined() to support full Unicode input.

Returns:

The ASCII character for single-code-point character input, otherwise 0.

char32_t unicode() const noexcept

Get the Unicode code point for Type::Character.

Returns:

The single Unicode code point, or 0 if this key does not store exactly one code point.

std::u32string combined() const

Get the full combined Unicode payload for character input.

Returns:

The stored Unicode text, or an empty string for non-character keys.

inline bool valid() const noexcept

Test if this object represents a supported key.

inline constexpr std::size_t hash() const noexcept

Get a hash for this key.

std::string toString() const

Convert the key to configuration text.

Returns:

The canonical textual key name.

std::string toDisplayText(bool useBrackets = true) const

Convert the key to human-readable display text.

Parameters:

useBrackets – If true, wrap the text in [ and ].

Returns:

The display text for prompts and help texts.

Public Static Functions

static Key fromString(std::string text) noexcept

Decode a key from configuration text.

Parameters:

text – The textual key name.

Returns:

The decoded key, or Type::None if the text is unsupported.

static Key fromConsoleInput(const std::string &text) noexcept

Decode a key from console input text.

Parameters:

text – The input text or escape sequence.

Returns:

The decoded key, or Type::None if the input is unsupported.