Class: RubyRich::LineEditor

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_rich/line_editor.rb

Constant Summary collapse

WORD_PATTERN =
/[^\s]+/

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(multiline: false, history: [], history_path: nil, max_history: 200) ⇒ LineEditor

Returns a new instance of LineEditor.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/ruby_rich/line_editor.rb', line 10

def initialize(multiline: false, history: [], history_path: nil, max_history: 200)
  @multiline = multiline
  @history_path = history_path
  @max_history = max_history
  @history = []
  @history_index = nil
  @chars = []
  @cursor = 0
  @value_cache = nil
  @lines_cache = nil
  @line_starts_cache = nil
  @cursor_line_col_cache_key = nil
  @cursor_line_col_cache = nil
  load_history
  history.each { |item| add_history(item, persist: false) }
end

Instance Attribute Details

#cursorObject (readonly)

Returns the value of attribute cursor.



7
8
9
# File 'lib/ruby_rich/line_editor.rb', line 7

def cursor
  @cursor
end

#historyObject (readonly)

Returns the value of attribute history.



7
8
9
# File 'lib/ruby_rich/line_editor.rb', line 7

def history
  @history
end

#history_pathObject

Returns the value of attribute history_path.



8
9
10
# File 'lib/ruby_rich/line_editor.rb', line 8

def history_path
  @history_path
end

#max_historyObject

Returns the value of attribute max_history.



8
9
10
# File 'lib/ruby_rich/line_editor.rb', line 8

def max_history
  @max_history
end

#multilineObject

Returns the value of attribute multiline.



8
9
10
# File 'lib/ruby_rich/line_editor.rb', line 8

def multiline
  @multiline
end

Instance Method Details

#add_history(text, persist: true) ⇒ Object



168
169
170
171
172
173
174
175
176
177
# File 'lib/ruby_rich/line_editor.rb', line 168

def add_history(text, persist: true)
  item = text.to_s
  return self if item.strip.empty?

  @history.delete(item)
  @history << item
  @history.shift while @history.length > @max_history
  persist_history if persist && @history_path
  self
end

#backspaceObject



68
69
70
71
72
73
74
75
# File 'lib/ruby_rich/line_editor.rb', line 68

def backspace
  return false if @cursor.zero?

  @chars.delete_at(@cursor - 1)
  @cursor -= 1
  invalidate_content_cache
  true
end

#buffer_endObject



115
116
117
118
119
# File 'lib/ruby_rich/line_editor.rb', line 115

def buffer_end
  @cursor = @chars.length
  invalidate_cursor_cache
  self
end

#buffer_startObject



109
110
111
112
113
# File 'lib/ruby_rich/line_editor.rb', line 109

def buffer_start
  @cursor = 0
  invalidate_cursor_cache
  self
end

#clearObject



43
44
45
46
47
48
49
# File 'lib/ruby_rich/line_editor.rb', line 43

def clear
  @chars.clear
  @cursor = 0
  @history_index = nil
  invalidate_content_cache
  self
end

#cursor_line_colObject



186
187
188
189
190
191
192
193
# File 'lib/ruby_rich/line_editor.rb', line 186

def cursor_line_col
  cache_key = [@cursor, @chars.length]
  return @cursor_line_col_cache if @cursor_line_col_cache_key == cache_key && @cursor_line_col_cache

  line_index = line_index_for_cursor
  @cursor_line_col_cache_key = cache_key
  @cursor_line_col_cache = [line_index, @cursor - line_starts[line_index]]
end

#deleteObject



77
78
79
80
81
82
83
# File 'lib/ruby_rich/line_editor.rb', line 77

def delete
  return false if @cursor >= @chars.length

  @chars.delete_at(@cursor)
  invalidate_content_cache
  true
end

#empty?Boolean

Returns:

  • (Boolean)


39
40
41
# File 'lib/ruby_rich/line_editor.rb', line 39

def empty?
  @chars.empty?
end

#endObject



