reline 0.5.5 → 0.5.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 590a83a7301ffc23869017938e580376b9e3025130ebb0f102fa47d5ac9be28f
4
- data.tar.gz: 4652d400dba7e688591f1795e1c2a42b51ce4c9ad8381420c56e68c167034535
3
+ metadata.gz: 06a566ff8fc4daaf8ecee47eb28dac9e3e1a1d94fe05be5b9b9e1eb3a58228cc
4
+ data.tar.gz: 70b3aa5a4bcbf7fd7e564d47857f18717e49e2163ee5e5789d81f0bc246a2e17
5
5
  SHA512:
6
- metadata.gz: 9d3272d6b13d84818a895910d2a0201fa1629ea0dfc71037904a9c5f862c277866780df9aad323a5898941c9f2162fa2684892451617b30e7b9ec637ec3c143d
7
- data.tar.gz: 67004e4bf5b626ebf7d098750ffa7b198539ae8d344ad65b80f101faef0f0f57504e05cd2cd90a167feaea0f6a78c179abd1d698cecb29c290a7d2dbac3923ae
6
+ metadata.gz: e1eaf728bdb9be12e3d6fdba67a00651641426f7f70b6248360d47b7101d638d17b9ddbc70e20ad6fbd428dfcd69a6cb75e01bf4f9b20ebde16c3c5e2216231d
7
+ data.tar.gz: 28645bd429b1210b50875109c1fad90a5cd759e0411e99292ef1d785341b28ae851d144c3e1faeae994e42eaed735a71f8a94d5c74423085f1ac7d5ce72bdb72
data/lib/reline/ansi.rb CHANGED
@@ -45,6 +45,7 @@ class Reline::ANSI
45
45
  end
46
46
 
47
47
  def self.set_default_key_bindings(config, allow_terminfo: true)
48
+ set_bracketed_paste_key_bindings(config)
48
49
  set_default_key_bindings_ansi_cursor(config)
49
50
  if allow_terminfo && Reline::Terminfo.enabled?
50
51
  set_default_key_bindings_terminfo(config)
@@ -66,6 +67,12 @@ class Reline::ANSI
66
67
  end
67
68
  end
68
69
 
70
+ def self.set_bracketed_paste_key_bindings(config)
71
+ [:emacs, :vi_insert, :vi_command].each do |keymap|
72
+ config.add_default_key_binding_by_keymap(keymap, START_BRACKETED_PASTE.bytes, :bracketed_paste_start)
73
+ end
74
+ end
75
+
69
76
  def self.set_default_key_bindings_ansi_cursor(config)
70
77
  ANSI_CURSOR_KEY_BINDINGS.each do |char, (default_func, modifiers)|
71
78
  bindings = [["\e[#{char}", default_func]] # CSI + char
@@ -178,46 +185,26 @@ class Reline::ANSI
178
185
  nil
179
186
  end
180
187
 
181
- @@in_bracketed_paste_mode = false
182
- START_BRACKETED_PASTE = String.new("\e[200~,", encoding: Encoding::ASCII_8BIT)
183
- END_BRACKETED_PASTE = String.new("\e[200~.", encoding: Encoding::ASCII_8BIT)
184
- def self.getc_with_bracketed_paste(timeout_second)
188
+ START_BRACKETED_PASTE = String.new("\e[200~", encoding: Encoding::ASCII_8BIT)
189
+ END_BRACKETED_PASTE = String.new("\e[201~", encoding: Encoding::ASCII_8BIT)
190
+ def self.read_bracketed_paste
185
191
  buffer = String.new(encoding: Encoding::ASCII_8BIT)
