Module: Muxr::KeyParser
- Defined in:
- lib/muxr/key_parser.rb
Overview
Translates an array of “keys” entries (a mix of literal text and vim-style named keys like “<esc>”) into a stream of byte segments tagged by kind.
Each input element is either:
- Literal text (UTF-8) — emitted as [:literal, bytes].
- A named key wrapped in angle brackets like "<esc>", "<c-c>", "<up>" —
emitted as [:special, bytes] using the appropriate control sequence.
The tagged form lets callers wrap only literal segments in bracketed-paste markers when desired. Concatenating the bytes of all segments gives the raw byte stream to write to the PTY.
Constant Summary collapse
- NAMED_KEY_RE =
/\A<([^<>]+)>\z/.freeze
- CSI =
CSI = ESC [ , SS3 = ESC O — both standard xterm key encodings.
"\e[".b.freeze
- SS3 =
"\eO".b.freeze
- NAMED_KEYS =
Single canonical map. Keys are lowercased; aliases live alongside their canonical forms. Values are ASCII byte strings.
{ "esc" => "\e".b, "escape" => "\e".b, "enter" => "\r".b, "cr" => "\r".b, "return" => "\r".b, "tab" => "\t".b, "s-tab" => "#{CSI}Z".b, "bs" => "\x7f".b, # what real backspace keys send through a PTY "backspace"=> "\x7f".b, "space" => " ".b, "up" => "#{CSI}A".b, "down" => "#{CSI}B".b, "right" => "#{CSI}C".b, "left" => "#{CSI}D".b, "home" => "#{CSI}H".b, "end" => "#{CSI}F".b, "pageup" => "#{CSI}5~".b, "pagedown" => "#{CSI}6~".b, "f1" => "#{SS3}P".b, "f2" => "#{SS3}Q".b, "f3" => "#{SS3}R".b, "f4" => "#{SS3}S".b, "f5" => "#{CSI}15~".b, "f6" => "#{CSI}17~".b, "f7" => "#{CSI}18~".b, "f8" => "#{CSI}19~".b, "f9" => "#{CSI}20~".b, "f10" => "#{CSI}21~".b, "f11" => "#{CSI}23~".b, "f12" => "#{CSI}24~".b }.freeze
- CTRL_RE =
/\Ac-([a-z])\z/.freeze
Class Method Summary collapse
- .classify(entry) ⇒ Object
- .ctrl_bytes(name) ⇒ Object
-
.translate(entries) ⇒ Object
Returns an array of [kind, bytes] pairs.
Class Method Details
.classify(entry) ⇒ Object
71 72 73 74 75 76 77 78 79 80 |
# File 'lib/muxr/key_parser.rb', line 71 def classify(entry) m = NAMED_KEY_RE.match(entry) return [:literal, entry.b] unless m name = m[1].downcase bytes = NAMED_KEYS[name] || ctrl_bytes(name) raise Dispatcher::Error.new("unknown named key #{entry.inspect}") unless bytes [:special, bytes] end |
.ctrl_bytes(name) ⇒ Object
82 83 84 85 86 87 |
# File 'lib/muxr/key_parser.rb', line 82 def ctrl_bytes(name) m = CTRL_RE.match(name) return nil unless m # <c-a>=0x01 .. <c-z>=0x1A (m[1].ord - "a".ord + 1).chr.b end |
.translate(entries) ⇒ Object
Returns an array of [kind, bytes] pairs. Raises Dispatcher::Error on a non-array input or an unrecognized ‘<name>`.
62 63 64 65 66 67 68 69 |
# File 'lib/muxr/key_parser.rb', line 62 def translate(entries) raise Dispatcher::Error.new("`keys` must be an array of strings") unless entries.is_a?(Array) entries.map do |entry| raise Dispatcher::Error.new("`keys` entries must be strings") unless entry.is_a?(String) classify(entry) end end |