reline 0.5.5 → 0.5.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 590a83a7301ffc23869017938e580376b9e3025130ebb0f102fa47d5ac9be28f
4
- data.tar.gz: 4652d400dba7e688591f1795e1c2a42b51ce4c9ad8381420c56e68c167034535
3
+ metadata.gz: a87d2a8f8718292be59386f13b873af0fa94cb20f6837761332174c413dc7755
4
+ data.tar.gz: 342c0dfbcf1e99af3c31ac4370f576e6a447728b2942328db1fc2a8a5b458b9e
5
5
  SHA512:
6
- metadata.gz: 9d3272d6b13d84818a895910d2a0201fa1629ea0dfc71037904a9c5f862c277866780df9aad323a5898941c9f2162fa2684892451617b30e7b9ec637ec3c143d
7
- data.tar.gz: 67004e4bf5b626ebf7d098750ffa7b198539ae8d344ad65b80f101faef0f0f57504e05cd2cd90a167feaea0f6a78c179abd1d698cecb29c290a7d2dbac3923ae
6
+ metadata.gz: 0031f7bd3660b7adda54149c1e15da1d1d2f9ef5c7e240828c9a1f3337d0c7bf2e1796c5ba6f61f1352c18819225697e4dd7c32149ff3297f65ddf0fd8f06e82
7
+ data.tar.gz: ea8bfe21ce43dbd3f1f6fa23d1d1a1948005cdda278485bba9010060f1ad1e3900c749e1a2966caf39f892c4c38692bc4abe8283425e3c3138e273f65b170ca9
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
@@ -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
@@ -235,7 +235,6 @@ class Reline::LineEditor
235
235
  @vi_waiting_operator_arg = nil
236
236
  @completion_journey_state = nil
237
237
  @completion_state = CompletionState::NORMAL
238
- @completion_occurs = false
239
238
  @perfect_matched = nil
240
239
  @menu_info = nil
241
240
  @searching_prompt = nil
@@ -284,7 +283,7 @@ class Reline::LineEditor
284
283
  indent1 = @auto_indent_proc.(@buffer_of_lines.take(@line_index - 1).push(''), @line_index - 1, 0, true)
285
284
  indent2 = @auto_indent_proc.(@buffer_of_lines.take(@line_index), @line_index - 1, @buffer_of_lines[@line_index - 1].bytesize, false)
286
285
  indent = indent2 || indent1
287
- @buffer_of_lines[@line_index - 1] = ' ' * indent + @buffer_of_lines[@line_index - 1].gsub(/\A */, '')
286
+ @buffer_of_lines[@line_index - 1] = ' ' * indent + @buffer_of_lines[@line_index - 1].gsub(/\A\s*/, '')
288
287
  )
289
288
  process_auto_indent @line_index, add_newline: true
290
289
  else
@@ -856,7 +855,7 @@ class Reline::LineEditor
856
855
  [target, preposing, completed, postposing]
857
856
  end
858
857
 
859
- private def complete(list, just_show_list)
858
+ private def perform_completion(list, just_show_list)
860
859
  case @completion_state
861
860
  when CompletionState::NORMAL
862
861
  @completion_state = CompletionState::COMPLETION
@@ -885,12 +884,12 @@ class Reline::LineEditor
885
884
  @completion_state = CompletionState::PERFECT_MATCH
886
885
  else
887
886
  @completion_state = CompletionState::MENU_WITH_PERFECT_MATCH
888
- complete(list, true) if @config.show_all_if_ambiguous
887
+ perform_completion(list, true) if @config.show_all_if_ambiguous
889
888
  end
890
889
  @perfect_matched = completed
891
890
  else
892
891
  @completion_state = CompletionState::MENU
893
- complete(list, true) if @config.show_all_if_ambiguous
892
+ perform_completion(list, true) if @config.show_all_if_ambiguous
894
893
  end
895
894
  if not just_show_list and target < completed
896
895
  @buffer_of_lines[@line_index] = (preposing + completed + completion_append_character.to_s + postposing).split("\n")[@line_index] || String.new(encoding: @encoding)