103
104
105
106
107
# File 'lib/ruby_rich/line_editor.rb', line 103

def end
  @cursor = current_line_end
  invalidate_cursor_cache
  self
end

#homeObject



97
98
99
100
101
# File 'lib/ruby_rich/line_editor.rb', line 97

def home
  @cursor = current_line_start
  invalidate_cursor_cache
  self
end

#insert(text) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/ruby_rich/line_editor.rb', line 51

def insert(text)
  incoming = normalize_insert_text(text)
  return self if incoming.empty?

  new_chars = incoming.chars
  @chars.insert(@cursor, *new_chars)
  @cursor += new_chars.length
  @history_index = nil
  invalidate_content_cache
  self
end

#kill_to_endObject



133
134
135
136
137
138
139
# File 'lib/ruby_rich/line_editor.rb', line 133

def kill_to_end
  return false if @cursor >= @chars.length

  @chars.slice!(@cursor...current_line_end)
  invalidate_content_cache
  true
end

#kill_to_startObject



141
142
143
144
145
146
147
148
149
# File 'lib/ruby_rich/line_editor.rb', line 141

def kill_to_start
  start = current_line_start
  return false if @cursor <= start

  @chars.slice!(start...@cursor)
  @cursor = start
  invalidate_content_cache
  true
end

#kill_word_backObject



151
152
153
154
155
156
157
158
159
# File 'lib/ruby_rich/line_editor.rb', line 151

def kill_word_back
  return false if @cursor.zero?

  start = previous_word_start
  @chars.slice!(start...@cursor)
  @cursor = start
  invalidate_content_cache
  true
end

#linesObject



179
180
181
182
183
184
# File 'lib/ruby_rich/line_editor.rb', line 179

def lines
  @lines_cache ||= begin
    text = value
    text.empty? ? [""] : text.split("\n", -1)
  end
end

#move_downObject



127
128
129
130
131
# File 'lib/ruby_rich/line_editor.rb', line 127

def move_down
  return history_next if !@multiline || single_empty_line? || @history_index

  move_vertical(1)
end

#move_leftObject



85
86
87
88
89
# File 'lib/ruby_rich/line_editor.rb', line 85

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

#move_rightObject



91
92
93
94
95
# File 'lib/ruby_rich/line_editor.rb', line 91

def move_right
  @cursor = [@cursor + 1, @chars.length].min
  invalidate_cursor_cache
  self
end

#move_upObject



121
122
123
124
125
# File 'lib/ruby_rich/line_editor.rb', line 121

def move_up
  return history_previous if !@multiline || single_empty_line? || @history_index

  move_vertical(-1)
end

#newlineObject



63
64
65
66
# File 'lib/ruby_rich/line_editor.rb', line 63

def newline
  insert("\n") if @multiline
  self
end

#render_lines(width:, placeholder: nil, focused: true) ⇒ Object



195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/ruby_rich/line_editor.rb', line 195

def render_lines(width:, placeholder: nil, focused: true)
  content = value
  return [placeholder.to_s] if content.empty? && placeholder

  rendered = []
  line_index, col = cursor_line_col
  lines.each_with_index do |line, index|
    marker_col = focused && index == line_index ? col : nil
    rendered.concat(wrap_line_with_cursor(line, width, marker_col))
  end
  rendered.empty? ? [""] : rendered
end

#submit_valueObject



161
162
163
164
165
166
# File 'lib/ruby_rich/line_editor.rb', line 161

def submit_value
   = value
  add_history() unless .strip.empty?
  clear
  
end

#valueObject



27
28
29
# File 'lib/ruby_rich/line_editor.rb', line 27

def value
  @value_cache ||= @chars.join
end

#value=(text) ⇒ Object



31
32
33
34
35
36
37
# File 'lib/ruby_rich/line_editor.rb', line 31

def value=(text)
  @chars = text.to_s.chars
  @cursor = @chars.length
  @history_index = nil
  invalidate_content_cache
  self
end