Class: Thor::Interactive::TUI::TextInput

Inherits:
Object
  • Object
show all
Defined in:
lib/thor/interactive/tui/text_input.rb

Overview

Multi-line text buffer with cursor tracking. Used as the data model for the input area in the TUI shell.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeTextInput

Returns a new instance of TextInput.



11
12
13
14
15
16
17
18
# File 'lib/thor/interactive/tui/text_input.rb', line 11

def initialize
  @lines = [+""]
  @cursor_row = 0
  @cursor_col = 0
  @history = []
  @history_index = nil
  @saved_input = nil
end

Instance Attribute Details

#cursor_colObject (readonly)

Returns the value of attribute cursor_col.



9
10
11
# File 'lib/thor/interactive/tui/text_input.rb', line 9

def cursor_col
  @cursor_col
end

#cursor_rowObject (readonly)

Returns the value of attribute cursor_row.



9
10
11
# File 'lib/thor/interactive/tui/text_input.rb', line 9

def cursor_row
  @cursor_row
end

Instance Method Details

#add_to_history(text) ⇒ Object



163
164
165
166
# File 'lib/thor/interactive/tui/text_input.rb', line 163

def add_to_history(text)
  # Don't add duplicates of the most recent entry
  @history.push(text) unless @history.last == text
end

#backspaceObject



82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/thor/interactive/tui/text_input.rb', line 82

def backspace
  if @cursor_col > 0
    @lines[@cursor_row] = @lines[@cursor_row][0...@cursor_col - 1] + @lines[@cursor_row][@cursor_col..]
    @cursor_col -= 1
  elsif @cursor_row > 0
    # Join with previous line
    prev_col = @lines[@cursor_row - 1].length
    @lines[@cursor_row - 1] += @lines[@cursor_row]
    @lines.delete_at(@cursor_row)
    @cursor_row -= 1
    @cursor_col = prev_col
  end
end

#clearObject



146
147
148
149
150
# File 'lib/thor/interactive/tui/text_input.rb', line 146

def clear
  @lines = [+""]
  @cursor_row = 0
  @cursor_col = 0
end

#contentObject



20
21
22
# File 'lib/thor/interactive/tui/text_input.rb', line 20

def content
  @lines.join("\n")
end

#current_lineObject



36
37
38
# File 'lib/thor/interactive/tui/text_input.rb', line 36

def current_line
  @lines[@cursor_row] || ""
end

#delete_charObject



96
97
98
99
100
101
102
103
104
# File 'lib/thor/interactive/tui/text_input.rb', line 96

def delete_char
  if @cursor_col < @lines[@cursor_row].length
    @lines[@cursor_row] = @lines[@cursor_row][0...@cursor_col] + @lines[@cursor_row][@cursor_col + 1..]
  elsif @cursor_row < @lines.length - 1
    # Join with next line
    @lines[@cursor_row] += @lines[@cursor_row + 1]
    @lines.delete_at(@cursor_row + 1)
  end
end

#empty?Boolean

Returns:

  • (Boolean)


24
25
26
# File 'lib/thor/interactive/tui/text_input.rb', line 24

def empty?
  @lines.length == 1 && @lines[0].empty?
end

#history_backObject



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/thor/interactive/tui/text_input.rb', line 168

def history_back
  return false if @history.empty?

  if @history_index.nil?
    @saved_input = content
    @history_index = @history.length - 1
  elsif @history_index > 0
    @history_index -= 1
  else
    return false
  end

  load_from_string(@history[@history_index])
  true
end

#history_entriesObject



203
204
205
# File 'lib/thor/interactive/tui/text_input.rb', line 203

def history_entries
  @history.dup
end

#history_forwardObject



184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/thor/interactive/tui/text_input.rb', line 184

def history_forward
  return false if @history_index.nil?

  if @history_index < @history.length - 1
    @history_index += 1
    load_from_string(@history[@history_index])
  else
    @history_index = nil
    load_from_string(@saved_input || "")
    @saved_input = nil
  end
  true
