reline 0.5.2 → 0.5.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -43,11 +43,13 @@ class Reline::Unicode
43
43
 
44
44
  def self.escape_for_print(str)
45
45
  str.chars.map! { |gr|
46
- escaped = EscapedPairs[gr.ord]
47
- if escaped && gr != -"\n" && gr != -"\t"
48
- escaped
49
- else
46
+ case gr
47
+ when -"\n"
50
48
  gr
49
+ when -"\t"
50
+ -' '
51
+ else
52
+ EscapedPairs[gr.ord] || gr
51
53
  end
52
54
  }.join
53
55
  end
@@ -128,10 +130,10 @@ class Reline::Unicode
128
130
  end
129
131
  end
130
132
 
131
- def self.split_by_width(str, max_width, encoding = str.encoding)
133
+ def self.split_by_width(str, max_width, encoding = str.encoding, offset: 0)
132
134
  lines = [String.new(encoding: encoding)]
133
135
  height = 1
134
- width = 0
136
+ width = offset
135
137
  rest = str.encode(Encoding::UTF_8)
136
138
  in_zero_width = false
137
139
  seq = String.new(encoding: encoding)
@@ -145,7 +147,13 @@ class Reline::Unicode
145
147
  lines.last << NON_PRINTING_END
146
148
  when csi
147
149
  lines.last << csi
148
- seq << csi
150
+ unless in_zero_width
151
+ if csi == -"\e[m" || csi == -"\e[0m"
152
+ seq.clear
153
+ else
154
+ seq << csi
155
+ end
156
+ end
149
157
  when osc
150
158
  lines.last << osc
151
159
  seq << osc
@@ -173,32 +181,78 @@ class Reline::Unicode
173
181
 
174
182
  # Take a chunk of a String cut by width with escape sequences.
175
183
  def self.take_range(str, start_col, max_width)
184
+ take_mbchar_range(str, start_col, max_width).first
185
+ end
186
+
187
+ def self.take_mbchar_range(str, start_col, width, cover_begin: false, cover_end: false, padding: false)
176
188
  chunk = String.new(encoding: str.encoding)
189
+
190
+ end_col = start_col + width
177
191
  total_width = 0
178
192
  rest = str.encode(Encoding::UTF_8)
179
193
  in_zero_width = false
194
+ chunk_start_col = nil
195
+ chunk_end_col = nil
196
+ has_csi = false
180
197
  rest.scan(WIDTH_SCANNER) do |non_printing_start, non_printing_end, csi, osc, gc|
181
198
  case
182
199
  when non_printing_start
183
200
  in_zero_width = true
201
+ chunk << NON_PRINTING_START
184
202
  when non_printing_end
185
203
  in_zero_width = false
204
+ chunk << NON_PRINTING_END
186
205
  when csi
206
+ has_csi = true
187
207
  chunk << csi
188
208
  when osc
189
209
  chunk << osc
190
210
  when gc
191
211
  if in_zero_width
192
212
  chunk << gc
213
+ next
214
+ end
215
+
216
+ mbchar_width = get_mbchar_width(gc)
217
+ prev_width = total_width
218
+ total_width += mbchar_width
219
+
220
+ if (cover_begin || padding ? total_width <= start_col : prev_width < start_col)
221
+ # Current character haven't reached start_col yet
222
+ next
223
+ elsif padding && !cover_begin && prev_width < start_col && start_col < total_width
224
+ # Add preceding padding. This padding might have background color.
225
+ chunk << ' '
226
+ chunk_start_col ||= start_col
227
+ chunk_end_col = total_width
228
+ next
229
+ elsif (cover_end ? prev_width < end_col : total_width <= end_col)
230
+ # Current character is in the range
231
+ chunk << gc
232
+ chunk_start_col ||= prev_width
233
+ chunk_end_col = total_width
234
+ break if total_width >= end_col
193
235
  else
194
- mbchar_width = get_mbchar_width(gc)
195
- total_width += mbchar_width
196
- break if (start_col + max_width) < total_width
197
- chunk << gc if start_col < total_width
236
+ # Current character exceeds end_col
237
+ if padding && end_col < total_width
238
+ # Add succeeding padding. This padding might have background color.
239
+ chunk << ' '
240
+ chunk_start_col ||= prev_width
241
+ chunk_end_col = end_col
242
+ end
243
+ break
198
244
  end
