reline 0.6.1 → 0.6.2

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: 2fb74f487afccdfb3b0530a043cfb7090f2a4860f2fdd168bc94112818b5f57d
4
- data.tar.gz: 96b74e0f611f24022f204e9551d8692ef017c52a197ae169fbfdc1074a130857
3
+ metadata.gz: ec7aa526103ceb5eff3fa7dbbfff8c33f296f9cfb28ec4cc925b28e649dc18c8
4
+ data.tar.gz: 5c86a58b7769f390a81e9f6ca19a1e64eefad4ad05091544e5a01ef752b21983
5
5
  SHA512:
6
- metadata.gz: ffdcec13818f2445bd9f639e75b36405c76a439378335fa7c05fad90a26f06965e54cd9dce1b8e1411e16df9ffc80c3c0ac356320654af2ebd40a33fd28cb247
7
- data.tar.gz: 24be10266aebce2d07f1519010f6ce0e6b92b816b17e526ede204943880b54388aa5ebf5da086bde0212b5e1f837936e4972c09a57a2d6c94f7c9a41412966d9
6
+ metadata.gz: f4e586ed0f631e402d0b4b58fb05f0eec016f1290624021e957de1ced06c15e8638dac34e91c72d4b53a83e2c6b5eb5aadec2b749271d47201773dd220c63827
7
+ data.tar.gz: 6dcd53d5a30722bb4884f79eb9c70f49ab267b5e285b231237d339a52efdaa597377d308a264ed2cef23802b27aabb38d5ccbfd0c2dce40d631e15a6da5ede68
data/lib/reline/config.rb CHANGED
@@ -177,6 +177,11 @@ class Reline::Config
177
177
  if_stack = []
178
178
 
179
179
  lines.each_with_index do |line, no|
