Class: LLM::Repl::Input Private
- Inherits:
-
Object
- Object
- LLM::Repl::Input
- Defined in:
- lib/llm/repl/input.rb
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
The LLM::Repl::Input class manages the editable input line shown at the bottom of the REPL.
Constant Summary collapse
- CTRL =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
{ A: Curses::KEY_CTRL_A, E: Curses::KEY_CTRL_E, F: Curses::KEY_CTRL_F, K: Curses::KEY_CTRL_K, Y: Curses::KEY_CTRL_Y, D: Curses::KEY_CTRL_D, P: Curses::KEY_CTRL_P, N: Curses::KEY_CTRL_N }
- REPEATS =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
This hash tracks how many times a given key was pressed repeatedly without being interrupted by another key. The previous key is reset to 0 when a different key is pressed.
{}
- UP =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Curses::Key::UP
- DOWN =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Curses::Key::DOWN
- LEFT =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Curses::Key::LEFT
- RIGHT =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Curses::Key::RIGHT
- PGUP =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Curses::KEY_PPAGE
- PGDOWN =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Curses::KEY_NPAGE
- TAB =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
9- ESC =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
27- ENTER =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
10- BACKSPACE =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
127- PASTE_THRESHOLD =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Threshold in seconds. If characters arrive faster than this, we assume the user is pasting multi-line text. Human typing is ~150–300ms per key, so 50ms reliably distinguishes a paste from manual typing.
0.05
Instance Attribute Summary collapse
- #buffer ⇒ String readonly private
- #paste ⇒ void writeonly private
Instance Method Summary collapse
- #autocomplete ⇒ void private
- #cursor ⇒ Integer private
-
#cursor_pos ⇒ Array(Integer, Integer)
private
Returns the cursor position as [line, column] within the visible viewport.
- #delete ⇒ void private
- #height ⇒ Integer private
- #initialize(repl, options = {}) ⇒ LLM::Repl::Input constructor private
- #kill ⇒ void private
-
#lines ⇒ Array<String>
private
Returns the visible lines of the input buffer, split by newlines.
- #move_end ⇒ void private
- #move_forward ⇒ void private
- #move_left ⇒ void private
- #move_right ⇒ void private
- #move_start ⇒ void private
- #on_char(window, char, now) ⇒ Symbol? private
- #paste? ⇒ Boolean private
- #restore ⇒ void private
- #take ⇒ String private
- #to_s ⇒ String private
Constructor Details
#initialize(repl, options = {}) ⇒ LLM::Repl::Input
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/llm/repl/input.rb', line 59 def initialize(repl, = {}) @name = repl.name @agent = repl.agent @provider = @agent.llm.name @buffer = +"" @cursor = 0 @scroll = 0 @height = .fetch(:height, 3) @last_char_at = nil @memory = @agent..select(&:user?).map(&:content) @walker = Walker.new(@memory) @paste = false end |
Instance Attribute Details
#buffer ⇒ String (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
49 50 51 |
# File 'lib/llm/repl/input.rb', line 49 def buffer @buffer end |
#paste=(value) ⇒ void (writeonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
54 55 56 |
# File 'lib/llm/repl/input.rb', line 54 def paste=(value) @paste = value end |
Instance Method Details
#autocomplete ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/llm/repl/input.rb', line 230 def autocomplete return unless @buffer[0] == "/" ## # This method implements a simple autocomplete # that supports cycling through all known # commands. When given tab in quick succession, # we cycle to the nearest neighbour for the last # full match. However, it's not based on similarity, # it's just the next element in the array. keys = LLM::Command.registry.keys candidates = LLM::Command.complete(@buffer) if REPEATS[TAB] >= 1 candidate = keys[keys.index(candidates[0]) + 1] || keys[0] else candidate = candidates[0] end @buffer = "/#{candidate}" @cursor = @buffer.size end |
#cursor ⇒ Integer
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
165 166 167 |
# File 'lib/llm/repl/input.rb', line 165 def cursor prompt.size + @cursor end |
#cursor_pos ⇒ Array(Integer, Integer)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the cursor position as [line, column] within the visible viewport.
190 191 192 193 194 195 196 |
# File 'lib/llm/repl/input.rb', line 190 def cursor_pos scroll! before = to_s[0...cursor] line = before.count("\n") col = cursor - (before.rindex("\n") || -1) - 1 [line - @scroll, col] end |
#delete ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
260 261 262 263 |
# File 'lib/llm/repl/input.rb', line 260 def delete @buffer[@cursor] = "" @cursor = [0, @cursor].max end |
#height ⇒ Integer
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
171 172 173 |
# File 'lib/llm/repl/input.rb', line 171 def height @height end |
#kill ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
252 253 254 255 256 |
# File 'lib/llm/repl/input.rb', line 252 def kill @copy = @buffer.slice(@cursor, @buffer.size) @buffer[@cursor, @buffer.size] = "" @cursor = @buffer.size end |
#lines ⇒ Array<String>
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the visible lines of the input buffer, split by newlines. The viewport follows the cursor so the cursor line is always visible.
180 181 182 183 184 |
# File 'lib/llm/repl/input.rb', line 180 def lines scroll! chunks = to_s.split("\n", -1) chunks[@scroll, height] || [] end |
#move_end ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
206 207 208 |
# File 'lib/llm/repl/input.rb', line 206 def move_end @cursor = [0, @buffer.size].max end |
#move_forward ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
224 225 226 |
# File 'lib/llm/repl/input.rb', line 224 def move_forward @cursor = [0, @cursor + 1].max end |
#move_left ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
212 213 214 |
# File 'lib/llm/repl/input.rb', line 212 def move_left @cursor = [@cursor - 1, 0].max end |
#move_right ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
218 219 220 |
# File 'lib/llm/repl/input.rb', line 218 def move_right @cursor = [@cursor + 1, @buffer.size].min end |
#move_start ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
200 201 202 |
# File 'lib/llm/repl/input.rb', line 200 def move_start @cursor = 0 end |
#on_char(window, char, now) ⇒ Symbol?
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/llm/repl/input.rb', line 77 def on_char(window, char, now) is_paste = lambda { @last_char_at and (now - @last_char_at) < PASTE_THRESHOLD } if char and @char != char REPEATS[@char] = 0 end if PGUP == char (window.rows - 3).times { window.scroll_up } :pageup elsif PGDOWN == char (window.rows - 3).times { window.scroll_down } :pagedown elsif TAB == char autocomplete :tab elsif ESC == char @agent.cancel! elsif CTRL[:P] == char @buffer = @walker.prev.dup @cursor = @buffer.size :ctrl_p elsif CTRL[:N] == char @buffer = @walker.next.dup @cursor = @buffer.size :ctrl_n elsif CTRL[:D] == char delete :ctrl_d elsif CTRL[:A] == char move_start :ctrl_a elsif CTRL[:E] == char move_end :ctrl_e elsif CTRL[:F] == char move_forward :ctrl_f elsif CTRL[:Y] == char restore :ctrl_y elsif CTRL[:K] == char kill :ctrl_k elsif char == LEFT move_left :left elsif char == RIGHT move_right :right elsif BACKSPACE == char backspace :backspace elsif ENTER == char if @paste = is_paste.() insert("\n") :char else @memory.push(@buffer.dup) @walker.cursor = @memory.size :submit end elsif char == UP window.scroll_up :up elsif char == DOWN window.scroll_down :down elsif String === char insert(char) :char else nil end ensure if char REPEATS[char] += 1 @last_char_at = now @char = char end end |
#paste? ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
285 286 287 |
# File 'lib/llm/repl/input.rb', line 285 def paste? @paste end |
#restore ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
267 268 269 270 271 |
# File 'lib/llm/repl/input.rb', line 267 def restore return unless @copy @buffer.insert(@cursor, @copy) @cursor += @copy.size end |
#take ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
275 276 277 278 279 280 281 |
# File 'lib/llm/repl/input.rb', line 275 def take @buffer.dup.tap do @buffer.clear @cursor = 0 @scroll = 0 end end |
#to_s ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
159 160 161 |
# File 'lib/llm/repl/input.rb', line 159 def to_s "#{prompt}#{@buffer}" end |