Class: TUITD::State

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

Overview

Represents the parsed state of a terminal screen. Provides high-level query methods for AI consumption.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data) ⇒ State

Returns a new instance of State.

Raises:

  • (ArgumentError)


9
10
11
12
13
14
15
16
17
# File 'lib/tui_td/state.rb', line 9

def initialize(data)
  raise ArgumentError, "State data must include :size key" unless data[:size]
  raise ArgumentError, "State data must include :rows key" unless data[:rows]

  @rows = data[:size][:rows]
  @cols = data[:size][:cols]
  @grid = data[:rows]
  @cursor = data[:cursor]
end

Instance Attribute Details

#colsObject (readonly)

Returns the value of attribute cols.



7
8
9
# File 'lib/tui_td/state.rb', line 7

def cols
  @cols
end

#cursorObject (readonly)

Returns the value of attribute cursor.



7
8
9
# File 'lib/tui_td/state.rb', line 7

def cursor
  @cursor
end

#gridObject (readonly)

Returns the value of attribute grid.



7
8
9
# File 'lib/tui_td/state.rb', line 7

def grid
  @grid
end

#rowsObject (readonly)

Returns the value of attribute rows.



7
8
9
# File 'lib/tui_td/state.rb', line 7

def rows
  @rows
end

Instance Method Details

#background_at(row, col) ⇒ Object



50
51
52
53
# File 'lib/tui_td/state.rb', line 50

def background_at(row, col)
  return nil if row >= @rows || col >= @cols
  @grid[row][col][:bg]
end

#find_text(pattern) ⇒ Object

Search for text across the entire terminal



31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/tui_td/state.rb', line 31

def find_text(pattern)
  results = []
  @grid.each_with_index do |row, ri|
    text = row.map { |c| c[:char] }.join
    pos = 0
    while (match = text.index(pattern, pos))
      results << { row: ri, col: match, text: pattern, full_line: text }
      pos = match + 1
    end
  end
  results
end

#foreground_at(row, col) ⇒ Object

Get the color at a specific cell



45
46
47
48
# File 'lib/tui_td/state.rb', line 45

def foreground_at(row, col)
  return nil if row >= @rows || col >= @cols
  @grid[row][col][:fg]
end

#plain_textObject

Get plain text of the entire terminal (no ANSI)



20
21
22
# File 'lib/tui_td/state.rb', line 20

def plain_text
  @grid.map { |row| row.map { |c| c[:char] }.join.rstrip }.join("\n")
end

#style_at(row, col) ⇒ Object



55
56
57
58
59
# File 'lib/tui_td/state.rb', line 55

def style_at(row, col)
  return nil if row >= @rows || col >= @cols
  cell = @grid[row][col]
  { bold: cell[:bold], italic: cell[:italic], underline: cell[:underline] }
end

#text_at(row, col, length = @cols - col) ⇒ Object

Get text at a specific position



25
26
27
28
# File 'lib/tui_td/state.rb', line 25

def text_at(row, col, length = @cols - col)
  return "" if row >= @rows || col >= @cols
  @grid[row][col, length].map { |c| c[:char] }.join
end

#to_ai_jsonObject



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/tui_td/state.rb', line 61

def to_ai_json
  h = extract_highlights
  cursor_info = @cursor.is_a?(Hash) ? @cursor : {}
  r = cursor_info[:row] || cursor_info["row"] || 0
  c = cursor_info[:col] || cursor_info["col"] || 0
  styled_count = h.count { |hl| hl[:bold] || hl[:italic] || hl[:underline] || hl[:fg] || hl[:bg] }

  summary = +"Cursor at [#{r},#{c}]. "
  summary << "#{styled_count} styled row#{styled_count == 1 ? '' : 's'}"
  fgs = h.flat_map { |hl| hl[:fg] }.compact.uniq
  bgs = h.flat_map { |hl| hl[:bg] }.compact.uniq
  summary << ", colors: fg=#{fgs.sort.join(',')}" unless fgs.empty?
  summary << ", bg=#{bgs.sort.join(',')}" unless bgs.empty?
  summary << "."

  {
    size: { rows: @rows, cols: @cols },
    cursor: cursor_info,
    text: plain_text,
    highlights: h,
    summary: summary,
  }
end