Class: Kward::PromptInterface::ComposerState
- Inherits:
-
Object
- Object
- Kward::PromptInterface::ComposerState
- Defined in:
- lib/kward/prompt_interface/composer_state.rb
Overview
Mutable text, cursor, history, and overlay state for the composer.
Instance Attribute Summary collapse
-
#attachments ⇒ Array<Hash>
readonly
Pending image/file attachments submitted with the next turn.
-
#cursor ⇒ Integer
Cursor offset into
input. -
#history ⇒ Array<String>
readonly
Submitted input history.
-
#history_draft ⇒ String?
Draft restored after leaving history navigation.
-
#history_index ⇒ Integer?
Active history index while navigating history.
-
#input ⇒ String
Editable text currently shown in the composer.
-
#kill_buffer ⇒ String
Most recently killed text available for yank.
-
#prefill_input ⇒ String?
Text queued for the next composer prompt.
Instance Method Summary collapse
-
#add_attachment(attachment) ⇒ Object
Adds one attachment unless its source is already pending.
-
#add_history(value) ⇒ Object
Stores a submitted input unless it is blank or duplicates the previous entry.
-
#clear_attachments ⇒ Object
Removes all pending attachments without changing text input.
-
#cursor_logical_position ⇒ Object
Returns
[row, column]for cursor placement in multi-line input. -
#delete_at_cursor ⇒ Object
Deletes one character at the cursor without moving it.
-
#delete_before_cursor ⇒ Object
Deletes one character before the cursor.
-
#delete_word_after_cursor ⇒ Object
Kills the word after the cursor into
kill_buffer. -
#delete_word_before_cursor ⇒ Object
Kills the word before the cursor into
kill_buffer. -
#initialize ⇒ ComposerState
constructor
A new instance of ComposerState.
-
#insert_string(string) ⇒ Object
Inserts text at the cursor and advances by the inserted length.
-
#kill_line_after_cursor ⇒ Object
Kills all text after the cursor into
kill_buffer. -
#kill_line_before_cursor ⇒ Object
Kills all text before the cursor into
kill_buffer. -
#kill_range(start_index, end_index) ⇒ Object
Removes a range, stores it in
kill_buffer, and moves the cursor to the start. -
#move_cursor_left ⇒ Object
Moves the cursor one character left when possible.
-
#move_cursor_right ⇒ Object
Moves the cursor one character right when possible.
-
#move_to_end_of_line ⇒ Object
Moves the cursor to the end of the input buffer.
-
#move_to_next_word ⇒ Object
Moves the cursor to the next word boundary.
-
#move_to_previous_word ⇒ Object
Moves the cursor to the previous word boundary.
-
#move_to_start_of_line ⇒ Object
Moves the cursor to the beginning of the input buffer.
-
#next_word_boundary(index) ⇒ Object
Finds the end offset of the word after
index. -
#previous_word_boundary(index) ⇒ Object
Finds the start offset of the word before
index. -
#recall_next_history ⇒ Object
Replaces input with the next history entry or restores the saved draft.
-
#recall_previous_history ⇒ Object
Replaces input with the previous history entry, preserving the draft first.
-
#remove_last_attachment ⇒ Object
Removes the most recently added attachment.
-
#replace_input(value) ⇒ Object
Replaces the full input buffer and places the cursor at the end.
-
#reset_history_navigation ⇒ Object
Leaves history navigation and clears the saved draft/index state.
-
#word_separator?(char) ⇒ Boolean
Treats whitespace as the only word separator for composer navigation.
-
#yank_kill_buffer ⇒ Object
Inserts the last killed text at the cursor.
Constructor Details
#initialize ⇒ ComposerState
Returns a new instance of ComposerState.
24 25 26 27 28 29 30 31 32 33 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 24 def initialize @input = +"" @cursor = 0 @attachments = [] @kill_buffer = "" @history = [] @history_index = nil @history_draft = nil @prefill_input = nil end |
Instance Attribute Details
#attachments ⇒ Array<Hash> (readonly)
Returns pending image/file attachments submitted with the next turn.
20 21 22 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 20 def @attachments end |
#cursor ⇒ Integer
Returns cursor offset into input.
10 11 12 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 10 def cursor @cursor end |
#history ⇒ Array<String> (readonly)
Returns submitted input history.
22 23 24 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 22 def history @history end |
#history_draft ⇒ String?
Returns draft restored after leaving history navigation.
16 17 18 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 16 def history_draft @history_draft end |
#history_index ⇒ Integer?
Returns active history index while navigating history.
14 15 16 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 14 def history_index @history_index end |
#input ⇒ String
Returns editable text currently shown in the composer.
8 9 10 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 8 def input @input end |
#kill_buffer ⇒ String
Returns most recently killed text available for yank.
12 13 14 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 12 def kill_buffer @kill_buffer end |
#prefill_input ⇒ String?
Returns text queued for the next composer prompt.
18 19 20 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 18 def prefill_input @prefill_input end |
Instance Method Details
#add_attachment(attachment) ⇒ Object
Adds one attachment unless its source is already pending.
41 42 43 44 45 46 47 48 49 50 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 41 def () return false unless .respond_to?(:key?) source = [:source_text] || ["source_text"] || [:original_path] || ["original_path"] return false if source.to_s.empty? return false if @attachments.any? { |item| (item[:source_text] || item["source_text"]).to_s == source.to_s } @attachments << true end |
#add_history(value) ⇒ Object
Stores a submitted input unless it is blank or duplicates the previous entry.
184 185 186 187 188 189 190 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 184 def add_history(value) stripped = value.to_s.strip return if stripped.empty? return if @history.last == value @history << value end |
#clear_attachments ⇒ Object
Removes all pending attachments without changing text input.
36 37 38 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 36 def @attachments.clear end |
#cursor_logical_position ⇒ Object
Returns [row, column] for cursor placement in multi-line input.
178 179 180 181 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 178 def cursor_logical_position before_cursor = @input[0...@cursor] [before_cursor.count("\n"), (before_cursor.split("\n", -1).last || "").length] end |
#delete_at_cursor ⇒ Object
Deletes one character at the cursor without moving it.
78 79 80 81 82 83 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 78 def delete_at_cursor return false unless @cursor < @input.length @input = @input[0...@cursor] + @input[(@cursor + 1)..] true end |
#delete_before_cursor ⇒ Object
Deletes one character before the cursor.
69 70 71 72 73 74 75 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 69 def delete_before_cursor return false if @cursor.zero? @input = @input[0...(@cursor - 1)] + @input[@cursor..] @cursor -= 1 true end |
#delete_word_after_cursor ⇒ Object
Kills the word after the cursor into kill_buffer.
121 122 123 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 121 def delete_word_after_cursor kill_range(@cursor, next_word_boundary(@cursor)) end |
#delete_word_before_cursor ⇒ Object
Kills the word before the cursor into kill_buffer.
116 117 118 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 116 def delete_word_before_cursor kill_range(previous_word_boundary(@cursor), @cursor) end |
#insert_string(string) ⇒ Object
Inserts text at the cursor and advances by the inserted length.
61 62 63 64 65 66 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 61 def insert_string(string) return if string.empty? @input = @input[0...@cursor] + string + @input[@cursor..] @cursor += string.length end |
#kill_line_after_cursor ⇒ Object
Kills all text after the cursor into kill_buffer.
131 132 133 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 131 def kill_line_after_cursor kill_range(@cursor, @input.length) end |
#kill_line_before_cursor ⇒ Object
Kills all text before the cursor into kill_buffer.
126 127 128 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 126 def kill_line_before_cursor kill_range(0, @cursor) end |
#kill_range(start_index, end_index) ⇒ Object
Removes a range, stores it in kill_buffer, and moves the cursor to the start.
136 137 138 139 140 141 142 143 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 136 def kill_range(start_index, end_index) return false if start_index == end_index @kill_buffer = @input[start_index...end_index].to_s @input = @input[0...start_index].to_s + @input[end_index..].to_s @cursor = start_index true end |
#move_cursor_left ⇒ Object
Moves the cursor one character left when possible.
86 87 88 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 86 def move_cursor_left @cursor -= 1 if @cursor.positive? end |
#move_cursor_right ⇒ Object
Moves the cursor one character right when possible.
91 92 93 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 91 def move_cursor_right @cursor += 1 if @cursor < @input.length end |
#move_to_end_of_line ⇒ Object
Moves the cursor to the end of the input buffer.
101 102 103 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 101 def move_to_end_of_line @cursor = @input.length end |
#move_to_next_word ⇒ Object
Moves the cursor to the next word boundary.
111 112 113 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 111 def move_to_next_word @cursor = next_word_boundary(@cursor) end |
#move_to_previous_word ⇒ Object
Moves the cursor to the previous word boundary.
106 107 108 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 106 def move_to_previous_word @cursor = previous_word_boundary(@cursor) end |
#move_to_start_of_line ⇒ Object
Moves the cursor to the beginning of the input buffer.
96 97 98 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 96 def move_to_start_of_line @cursor = 0 end |
#next_word_boundary(index) ⇒ Object
Finds the end offset of the word after index.
159 160 161 162 163 164 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 159 def next_word_boundary(index) cursor = index cursor += 1 while cursor < @input.length && word_separator?(@input[cursor]) cursor += 1 while cursor < @input.length && !word_separator?(@input[cursor]) cursor end |
#previous_word_boundary(index) ⇒ Object
Finds the start offset of the word before index.
151 152 153 154 155 156 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 151 def previous_word_boundary(index) cursor = index cursor -= 1 while cursor.positive? && word_separator?(@input[cursor - 1]) cursor -= 1 while cursor.positive? && !word_separator?(@input[cursor - 1]) cursor end |
#recall_next_history ⇒ Object
Replaces input with the next history entry or restores the saved draft.
202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 202 def recall_next_history return if @history_index.nil? if @history_index < @history.length - 1 @history_index += 1 replace_input(@history[@history_index]) else replace_input(@history_draft || "") end end |
#recall_previous_history ⇒ Object
Replaces input with the previous history entry, preserving the draft first.
193 194 195 196 197 198 199 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 193 def recall_previous_history return if @history.empty? @history_draft = @input if @history_index.nil? @history_index = @history_index.nil? ? @history.length - 1 : [@history_index - 1, 0].max replace_input(@history[@history_index]) end |
#remove_last_attachment ⇒ Object
Removes the most recently added attachment.
53 54 55 56 57 58 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 53 def return false if @attachments.empty? @attachments.pop true end |
#replace_input(value) ⇒ Object
Replaces the full input buffer and places the cursor at the end.
172 173 174 175 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 172 def replace_input(value) @input = value.to_s @cursor = @input.length end |
#reset_history_navigation ⇒ Object
Leaves history navigation and clears the saved draft/index state.
215 216 217 218 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 215 def @history_index = nil @history_draft = nil end |
#word_separator?(char) ⇒ Boolean
Treats whitespace as the only word separator for composer navigation.
167 168 169 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 167 def word_separator?(char) char.to_s.match?(/\s/) end |
#yank_kill_buffer ⇒ Object
Inserts the last killed text at the cursor.
146 147 148 |
# File 'lib/kward/prompt_interface/composer_state.rb', line 146 def yank_kill_buffer insert_string(@kill_buffer.to_s) unless @kill_buffer.to_s.empty? end |