180
+ # Even after encoding conversion, we need to verify the encoding is valid
181
+ # as some invalid byte sequences might pass through the conversion.
182
+ unless line.valid_encoding?
183
+ raise InvalidInputrc, "#{file}:#{no + 1}: can't be converted to the locale #{Reline.encoding_system_needs.name}"
184
+ end
180
185
  next if line.match(/\A\s*#/)
181
186
 
182
187
  no += 1
@@ -124,6 +124,10 @@ class Reline::ANSI < Reline::IO
124
124
  Reline.core.line_editor.handle_signal
125
125
  end
126
126
  c = @input.getbyte
127
+
128
+ # When "Escape non-ASCII Input with Control-V" is enabled in macOS Terminal.app,
129
+ # all non-ascii bytes are automatically escaped with `C-v`.
130
+ # "\xE3\x81\x82" (U+3042) becomes "\x16\xE3\x16\x81\x16\x82".
127
131
  (c == 0x16 && @input.tty? && @input.raw(min: 0, time: 0, &:getbyte)) || c
128
132
  rescue Errno::EIO
129
133
  # Maybe the I/O has been closed.
@@ -180,14 +184,14 @@ class Reline::ANSI < Reline::IO
180
184
  s = [ENV["LINES"].to_i, ENV["COLUMNS"].to_i]
181
185
  return s if s[0] > 0 && s[1] > 0
182
186
  [24, 80]
183
- rescue Errno::ENOTTY, Errno::ENODEV
187
+ rescue SystemCallError
184
188
  [24, 80]
185
189
  end
186
190
 
187
191
  def set_screen_size(rows, columns)
188
192
  @input.winsize = [rows, columns]
189
193
  self
190
- rescue Errno::ENOTTY, Errno::ENODEV
194
+ rescue SystemCallError
191
195
  self
192
196
  end
193
197
 
@@ -295,7 +299,7 @@ class Reline::ANSI < Reline::IO
295
299
  # Signal.trap may raise an ArgumentError if the platform doesn't support the signal.
296
300
  end
297
301
 
298
- def read_single_char(keyseq_timeout)
302
+ def read_single_char(timeout_second)
299
303
  # Disable intr to read `C-c` `C-z` `C-\` for quoted insert
300
304
  @input.raw(intr: false) do
301
305
  super
data/lib/reline/io.rb CHANGED
@@ -37,10 +37,10 @@ module Reline
37
37
  end
38
38
 
39
39
  # Read a single encoding valid character from the input.
40
- def read_single_char(keyseq_timeout)
40
+ def read_single_char(timeout_second)
41
41
  buffer = String.new(encoding: Encoding::ASCII_8BIT)
42
42
  loop do
43
- timeout = buffer.empty? ? Float::INFINITY : keyseq_timeout
43
+ timeout = buffer.empty? ? Float::INFINITY : timeout_second
44
44
  c = getc(timeout)
45
45
  return unless c
46
46
 
@@ -377,11 +377,11 @@ module Reline::KeyActor
377
377
  # 187 M-;
378
378
  nil,
379
379
  # 188 M-<
380
- nil,
380
+ :beginning_of_history,
381
381
  # 189 M-=
382
382
  nil,
383
383
  # 190 M->
384
- nil,
384
+ :end_of_history,
385
385
  # 191 M-?
386
386
  nil,
387
387
  # 192 M-@
@@ -470,14 +470,6 @@ class Reline::LineEditor
470
470
  end
471
471
  end
472
472
 
473
- def print_nomultiline_prompt
474
- Reline::IOGate.disable_auto_linewrap(true) if Reline::IOGate.win?
475
- # Readline's test `TestRelineAsReadline#test_readline` requires first output to be prompt, not cursor reset escape sequence.
476
- Reline::IOGate.write Reline::Unicode.strip_non_printing_start_end(@prompt) if @prompt && !@is_multiline
477
- ensure
478
- Reline::IOGate.disable_auto_linewrap(false) if Reline::IOGate.win?
479
- end
480
-
481
473
  def render
482
474
  wrapped_cursor_x, wrapped_cursor_y = wrapped_cursor_position
483
475
  new_lines = wrapped_prompt_and_input_lines.flatten(1)[screen_scroll_top, screen_height].map do |prompt, line|
@@ -1654,6 +1646,16 @@ class Reline::LineEditor
1654
1646
  end
1655
1647
  alias_method :next_history, :ed_next_history
1656
1648
 
1649
+ private def ed_beginning_of_history(key)
1650
+ move_history(0, line: :end, cursor: :end)
1651
+ end
1652
+ alias_method :beginning_of_history, :ed_beginning_of_history
1653
+
1654
+ private def ed_end_of_history(key)
1655
+ move_history(Reline::HISTORY.size, line: :end, cursor: :end)
1656
+ end
1657
+ alias_method :end_of_history, :ed_end_of_history
1658
+
1657
1659
  private def ed_newline(key)
1658
1660
  process_insert(force: true)
1659
1661
  if @is_multiline
@@ -129,7 +129,7 @@ class Reline::Unicode::EastAsianWidth
129
129
  [0x450, 1],
130
130
  [0x451, -1],
131
131
  [0x482, 1],
132
- [0x487, 0],
132
+ [0x489, 0],
133
133
  [0x590, 1],
134
134
  [0x5bd, 0],
135
135
  [0x5be, 1],
@@ -356,6 +356,7 @@ class Reline::Unicode::EastAsianWidth
356
356
  [0x109d, 0],
357
357
  [0x10ff, 1],
358
358
  [0x115f, 2],
359
+ [0x11ff, 0],
359
360
  [0x135c, 1],
360
361
  [0x135f, 0],
361
362
  [0x1711, 1],
@@ -411,8 +412,6 @@ class Reline::Unicode::EastAsianWidth
411
412
  [0x1a7e, 1],
412
413
  [0x1a7f, 0],
413
414
  [0x1aaf, 1],
414
- [0x1abd, 0],
415
- [0x1abe, 1],
416
415
  [0x1ace, 0],
417
416
  [0x1aff, 1],
418
417
  [0x1b03, 0],
@@ -491,10 +490,6 @@ class Reline::Unicode::EastAsianWidth
491
490
  [0x20ab, 1],
492
491
  [0x20ac, -1],
493
492
  [0x20cf, 1],
494
- [0x20dc, 0],
495
- [0x20e0, 1],
496
- [0x20e1, 0],
497
- [0x20e4, 1],
498
493
  [0x20f0, 0],
499
494
  [0x2102, 1],
500
495
  [0x2103, -1],
@@ -767,7 +762,7 @@ class Reline::Unicode::EastAsianWidth
767
762
  [0xa48f, 1],
768
763
  [0xa4c6, 2],
769
764
  [0xa66e, 1],
770
- [0xa66f, 0],
765
+ [0xa672, 0],
771
766
  [0xa673, 1],
772
767
  [0xa67d, 0],
773
768
  [0xa69d, 1],
@@ -840,6 +835,10 @@ class Reline::Unicode::EastAsianWidth
840
835
  [0xabed, 0],
841
836
  [0xabff, 1],
842
837
  [0xd7a3, 2],
838
+ [0xd7af, 1],
839
+ [0xd7c6, 0],
840
+ [0xd7ca, 1],
841
+ [0xd7fb, 0],
843
842
  [0xdfff, 1],
844
843
  [0xf8ff, -1],
845
844
  [0xfaff, 2],
@@ -72,26 +72,32 @@ class Reline::Unicode
72
72
 
73
73
  require 'reline/unicode/east_asian_width'
74
74
 
75
+ def self.east_asian_width(ord)
76
+ chunk_index = EastAsianWidth::CHUNK_LAST.bsearch_index { |o| ord <= o }
77
+ size = EastAsianWidth::CHUNK_WIDTH[chunk_index]
78
+ size == -1 ? Reline.ambiguous_width : size
79
+ end
80
+
75
81
  def self.get_mbchar_width(mbchar)
76
82
  ord = mbchar.ord
77
83
  if ord <= 0x1F # in EscapedPairs
78
84
  return 2
79
- elsif ord <= 0x7E # printable ASCII chars
85
+ elsif mbchar.length == 1 && ord <= 0x7E # printable ASCII chars
80
86
  return 1
81
87
  end
88
+
82
89
  utf8_mbchar = mbchar.encode(Encoding::UTF_8)
83
- ord = utf8_mbchar.ord
84
- chunk_index = EastAsianWidth::CHUNK_LAST.bsearch_index { |o| ord <= o }
85
- size = EastAsianWidth::CHUNK_WIDTH[chunk_index]
86
- if size == -1
87
- Reline.ambiguous_width
88
- elsif size == 1 && utf8_mbchar.size >= 2
89
- second_char_ord = utf8_mbchar[1].ord
90
- # Halfwidth Dakuten Handakuten
91
- # Only these two character has Letter Modifier category and can be combined in a single grapheme cluster
92
- (second_char_ord == 0xFF9E || second_char_ord == 0xFF9F) ? 2 : 1
93
- else
94
- size
90
+ zwj = false
91
+ utf8_mbchar.chars.sum do |c|
92
+ if zwj
93
+ zwj = false
94
+ 0
95
+ elsif c.ord == 0x200D # Zero Width Joiner
96
+ zwj = true
97
+ 0
98
+ else
99
+ east_asian_width(c.ord)
100
+ end
95
101
  end
96
102
  end
97
103
 
@@ -214,7 +220,7 @@ class Reline::Unicode
214
220
  next
215
221
  elsif padding && !cover_begin && prev_width < start_col && start_col < total_width
216
222
  # Add preceding padding. This padding might have background color.
217
- chunk << ' '
223
+ chunk << ' ' * (total_width - start_col)
218
224
  chunk_start_col ||= start_col
219
225
  chunk_end_col = total_width
220
226
  next
@@ -228,7 +234,7 @@ class Reline::Unicode
228
234
  # Current character exceeds end_col
229
235
  if padding && end_col < total_width
230
236
  # Add succeeding padding. This padding might have background color.
231
- chunk << ' '
237
+ chunk << ' ' * (end_col - prev_width)
232
238
  chunk_start_col ||= prev_width
233
239
  chunk_end_col = end_col
234
240
  end
@@ -1,3 +1,3 @@
1
1
  module Reline
2
- VERSION = '0.6.1'
2
+ VERSION = '0.6.2'
3
3
  end
data/lib/reline.rb CHANGED
@@ -324,8 +324,6 @@ module Reline
324
324
  line_editor.auto_indent_proc = auto_indent_proc
325
325
  line_editor.dig_perfect_match_proc = dig_perfect_match_proc
326
326
 
327
- # Readline calls pre_input_hook just after printing the first prompt.
328
- line_editor.print_nomultiline_prompt
329
327
  pre_input_hook&.call
330
328
 
331
329
  unless Reline::IOGate.dumb?
@@ -347,7 +345,8 @@ module Reline
347
345
  # io_gate is Reline::ANSI because the key :bracketed_paste_start is only assigned in Reline::ANSI
348
346
  key = Reline::Key.new(io_gate.read_bracketed_paste, :insert_multiline_text)
349
347
  when :quoted_insert, :ed_quoted_insert
350
- key = Reline::Key.new(io_gate.read_single_char(config.keyseq_timeout), :insert_raw_char)
348
+ char = io_gate.read_single_char(config.keyseq_timeout.fdiv(1000))
349
+ key = Reline::Key.new(char || '', :insert_raw_char)
351
350
  end
352
351
  line_editor.set_pasting_state(io_gate.in_pasting?)
353
352
  line_editor.update(key)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reline
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - aycabta
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-04-04 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: io-console
@@ -75,7 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
75
75
  - !ruby/object:Gem::Version
76
76
  version: '0'
77
77
  requirements: []
78
- rubygems_version: 3.6.3
78
+ rubygems_version: 3.6.7
79
79
  specification_version: 4
80
80
  summary: Alternative GNU Readline or Editline implementation by pure Ruby.
81
81
  test_files: []