@@ -1065,10 +1064,6 @@ class Reline::LineEditor
1065
1064
  end
1066
1065
 
1067
1066
  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
1067
  @multibyte_buffer << key.combined_char
1073
1068
  if @multibyte_buffer.size > 1
1074
1069
  if @multibyte_buffer.dup.force_encoding(@encoding).valid_encoding?
@@ -1128,29 +1123,8 @@ class Reline::LineEditor
1128
1123
  old_lines = @buffer_of_lines.dup
1129
1124
  @first_char = false
1130
1125
  @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)
1126
+
1127
+ if key.char.is_a?(Symbol)
1154
1128
  process_key(key.char, key.char)
1155
1129
  else
1156
1130
  normal_char(key)
@@ -1331,6 +1305,16 @@ class Reline::LineEditor
1331
1305
  @confirm_multiline_termination_proc.(temp_buffer.join("\n") + "\n")
1332
1306
  end
1333
1307
 
1308
+ def insert_pasted_text(text)
1309
+ pre = @buffer_of_lines[@line_index].byteslice(0, @byte_pointer)
1310
+ post = @buffer_of_lines[@line_index].byteslice(@byte_pointer..)
1311
+ lines = (pre + text.gsub(/\r\n?/, "\n") + post).split("\n", -1)
1312
+ lines << '' if lines.empty?
1313
+ @buffer_of_lines[@line_index, 1] = lines
1314
+ @line_index += lines.size - 1
1315
+ @byte_pointer = @buffer_of_lines[@line_index].bytesize - post.bytesize
1316
+ end
1317
+
1334
1318
  def insert_text(text)
1335
1319
  if @buffer_of_lines[@line_index].bytesize == @byte_pointer
1336
1320
  @buffer_of_lines[@line_index] += text
@@ -1429,13 +1413,42 @@ class Reline::LineEditor
1429
1413
  end
1430
1414
  end
1431
1415
 
1432
- private def completion_journey_up(key)
1433
- if not @config.disable_completion and @config.autocompletion
1416
+ private def complete(_key)
1417
+ return if @config.disable_completion
1418
+
1419
+ process_insert(force: true)
1420
+ if @config.autocompletion
1434
1421
  @completion_state = CompletionState::NORMAL
1435
- @completion_occurs = move_completed_list(:up)
1422
+ @completion_occurs = move_completed_list(:down)
1423
+ else
1424
+ @completion_journey_state = nil
1425
+ result = call_completion_proc
1426
+ if result.is_a?(Array)
1427
+ @completion_occurs = true
1428
+ perform_completion(result, false)
1429
+ end
1436
1430
  end
1437
1431
  end
1438
- alias_method :menu_complete_backward, :completion_journey_up
1432
+
1433
+ private def completion_journey_move(direction)
1434
+ return if @config.disable_completion
1435
+
1436
+ process_insert(force: true)
1437
+ @completion_state = CompletionState::NORMAL
1438
+ @completion_occurs = move_completed_list(direction)
1439
+ end
1440
+
1441
+ private def menu_complete(_key)
1442
+ completion_journey_move(:down)
1443
+ end
1444
+
1445
+ private def menu_complete_backward(_key)
1446
+ completion_journey_move(:up)
1447
+ end
1448
+
1449
+ private def completion_journey_up(_key)
1450
+ completion_journey_move(:up) if @config.autocompletion
1451
+ end
1439
1452
 
1440
1453
  # Editline:: +ed-unassigned+ This editor command always results in an error.
1441
1454
  # GNU Readline:: There is no corresponding macro.
@@ -1904,7 +1917,7 @@ class Reline::LineEditor
1904
1917
  elsif !@config.autocompletion # show completed list
1905
1918
  result = call_completion_proc
1906
1919
  if result.is_a?(Array)
1907
- complete(result, true)
1920
+ perform_completion(result, true)
1908
1921
  end
1909
1922
  end
1910
1923
  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.6'
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.6
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-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: io-console