186
- buffer << inner_getc(timeout_second)
187
- while START_BRACKETED_PASTE.start_with?(buffer) or END_BRACKETED_PASTE.start_with?(buffer) do
188
- if START_BRACKETED_PASTE == buffer
189
- @@in_bracketed_paste_mode = true
190
- return inner_getc(timeout_second)
191
- elsif END_BRACKETED_PASTE == buffer
192
- @@in_bracketed_paste_mode = false
193
- ungetc(-1)
194
- return inner_getc(timeout_second)
195
- end
196
- succ_c = inner_getc(Reline.core.config.keyseq_timeout)
197
-
198
- if succ_c
199
- buffer << succ_c
200
- else
201
- break
202
- end
192
+ until buffer.end_with?(END_BRACKETED_PASTE)
193
+ c = inner_getc(Float::INFINITY)
194
+ break unless c
195
+ buffer << c
203
196
  end
204
- buffer.bytes.reverse_each do |ch|
205
- ungetc ch
206
- end
207
- inner_getc(timeout_second)
197
+ string = buffer.delete_suffix(END_BRACKETED_PASTE).force_encoding(encoding)
198
+ string.valid_encoding? ? string : ''
208
199
  end
209
200
 
210
201
  # if the usage expects to wait indefinitely, use Float::INFINITY for timeout_second
211
202
  def self.getc(timeout_second)
212
- if Reline.core.config.enable_bracketed_paste
213
- getc_with_bracketed_paste(timeout_second)
214
- else
215
- inner_getc(timeout_second)
216
- end
203
+ inner_getc(timeout_second)
217
204
  end
218
205
 
219
206
  def self.in_pasting?
220
- @@in_bracketed_paste_mode or (not empty_buffer?)
207
+ not empty_buffer?
221
208
  end
222
209
 
223
210
  def self.empty_buffer?
@@ -361,11 +348,15 @@ class Reline::ANSI
361
348
  end
362
349
 
363
350
  def self.prep
351
+ # Enable bracketed paste
352
+ @@output.write "\e[?2004h" if Reline.core.config.enable_bracketed_paste
364
353
  retrieve_keybuffer
365
354
  nil
366
355
  end
367
356
 
368
357
  def self.deprep(otio)
358
+ # Disable bracketed paste
359
+ @@output.write "\e[?2004l" if Reline.core.config.enable_bracketed_paste
369
360
  Signal.trap('WINCH', @@old_winch_handler) if @@old_winch_handler
370
361
  end
371
362
  end
data/lib/reline/config.rb CHANGED
@@ -8,31 +8,12 @@ class Reline::Config
8
8
  end
9
9
 
