Class: LLM::Repl::Input Private

Inherits:
Object
  • Object
show all
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
}
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
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.

[Curses::Key::ENTER, 10, 13]
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.

[Curses::Key::BACKSPACE, 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

Instance Method Summary collapse

Constructor Details

#initialize(agent, 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.

Parameters:



45
46
47
48
49
50
51
52
53
54
# File 'lib/llm/repl/input.rb', line 45

def initialize(agent, options = {})
  @agent = agent
  @provider = agent.llm.name
  @buffer = +""
  @cursor = 0
  @scroll = 0
  @height = options.fetch(:height, 3)
  @last_char_at = nil
  @paste = false
end

Instance Attribute Details

#bufferString (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.

Returns:

  • (String)


35
36
37
# File 'lib/llm/repl/input.rb', line 35

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.

Parameters:

  • bool (Boolean)


40
41
42
# File 'lib/llm/repl/input.rb', line 40

def paste=(value)
  @paste = value
end

Instance Method Details

#cursorInteger

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:

  • (Integer)


122
123
124
# File 'lib/llm/repl/input.rb', line 122

def cursor
  prompt.length + @cursor
end

#cursor_posArray(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.

Returns:

  • (Array(Integer, Integer))


147
148
149
150
151
152
153
# File 'lib/llm/repl/input.rb', line 147

def cursor_pos
  scroll!
  before = to_s[0...cursor]
  line  = before.count("\n")
  col   = cursor - (before.rindex("\n") || -1) - 1
  [line - @scroll, col]
end

#deletevoid

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.



195
196
197
198
# File 'lib/llm/repl/input.rb', line 195

def delete
  @buffer[@cursor] = ""
  @cursor = [0, @cursor].max
end

#heightInteger

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:

  • (Integer)


128
129
130
# File 'lib/llm/repl/input.rb', line 128

def height
  @height
end

#killvoid

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.



187
188
189
190
191
# File 'lib/llm/repl/input.rb', line 187

def kill
  @copy = @buffer.slice(@cursor, @buffer.size)
  @buffer[@cursor, @buffer.size] = ""
  @cursor = @buffer.size
end

#linesArray<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.

Returns:

  • (Array<String>)


137
138
139
140
141
# File 'lib/llm/repl/input.rb', line 137

def lines
  scroll!
  chunks = to_s.split("\n", -1)
  chunks[@scroll, height] || []
end

#move_endvoid

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.



163
164
165
# File 'lib/llm/repl/input.rb', line 163

def move_end
  @cursor = [0, @buffer.size].max
end

#move_forwardvoid

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.



181
182
183
# File 'lib/llm/repl/input.rb', line 181

def move_forward
  @cursor = [0, @cursor + 1].max
end

#move_leftvoid

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.



169
170
171
# File 'lib/llm/repl/input.rb', line 169

def move_left
  @cursor = [@cursor - 1, 0].max
end

#move_rightvoid

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.



175
176
177
# File 'lib/llm/repl/input.rb', line 175

def move_right
  @cursor = [@cursor + 1, @buffer.size].min
end

#move_startvoid

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.



157
158
159
# File 'lib/llm/repl/input.rb', line 157

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.

Parameters:

Returns:

  • (Symbol, nil)


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
# File 'lib/llm/repl/input.rb', line 60

def on_char(window, char, now)
  is_paste = lambda { @last_char_at and (now - @last_char_at) < PASTE_THRESHOLD }
  if ESC == char
    @agent.cancel!
  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.include?(char)
    backspace
    :backspace
  elsif ENTER.include?(char)
    if @paste = is_paste.()
      insert("\n")
      :char
    else
      :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
  @last_char_at = now if char
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.

Returns:

  • (Boolean)


220
221
222
# File 'lib/llm/repl/input.rb', line 220

def paste?
  @paste
end

#restorevoid

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.



202
203
204
205
206
# File 'lib/llm/repl/input.rb', line 202

def restore
  return unless @copy
  @buffer.insert(@cursor, @copy)
  @cursor += @copy.size
end

#takeString

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:

  • (String)


210
211
212
213
214
215
216
# File 'lib/llm/repl/input.rb', line 210

def take
  @buffer.dup.tap do
    @buffer.clear
    @cursor = 0
    @scroll = 0
  end
end

#to_sString

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:

  • (String)


116
117
118
# File 'lib/llm/repl/input.rb', line 116

def to_s
  "#{@provider}> #{@buffer}"
end