199
245
  end
200
246
  end
201
- chunk
247
+ chunk_start_col ||= start_col
248
+ chunk_end_col ||= start_col
249
+ if padding && chunk_end_col < end_col
250
+ # Append padding. This padding should not include background color.
251
+ chunk << "\e[0m" if has_csi
252
+ chunk << ' ' * (end_col - chunk_end_col)
253
+ chunk_end_col = end_col
254
+ end
255
+ [chunk, chunk_start_col, chunk_end_col - chunk_start_col]
202
256
  end
203
257
 
204
258
  def self.get_next_mbchar_size(line, byte_pointer)
@@ -1,3 +1,3 @@
1
1
  module Reline
2
- VERSION = '0.5.2'
2
+ VERSION = '0.5.8'
3
3
  end
data/lib/reline.rb CHANGED
@@ -225,17 +225,20 @@ module Reline
225
225
  journey_data = completion_journey_data
226
226
  return unless journey_data
227
227
 
228
- target = journey_data.list[journey_data.pointer]
228
+ target = journey_data.list.first
229
+ completed = journey_data.list[journey_data.pointer]
229
230
  result = journey_data.list.drop(1)
230
231
  pointer = journey_data.pointer - 1
231
- return if target.empty? || (result == [target] && pointer < 0)
232
+ return if completed.empty? || (result == [completed] && pointer < 0)
232
233
 
233
234
  target_width = Reline::Unicode.calculate_width(target)
234
- x = cursor_pos.x - target_width
235
- if x < 0
236
- x = screen_width + x
235
+ completed_width = Reline::Unicode.calculate_width(completed)
236
+ if cursor_pos.x <= completed_width - target_width
237
+ # When target is rendered on the line above cursor position
238
+ x = screen_width - completed_width
237
239
  y = -1
238
240
  else
241
+ x = [cursor_pos.x - completed_width, 0].max
239
242
  y = 0
240
243
  end
241
244
  cursor_pos_to_render = Reline::CursorPos.new(x, y)
@@ -309,6 +312,10 @@ module Reline
309
312
  $stderr.sync = true
310
313
  $stderr.puts "Reline is used by #{Process.pid}"
311
314
  end
315
+ unless config.test_mode or config.loaded?
316
+ config.read
317
+ io_gate.set_default_key_bindings(config)
318
+ end
312
319
  otio = io_gate.prep
313
320
 
314
321
  may_req_ambiguous_char_width
@@ -335,12 +342,6 @@ module Reline
335
342
  end
336
343
  end
337
344
 
338
- unless config.test_mode
339
- config.read
340
- config.reset_default_key_bindings
341
- io_gate.set_default_key_bindings(config)
342
- end
343
-
344
345
  line_editor.print_nomultiline_prompt(prompt)
345
346
  line_editor.update_dialogs
346
347
  line_editor.rerender
@@ -350,7 +351,15 @@ module Reline
350
351
  loop do
351
352
  read_io(config.keyseq_timeout) { |inputs|
352
353
  line_editor.set_pasting_state(io_gate.in_pasting?)
353
- inputs.each { |key| line_editor.update(key) }
354
+ inputs.each do |key|
355
+ if key.char == :bracketed_paste_start
356
+ text = io_gate.read_bracketed_paste
357
+ line_editor.insert_pasted_text(text)
358
+ line_editor.scroll_into_view
359
+ else
360
+ line_editor.update(key)
361
+ end
362
+ end
354
363
  }
355
364
  if line_editor.finished?
356
365
  line_editor.render_finished
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reline
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - aycabta
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-16 00:00:00.000000000 Z
11
+ date: 2024-05-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: io-console
@@ -76,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
78
  requirements: []
79
- rubygems_version: 3.5.3
79
+ rubygems_version: 3.5.9
80
80
  signing_key:
81
81
  specification_version: 4
82
82
  summary: Alternative GNU Readline or Editline implementation by pure Ruby.