end

#insert_char(ch) ⇒ Object



40
41
42
43
# File 'lib/thor/interactive/tui/text_input.rb', line 40

def insert_char(ch)
  @lines[@cursor_row].insert(@cursor_col, ch)
  @cursor_col += ch.length
end

#insert_text(text) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/thor/interactive/tui/text_input.rb', line 45

def insert_text(text)
  text_lines = text.split("\n", -1)
  if text_lines.length == 1
    insert_char(text_lines[0])
  else
    # Split current line at cursor
    before = @lines[@cursor_row][0...@cursor_col]
    after = @lines[@cursor_row][@cursor_col..]

    # First fragment joins with text before cursor
    @lines[@cursor_row] = before + text_lines[0]

    # Middle lines insert after current row
    text_lines[1...-1].each_with_index do |line, i|
      @lines.insert(@cursor_row + 1 + i, line)
    end

    # Last fragment joins with text after cursor
    last_line = text_lines.last + after.to_s
    @lines.insert(@cursor_row + text_lines.length - 1, last_line)

    @cursor_row += text_lines.length - 1
    @cursor_col = text_lines.last.length
  end
end

#line_countObject



32
33
34
# File 'lib/thor/interactive/tui/text_input.rb', line 32

def line_count
  @lines.length
end

#linesObject



28
29
30
# File 'lib/thor/interactive/tui/text_input.rb', line 28

def lines
  @lines.dup
end

#load_history(entries) ⇒ Object

Load history entries from an array of strings



199
200
201
# File 'lib/thor/interactive/tui/text_input.rb', line 199

def load_history(entries)
  @history = entries.dup
end

#move_downObject



131
132
133
134
135
136
# File 'lib/thor/interactive/tui/text_input.rb', line 131

def move_down
  if @cursor_row < @lines.length - 1
    @cursor_row += 1
    @cursor_col = [@cursor_col, @lines[@cursor_row].length].min
  end
end

#move_endObject



142
143
144
# File 'lib/thor/interactive/tui/text_input.rb', line 142

def move_end
  @cursor_col = @lines[@cursor_row].length
end

#move_homeObject



138
139
140
# File 'lib/thor/interactive/tui/text_input.rb', line 138

def move_home
  @cursor_col = 0
end

#move_leftObject



106
107
108
109
110
111
112
113
# File 'lib/thor/interactive/tui/text_input.rb', line 106

def move_left
  if @cursor_col > 0
    @cursor_col -= 1
  elsif @cursor_row > 0
    @cursor_row -= 1
    @cursor_col = @lines[@cursor_row].length
  end
end

#move_rightObject



115
116
117
118
119
120
121
122
# File 'lib/thor/interactive/tui/text_input.rb', line 115

def move_right
  if @cursor_col < @lines[@cursor_row].length
    @cursor_col += 1
  elsif @cursor_row < @lines.length - 1
    @cursor_row += 1
    @cursor_col = 0
  end
end

#move_upObject



124
125
126
127
128
129
# File 'lib/thor/interactive/tui/text_input.rb', line 124

def move_up
  if @cursor_row > 0
    @cursor_row -= 1
    @cursor_col = [@cursor_col, @lines[@cursor_row].length].min
  end
end

#newlineObject



71
72
73
74
75
76
77
78
79
80
# File 'lib/thor/interactive/tui/text_input.rb', line 71

def newline
  # Split current line at cursor
  before = @lines[@cursor_row][0...@cursor_col]
  after = @lines[@cursor_row][@cursor_col..]

  @lines[@cursor_row] = before
  @lines.insert(@cursor_row + 1, after.to_s)
  @cursor_row += 1
  @cursor_col = 0
end

#submitObject

Submit the current content and add to history. Returns the content and clears the input.



154
155
156
157
158
159
160
161
# File 'lib/thor/interactive/tui/text_input.rb', line 154

def submit
  text = content
  add_to_history(text) unless text.strip.empty?
  clear
  @history_index = nil
  @saved_input = nil
  text
end