10
10
  VARIABLE_NAMES = %w{
11
- bind-tty-special-chars
12
- blink-matching-paren
13
- byte-oriented
14
11
  completion-ignore-case
15
12
  convert-meta
16
13
  disable-completion
17
- enable-keypad
18
- expand-tilde
19
- history-preserve-point
20
14
  history-size
21
- horizontal-scroll-mode
22
- input-meta
23
15
  keyseq-timeout
24
- mark-directories
25
- mark-modified-lines
26
- mark-symlinked-directories
27
- match-hidden-files
28
- meta-flag
29
- output-meta
30
- page-completions
31
- prefer-visible-bell
32
- print-completions-horizontally
33
16
  show-all-if-ambiguous
34
- show-all-if-unmodified
35
- visible-stats
36
17
  show-mode-in-prompt
37
18
  vi-cmd-mode-string
38
19
  vi-ins-mode-string
@@ -70,6 +51,7 @@ class Reline::Config
70
51
  @autocompletion = false
71
52
  @convert_meta = true if seven_bit_encoding?(Reline::IOGate.encoding)
72
53
  @loaded = false
54
+ @enable_bracketed_paste = true
73
55
  end
74
56
 
75
57
  def reset
@@ -19,7 +19,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
19
19
  # 8 ^H
20
20
  :em_delete_prev_char,
21
21
  # 9 ^I
22
- :ed_unassigned,
22
+ :complete,
23
23
  # 10 ^J
24
24
  :ed_newline,
25
25
  # 11 ^K
@@ -63,7 +63,7 @@ class Reline::KeyActor::Emacs < Reline::KeyActor::Base
63
63
  # 30 ^^
64
64
  :ed_unassigned,
65
65
  # 31 ^_
66
- :ed_unassigned,
66
+ :undo,
67
67
  # 32 SPACE
68
68
  :ed_insert,
69
69
  # 33 !
@@ -19,7 +19,7 @@ class Reline::KeyActor::ViInsert < Reline::KeyActor::Base
19
19
  # 8 ^H
20
20
  :vi_delete_prev_char,
21
21
  # 9 ^I
22
- :ed_insert,
22
+ :complete,
23
23
  # 10 ^J
24
24
  :ed_newline,
25
25
  # 11 ^K
@@ -29,11 +29,11 @@ class Reline::KeyActor::ViInsert < Reline::KeyActor::Base
29
29
  # 13 ^M
30
30
  :ed_newline,
31
31
  # 14 ^N
32
- :ed_insert,
32
+ :menu_complete,
33
33
  # 15 ^O
34
34
  :ed_insert,
35
35
  # 16 ^P
36
- :ed_insert,
36
+ :menu_complete_backward,
37
37
  # 17 ^Q
38
38
  :ed_ignore,
39
39
  # 18 ^R
@@ -4,7 +4,6 @@ require 'reline/unicode'
4
4
  require 'tempfile'
5
5
 
6
6
  class Reline::LineEditor
7
- # TODO: undo
8
7
  # TODO: Use "private alias_method" idiom after drop Ruby 2.5.
9
8
  attr_reader :byte_pointer
10
9
  attr_accessor :confirm_multiline_termination_proc
@@ -75,7 +74,7 @@ class Reline::LineEditor
75
74
  def initialize(config, encoding)
76
75
  @config = config
77
76
  @completion_append_character = ''
78
- @screen_size = Reline::IOGate.get_screen_size
77
+ @screen_size = [0, 0] # Should be initialized with actual winsize in LineEditor#reset
79
78
  reset_variables(encoding: encoding)
80
79
  end
81
80
 
@@ -235,7 +234,6 @@ class Reline::LineEditor
235
234
  @vi_waiting_operator_arg = nil
236
235
  @completion_journey_state = nil
237
236
  @completion_state = CompletionState::NORMAL
238
- @completion_occurs = false
239
237
  @perfect_matched = nil
240
238
  @menu_info = nil
241
239
  @searching_prompt = nil
@@ -252,6 +250,8 @@ class Reline::LineEditor
252
250
  @resized = false
253
251
  @cache = {}
254
252
  @rendered_screen = RenderedScreen.new(base_y: 0, lines: [], cursor_y: 0)
253
+ @past_lines = []
254
+ @undoing = false
255
255
  reset_line
256
256
  end
257
257
 
@@ -284,7 +284,7 @@ class Reline::LineEditor
284
284
  indent1 = @auto_indent_proc.(@buffer_of_lines.take(@line_index - 1).push(''), @line_index - 1, 0, true)
285
285
  indent2 = @auto_indent_proc.(@buffer_of_lines.take(@line_index), @line_index - 1, @buffer_of_lines[@line_index - 1].bytesize, false)
286
286
  indent = indent2 || indent1
287
- @buffer_of_lines[@line_index - 1] = ' ' * indent + @buffer_of_lines[@line_index - 1].gsub(/\A */, '')
287
+ @buffer_of_lines[@line_index - 1] = ' ' * indent + @buffer_of_lines[@line_index - 1].gsub(/\A\s*/, '')
288
288
  )
289
289
  process_auto_indent @line_index, add_newline: true
290
290
  else
@@ -856,7 +856,7 @@ class Reline::LineEditor
856
856
  [target, preposing, completed, postposing]
857
857
  end
858
858
 
859
- private def complete(list, just_show_list)
859
+ private def perform_completion(list, just_show_list)
860
860
  case @completion_state
861
861
  when CompletionState::NORMAL
862
862
  @completion_state = CompletionState::COMPLETION
@@ -885,12 +885,12 @@ class Reline::LineEditor
885
885
  @completion_state = CompletionState::PERFECT_MATCH
886
886
  else
887
887
  @completion_state = CompletionState::MENU_WITH_PERFECT_MATCH
