Module: Clack::Core::KeyReader
- Defined in:
- lib/clack/core/key_reader.rb
Overview
Reads single keystrokes from the terminal in raw mode. Handles escape sequences for arrow keys and other special keys.
Escape sequences come in two shapes: CSI (+ESC [+ ... final byte) and
SS3 (+ESC O+ + one byte), the latter used by terminals in application
cursor mode (tmux, and after vim or less leave keypad-transmit mode on).
Both are assembled here and folded into one canonical code per key via
Settings.normalize_key, so prompts only ever see "\e[A" for Up.
The Escape detection window is tunable via the CLACK_ESCAPE_TIMEOUT
env var (see Environment.escape_timeout) for high-latency links.
Constant Summary collapse
- SEQUENCE_INTRODUCERS =
Escape-sequence introducers: CSI ("[") and SS3 ("O").
["[", "O"].freeze
- MAX_SEQUENCE_LENGTH =
Upper bound on bytes assembled after the introducer, so a stream of garbage can never keep the reader inside one sequence forever.
32- CSI_FINAL_BYTES =
Range of CSI final bytes (+@+ through
~), per ECMA-48. (0x40..0x7E)
Class Method Summary collapse
-
.read(input = nil) ⇒ String
Read a single keystroke in raw mode.
Class Method Details
.read(input = nil) ⇒ String
Read a single keystroke in raw mode. When input is an IO backed by a console, uses raw mode. When input is a StringIO or test double, reads directly.
End of input (EOF) and a disconnected terminal both return Ctrl+C so the prompt cancels instead of spinning on an exhausted stream.
40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/clack/core/key_reader.rb', line 40 def read(input = nil) io = input || IO.console raise NotATerminalError, (io) unless io key = io.respond_to?(:raw) ? read_raw(io) : read_from(io) Settings.normalize_key(key || Settings::KEY_CTRL_C) rescue NotATerminalError raise rescue Errno::EIO, Errno::EBADF, IOError # Terminal disconnected or closed - treat as cancel Settings::KEY_CTRL_C end |