Class: Chamomile::EscapeParser
- Inherits:
-
Object
- Object
- Chamomile::EscapeParser
- Defined in:
- lib/chamomile/escape_parser.rb
Overview
State-machine parser for ANSI escape sequences, CSI params, SGR mouse, and bracketed paste.
Constant Summary collapse
- GROUND =
States
:ground- ESC_SEEN =
:esc_seen- CSI_ENTRY =
:csi_entry- SS3 =
:ss3- PASTE =
:paste- MODIFIER_MAP =
CSI modifier mapping (xterm-style: param 2=Shift, 3=Alt, 4=Shift+Alt, 5=Ctrl, etc.)
{ 2 => [:shift], 3 => [:alt], 4 => %i[shift alt], 5 => [:ctrl], 6 => %i[ctrl shift], 7 => %i[ctrl alt], 8 => %i[ctrl shift alt], }.freeze
- PASTE_START =
"\e[200~"- PASTE_END =
"\e[201~"- MAX_PASTE_SIZE =
Maximum paste buffer size (1MB) to prevent memory exhaustion
1_048_576
Instance Method Summary collapse
-
#feed(bytes, &block) ⇒ Object
Feed raw bytes into the parser, yielding parsed messages.
-
#initialize ⇒ EscapeParser
constructor
A new instance of EscapeParser.
-
#timeout! {|KeyEvent.new(key: :escape, mod: [])| ... } ⇒ Object
Call when IO.select times out — flushes ambiguous ESC as :escape key.
Constructor Details
#initialize ⇒ EscapeParser
Returns a new instance of EscapeParser.
30 31 32 33 34 |
# File 'lib/chamomile/escape_parser.rb', line 30 def initialize @state = GROUND @buf = +"" @paste_buf = +"" end |
Instance Method Details
#feed(bytes, &block) ⇒ Object
Feed raw bytes into the parser, yielding parsed messages.
37 38 39 |
# File 'lib/chamomile/escape_parser.rb', line 37 def feed(bytes, &block) bytes.each_char { |ch| process_char(ch, &block) } end |
#timeout! {|KeyEvent.new(key: :escape, mod: [])| ... } ⇒ Object
Call when IO.select times out — flushes ambiguous ESC as :escape key.
42 43 44 45 46 47 48 |
# File 'lib/chamomile/escape_parser.rb', line 42 def timeout! return unless @state == ESC_SEEN @state = GROUND @buf.clear yield KeyEvent.new(key: :escape, mod: []) end |