888
- complete(list, true) if @config.show_all_if_ambiguous
888
+ perform_completion(list, true) if @config.show_all_if_ambiguous
889
889
  end
890
890
  @perfect_matched = completed
891
891
  else
892
892
  @completion_state = CompletionState::MENU
893
- complete(list, true) if @config.show_all_if_ambiguous
893
+ perform_completion(list, true) if @config.show_all_if_ambiguous
894
894
  end
895
895
  if not just_show_list and target < completed
896
896
  @buffer_of_lines[@line_index] = (preposing + completed + completion_append_character.to_s + postposing).split("\n")[@line_index] || String.new(encoding: @encoding)
@@ -949,7 +949,8 @@ class Reline::LineEditor
949
949
  unless @waiting_proc
950
950
  byte_pointer_diff = @byte_pointer - old_byte_pointer
951
951
  @byte_pointer = old_byte_pointer
952
- send(@vi_waiting_operator, byte_pointer_diff)
952
+ method_obj = method(@vi_waiting_operator)
953
+ wrap_method_call(@vi_waiting_operator, method_obj, byte_pointer_diff)
953
954
  cleanup_waiting
954
955
  end
955
956
  else
@@ -1010,7 +1011,8 @@ class Reline::LineEditor
1010
1011
  if @vi_waiting_operator
1011
1012
  byte_pointer_diff = @byte_pointer - old_byte_pointer
1012
1013
  @byte_pointer = old_byte_pointer
1013
- send(@vi_waiting_operator, byte_pointer_diff)
1014
+ method_obj = method(@vi_waiting_operator)
1015
+ wrap_method_call(@vi_waiting_operator, method_obj, byte_pointer_diff)
1014
1016
  cleanup_waiting
1015
1017
  end
1016
1018
  @kill_ring.process
@@ -1065,10 +1067,6 @@ class Reline::LineEditor
1065
1067
  end
1066
1068
 
1067
1069
  private def normal_char(key)
1068
- if key.combined_char.is_a?(Symbol)
1069
- process_key(key.combined_char, key.combined_char)
1070
- return
1071
- end
1072
1070
  @multibyte_buffer << key.combined_char
1073
1071
  if @multibyte_buffer.size > 1
1074
1072
  if @multibyte_buffer.dup.force_encoding(@encoding).valid_encoding?
@@ -1111,6 +1109,7 @@ class Reline::LineEditor
1111
1109
  end
1112
1110
 
1113
1111
  def input_key(key)
1112
+ save_old_buffer
1114
1113
  @config.reset_oneshot_key_bindings
1115
1114
  @dialogs.each do |dialog|
1116
1115
  if key.char.instance_of?(Symbol) and key.char == dialog.name
@@ -1125,32 +1124,10 @@ class Reline::LineEditor
1125
1124
  finish
1126
1125
  return
1127
1126
  end
1128
- old_lines = @buffer_of_lines.dup
1129
1127
  @first_char = false
1130
1128
  @completion_occurs = false
1131
- if @config.editing_mode_is?(:emacs, :vi_insert) and key.char == "\C-i".ord
1132
- if !@config.disable_completion
1133
- process_insert(force: true)
1134
- if @config.autocompletion
1135
- @completion_state = CompletionState::NORMAL
1136
- @completion_occurs = move_completed_list(:down)
1137
- else
1138
- @completion_journey_state = nil
1139
- result = call_completion_proc
1140
- if result.is_a?(Array)
1141
- @completion_occurs = true
1142
- complete(result, false)
1143
- end
1144
- end
1145
- end
1146
- elsif @config.editing_mode_is?(:vi_insert) and ["\C-p".ord, "\C-n".ord].include?(key.char)
1147
- # In vi mode, move completed list even if autocompletion is off
1148
- if not @config.disable_completion
1149
- process_insert(force: true)
1150
- @completion_state = CompletionState::NORMAL
1151
- @completion_occurs = move_completed_list("\C-p".ord == key.char ? :up : :down)
1152
- end
1153
- elsif Symbol === key.char and respond_to?(key.char, true)
1129
+
1130
+ if key.char.is_a?(Symbol)
1154
1131
  process_key(key.char, key.char)
