Class: Charming::Internal::Terminal::MouseParser
- Inherits:
-
Object
- Object
- Charming::Internal::Terminal::MouseParser
- Defined in:
- lib/charming/internal/terminal/mouse_parser.rb
Overview
MouseParser parses raw terminal escape sequences into MouseEvent objects. Supports both modern SGR sequences (the most common, used by current terminals) and the older 3-byte legacy sequences. Both encodings pack modifiers and motion into the button code: bit 2 shift, bit 3 alt/meta, bit 4 ctrl, bit 5 motion. SGR signals release with a final "m" instead of "M". The public API is class methods; no instance state is required.
Constant Summary collapse
- SGR_PATTERN =
Matches an SGR-encoded mouse sequence: "\e[<button;col;row" + "M" (press) or "m" (release).
/\e\[<(\d+);(\d+);(\d+)(M|m)/- LEGACY_PATTERN =
Matches the legacy 3-byte mouse sequence: "\e[M" followed by 3 bytes.
/\e\[M(.{3})/- SHIFT_BIT =
Button-code bits for modifier keys and motion (shared by SGR and legacy).
4- ALT_BIT =
8- CTRL_BIT =
16- MOTION_BIT =
32- FLAG_BITS =
SHIFT_BIT | ALT_BIT | CTRL_BIT | MOTION_BIT
Class Method Summary collapse
-
.parse(raw) ⇒ Object
Parses raw into a MouseEvent, or returns nil when the string is not a mouse sequence or cannot be decoded.
-
.parse_legacy(raw) ⇒ Object
Parses a legacy 3-byte mouse sequence.
-
.parse_sgr(raw) ⇒ Object
Parses an SGR-format mouse sequence: button code with flag bits, 1-based (col, row), and the press/release final byte.
-
.sequence?(raw) ⇒ Boolean
Returns true when raw looks like a recognizable mouse sequence (SGR or legacy).
Class Method Details
.parse(raw) ⇒ Object
Parses raw into a MouseEvent, or returns nil when the string is not a mouse sequence or cannot be decoded.
38 39 40 41 42 43 44 |
# File 'lib/charming/internal/terminal/mouse_parser.rb', line 38 def self.parse(raw) return nil unless raw.is_a?(String) return parse_sgr(raw) if raw.match?(SGR_PATTERN) return parse_legacy(raw) if raw.start_with?("\e[M") nil end |
.parse_legacy(raw) ⇒ Object
Parses a legacy 3-byte mouse sequence. Each of the 3 bytes has 32 subtracted to recover the (button, col, row) values.
57 58 59 60 61 62 63 64 65 |
# File 'lib/charming/internal/terminal/mouse_parser.rb', line 57 def self.parse_legacy(raw) match = raw.match(LEGACY_PATTERN) return nil unless match bytes = match[1].bytes return nil unless bytes.length == 3 build_event(bytes[0] - 32, bytes[1] - 32, bytes[2] - 32, release: false) end |
.parse_sgr(raw) ⇒ Object
Parses an SGR-format mouse sequence: button code with flag bits, 1-based (col, row), and the press/release final byte.
48 49 50 51 52 53 |
# File 'lib/charming/internal/terminal/mouse_parser.rb', line 48 def self.parse_sgr(raw) match = raw.match(SGR_PATTERN) return nil unless match build_event(match[1].to_i, match[2].to_i - 1, match[3].to_i - 1, release: match[4] == "m") end |
.sequence?(raw) ⇒ Boolean
Returns true when raw looks like a recognizable mouse sequence (SGR or legacy). Lets the TTYBackend short-circuit and dispatch to MouseParser without allocation.
28 29 30 31 32 33 34 |
# File 'lib/charming/internal/terminal/mouse_parser.rb', line 28 def self.sequence?(raw) return false unless raw.is_a?(String) return true if raw.match?(SGR_PATTERN) return true if raw.start_with?("\e[M") false end |