Class: Thor::Interactive::TUI::TextInput
- Inherits:
-
Object
- Object
- Thor::Interactive::TUI::TextInput
- 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
-
#cursor_col ⇒ Object
readonly
Returns the value of attribute cursor_col.
-
#cursor_row ⇒ Object
readonly
Returns the value of attribute cursor_row.
Instance Method Summary collapse
- #add_to_history(text) ⇒ Object
- #backspace ⇒ Object
- #clear ⇒ Object
- #content ⇒ Object
- #current_line ⇒ Object
- #delete_char ⇒ Object
- #empty? ⇒ Boolean
- #history_back ⇒ Object
- #history_entries ⇒ Object
- #history_forward ⇒ Object
-
#initialize ⇒ TextInput
constructor
A new instance of TextInput.
- #insert_char(ch) ⇒ Object
- #insert_text(text) ⇒ Object
- #line_count ⇒ Object
- #lines ⇒ Object
-
#load_history(entries) ⇒ Object
Load history entries from an array of strings.
- #move_down ⇒ Object
- #move_end ⇒ Object
- #move_home ⇒ Object
- #move_left ⇒ Object
- #move_right ⇒ Object
- #move_up ⇒ Object
- #newline ⇒ Object
-
#submit ⇒ Object
Submit the current content and add to history.
Constructor Details
#initialize ⇒ TextInput
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_col ⇒ Object (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_row ⇒ Object (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 |
#backspace ⇒ Object
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 |
#clear ⇒ Object
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 |
#content ⇒ Object
20 21 22 |
# File 'lib/thor/interactive/tui/text_input.rb', line 20 def content @lines.join("\n") end |
#current_line ⇒ Object
36 37 38 |
# File 'lib/thor/interactive/tui/text_input.rb', line 36 def current_line @lines[@cursor_row] || "" end |
#delete_char ⇒ Object
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
24 25 26 |
# File 'lib/thor/interactive/tui/text_input.rb', line 24 def empty? @lines.length == 1 && @lines[0].empty? end |
#history_back ⇒ Object
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_entries ⇒ Object
203 204 205 |
# File 'lib/thor/interactive/tui/text_input.rb', line 203 def history_entries @history.dup end |
#history_forward ⇒ Object
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_count ⇒ Object
32 33 34 |
# File 'lib/thor/interactive/tui/text_input.rb', line 32 def line_count @lines.length end |
#lines ⇒ Object
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_down ⇒ Object
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_end ⇒ Object
142 143 144 |
# File 'lib/thor/interactive/tui/text_input.rb', line 142 def move_end @cursor_col = @lines[@cursor_row].length end |
#move_home ⇒ Object
138 139 140 |
# File 'lib/thor/interactive/tui/text_input.rb', line 138 def move_home @cursor_col = 0 end |
#move_left ⇒ Object
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_right ⇒ Object
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_up ⇒ Object
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 |
#newline ⇒ Object
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 |
#submit ⇒ Object
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 |