1155
1132
  else
1156
1133
  normal_char(key)
@@ -1160,12 +1137,15 @@ class Reline::LineEditor
1160
1137
  @completion_journey_state = nil
1161
1138
  end
1162
1139
 
1140
+ push_past_lines unless @undoing
1141
+ @undoing = false
1142
+
1163
1143
  if @in_pasting
1164
1144
  clear_dialogs
1165
1145
  return
1166
1146
  end
1167
1147
 
1168
- modified = old_lines != @buffer_of_lines
1148
+ modified = @old_buffer_of_lines != @buffer_of_lines
1169
1149
  if !@completion_occurs && modified && !@config.disable_completion && @config.autocompletion
1170
1150
  # Auto complete starts only when edited
1171
1151
  process_insert(force: true)
@@ -1174,6 +1154,26 @@ class Reline::LineEditor
1174
1154
  modified
1175
1155
  end
1176
1156
 
1157
+ def save_old_buffer
1158
+ @old_buffer_of_lines = @buffer_of_lines.dup
1159
+ @old_byte_pointer = @byte_pointer.dup
1160
+ @old_line_index = @line_index.dup
1161
+ end
1162
+
1163
+ def push_past_lines
1164
+ if @old_buffer_of_lines != @buffer_of_lines
1165
+ @past_lines.push([@old_buffer_of_lines, @old_byte_pointer, @old_line_index])
1166
+ end
1167
+ trim_past_lines
1168
+ end
1169
+
1170
+ MAX_PAST_LINES = 100
1171
+ def trim_past_lines
1172
+ if @past_lines.size > MAX_PAST_LINES
1173
+ @past_lines.shift
1174
+ end
1175
+ end
1176
+
1177
1177
  def scroll_into_view
1178
1178
  _wrapped_cursor_x, wrapped_cursor_y = wrapped_cursor_position
1179
1179
  if wrapped_cursor_y < screen_scroll_top
@@ -1250,6 +1250,18 @@ class Reline::LineEditor
1250
1250
  process_auto_indent
1251
1251
  end
1252
1252
 
1253
+ def set_current_lines(lines, byte_pointer = nil, line_index = 0)
1254
+ cursor = current_byte_pointer_cursor
1255
+ @buffer_of_lines = lines
1256
+ @line_index = line_index
1257
+ if byte_pointer
1258
+ @byte_pointer = byte_pointer
1259
+ else
1260
+ calculate_nearest_cursor(cursor)
1261
+ end
1262
+ process_auto_indent
1263
+ end
1264
+
1253
1265
  def retrieve_completion_block(set_completion_quote_character = false)
1254
1266
  if Reline.completer_word_break_characters.empty?
1255
1267
  word_break_regexp = nil
@@ -1331,6 +1343,18 @@ class Reline::LineEditor
1331
1343
  @confirm_multiline_termination_proc.(temp_buffer.join("\n") + "\n")
1332
1344
  end
1333
1345
 
1346
+ def insert_pasted_text(text)
1347
+ save_old_buffer
1348
+ pre = @buffer_of_lines[@line_index].byteslice(0, @byte_pointer)
1349
+ post = @buffer_of_lines[@line_index].byteslice(@byte_pointer..)
1350
+ lines = (pre + text.gsub(/\r\n?/, "\n") + post).split("\n", -1)
1351
+ lines << '' if lines.empty?
1352
+ @buffer_of_lines[@line_index, 1] = lines
1353
+ @line_index += lines.size - 1
1354
+ @byte_pointer = @buffer_of_lines[@line_index].bytesize - post.bytesize
1355
+ push_past_lines
1356
+ end
1357
+
1334
1358
  def insert_text(text)
1335
1359
  if @buffer_of_lines[@line_index].bytesize == @byte_pointer
1336
1360
  @buffer_of_lines[@line_index] += text
@@ -1429,13 +1453,42 @@ class Reline::LineEditor
1429
1453
  end
1430
1454
  end
1431
1455
 
