Class: EscapeParser

Inherits:
Object
  • Object
show all
Defined in:
lib/escapeparser.rb

Overview

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeEscapeParser

Returns a new instance of EscapeParser.



7
8
9
10
# File 'lib/escapeparser.rb', line 7

def initialize
  @state = :start
  @str = ""
end

Instance Attribute Details

#stateObject (readonly)

Returns the value of attribute state.



5
6
7
# File 'lib/escapeparser.rb', line 5

def state
  @state
end

#strObject (readonly)

Returns the value of attribute str.



5
6
7
# File 'lib/escapeparser.rb', line 5

def str
  @str
end

Instance Method Details

#complete?Boolean

Returns:

  • (Boolean)


70
# File 'lib/escapeparser.rb', line 70

def complete?; @state == :complete; end

#put(ch) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/escapeparser.rb', line 12

def put(ch)
  # ch is a codepoint, which for OSC/DCS string payloads (e.g. a window
  # title) can be a multibyte UTF-8 character - decode it as UTF-8.
  # Bare Integer#chr only handles 0..255 and raises RangeError on
  # anything larger (e.g. a spinner glyph in claude's title sequence).
  c = ch.chr(Encoding::UTF_8)
  case @state
  when :start
    return false if ch < 32
    @str << c
    case c
    when '['
      @state = :csi
    when ']'
      @state = :oc
    when 'P', 'X', '^', '_'
      # DCS, SOS, PM, APC - string sequences terminated by ST (ESC \) or BEL
      @state = :string
    when /\w|[=>|}~6-9]/
      @state = :complete
    end
  when :csi
    # A C0 control byte inside a CSI is executed immediately and the
    # sequence keeps parsing (per ECMA-48) - it must NOT be folded into
    # the sequence or terminate it. Returning false routes it to Term's
    # handle_control while @esc stays in :csi; ESC (27) restarts the
    # sequence there. (vttest "cursor-control chars inside ESC sequences".)
    return false if ch < 32
    @str << c
    @state = :complete if /[[:alpha:]]|[@]/.match(c)
  when :oc
    if ch == 7 then @state = :complete
    elsif ch < 32 then return false
    else @str << c
    end
  when :string
    if ch == 7
      @state = :complete
    elsif ch == 27
      @state = :string_esc
    elsif ch < 32
      return false
    else
      @str << c
    end
  when :string_esc
    if c == '\\'
      @state = :complete
    else
      @str << 27.chr << c
      @state = :string
    end
  else
    return false
  end
  true
end