1432
- private def completion_journey_up(key)
1433
- if not @config.disable_completion and @config.autocompletion
1456
+ private def complete(_key)
1457
+ return if @config.disable_completion
1458
+
1459
+ process_insert(force: true)
1460
+ if @config.autocompletion
1434
1461
  @completion_state = CompletionState::NORMAL
1435
- @completion_occurs = move_completed_list(:up)
1462
+ @completion_occurs = move_completed_list(:down)
1463
+ else
1464
+ @completion_journey_state = nil
1465
+ result = call_completion_proc
1466
+ if result.is_a?(Array)
1467
+ @completion_occurs = true
1468
+ perform_completion(result, false)
1469
+ end
1436
1470
  end
1437
1471
  end
1438
- alias_method :menu_complete_backward, :completion_journey_up
1472
+
1473
+ private def completion_journey_move(direction)
1474
+ return if @config.disable_completion
1475
+
1476
+ process_insert(force: true)
1477
+ @completion_state = CompletionState::NORMAL
1478
+ @completion_occurs = move_completed_list(direction)
1479
+ end
1480
+
1481
+ private def menu_complete(_key)
1482
+ completion_journey_move(:down)
1483
+ end
1484
+
1485
+ private def menu_complete_backward(_key)
1486
+ completion_journey_move(:up)
1487
+ end
1488
+
1489
+ private def completion_journey_up(_key)
1490
+ completion_journey_move(:up) if @config.autocompletion
1491
+ end
1439
1492
 
1440
1493
  # Editline:: +ed-unassigned+ This editor command always results in an error.
1441
1494
  # GNU Readline:: There is no corresponding macro.
@@ -1904,7 +1957,7 @@ class Reline::LineEditor
1904
1957
  elsif !@config.autocompletion # show completed list
1905
1958
  result = call_completion_proc
1906
1959
  if result.is_a?(Array)
1907
- complete(result, true)
1960
+ perform_completion(result, true)
1908
1961
  end
1909
1962
  end
1910
1963
  end
@@ -2474,4 +2527,15 @@ class Reline::LineEditor
2474
2527
  private def vi_editing_mode(key)
2475
2528
  @config.editing_mode = :vi_insert
2476
2529
  end
2530
+
2531
+ private def undo(_key)
2532
+ return if @past_lines.empty?
2533
+
2534
+ @undoing = true
2535
+
2536
+ target_lines, target_cursor_x, target_cursor_y = @past_lines.last
2537
+ set_current_lines(target_lines, target_cursor_x, target_cursor_y)
2538
+
2539
+ @past_lines.pop
2540
+ end
2477
2541
  end
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Reline
2
- VERSION = '0.5.5'
2
+ VERSION = '0.5.7'
3
3
  end
data/lib/reline.rb CHANGED
@@ -312,6 +312,10 @@ module Reline
312
312
  $stderr.sync = true
313
313
  $stderr.puts "Reline is used by #{Process.pid}"
314
314
  end
315
+ unless config.test_mode or config.loaded?
316
+ config.read
317
+ io_gate.set_default_key_bindings(config)
318
+ end
315
319
  otio = io_gate.prep
316
320
 
317
321
  may_req_ambiguous_char_width
@@ -338,11 +342,6 @@ module Reline
338
342
  end
339
343
  end
340
344
 
341
- unless config.test_mode or config.loaded?
342
- config.read
343
- io_gate.set_default_key_bindings(config)
344
- end
345
-
346
345
  line_editor.print_nomultiline_prompt(prompt)
347
346
  line_editor.update_dialogs
348
347
  line_editor.rerender
@@ -352,7 +351,15 @@ module Reline
352
351
  loop do
353
352
  read_io(config.keyseq_timeout) { |inputs|
354
353
  line_editor.set_pasting_state(io_gate.in_pasting?)
355
- 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
356
363
  }
357
364
  if line_editor.finished?
358
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.5
4
+ version: 0.5.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - aycabta
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-02 00:00:00.000000000 Z
11
+ date: 2024-05-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: io-console