reline 0.5.9 → 0.5.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -54,53 +54,44 @@ class Reline::Unicode
54
54
  }.join
55
55
  end
56
56
 
57
- require 'reline/unicode/east_asian_width'
57
+ def self.safe_encode(str, encoding)
58
+ # Reline only supports utf-8 convertible string.
59
+ converted = str.encode(encoding, invalid: :replace, undef: :replace)
60
+ return converted if str.encoding == Encoding::UTF_8 || converted.encoding == Encoding::UTF_8 || converted.ascii_only?
58
61
 
59
- HalfwidthDakutenHandakuten = /[\u{FF9E}\u{FF9F}]/
62
+ # This code is essentially doing the same thing as
63
+ # `str.encode(utf8, **replace_options).encode(encoding, **replace_options)`
64
+ # but also avoids unneccesary irreversible encoding conversion.
65
+ converted.gsub(/\X/) do |c|
66
+ c.encode(Encoding::UTF_8)
67
+ c
68
+ rescue Encoding::UndefinedConversionError
69
+ '?'
70
+ end
71
+ end
60
72
 
61
- MBCharWidthRE = /
62
- (?<width_2_1>
63
- [#{ EscapedChars.map {|c| "\\x%02x" % c.ord }.join }] (?# ^ + char, such as ^M, ^H, ^[, ...)
64
- )
65
- | (?<width_3>^\u{2E3B}) (?# THREE-EM DASH)
66
- | (?<width_0>^\p{M})
67
- | (?<width_2_2>
68
- #{ EastAsianWidth::TYPE_F }
69
- | #{ EastAsianWidth::TYPE_W }
70
- )
71
- | (?<width_1>
72
- #{ EastAsianWidth::TYPE_H }
73
- | #{ EastAsianWidth::TYPE_NA }
74
- | #{ EastAsianWidth::TYPE_N }
75
- )(?!#{ HalfwidthDakutenHandakuten })
76
- | (?<width_2_3>
77
- (?: #{ EastAsianWidth::TYPE_H }
78
- | #{ EastAsianWidth::TYPE_NA }
79
- | #{ EastAsianWidth::TYPE_N })
80
- #{ HalfwidthDakutenHandakuten }
81
- )
82
- | (?<ambiguous_width>
83
- #{EastAsianWidth::TYPE_A}
84
- )
85
- /x
73
+ require 'reline/unicode/east_asian_width'
86
74
 
87
75
  def self.get_mbchar_width(mbchar)
88
76
  ord = mbchar.ord
89
- if (0x00 <= ord and ord <= 0x1F) # in EscapedPairs
77
+ if ord <= 0x1F # in EscapedPairs
90
78
  return 2
91
- elsif (0x20 <= ord and ord <= 0x7E) # printable ASCII chars
79
+ elsif ord <= 0x7E # printable ASCII chars
92
80
  return 1
93
81
  end
94
- m = mbchar.encode(Encoding::UTF_8).match(MBCharWidthRE)
95
- case
96
- when m.nil? then 1 # TODO should be U+FFFD � REPLACEMENT CHARACTER
97
- when m[:width_2_1], m[:width_2_2], m[:width_2_3] then 2
98
- when m[:width_3] then 3
99
- when m[:width_0] then 0
100
- when m[:width_1] then 1
101
- when m[:ambiguous_width] then Reline.ambiguous_width
82
+ 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
102
93
  else
103
- nil
94
+ size
104
95
  end
105
96
  end
106
97
 
@@ -141,10 +132,8 @@ class Reline::Unicode
141
132
  case
142
133
  when non_printing_start
143
134
  in_zero_width = true
144
- lines.last << NON_PRINTING_START
145
135
  when non_printing_end
146
136
  in_zero_width = false
147
- lines.last << NON_PRINTING_END
148
137
  when csi
149
138
  lines.last << csi
150
139
  unless in_zero_width
@@ -156,7 +145,7 @@ class Reline::Unicode
156
145
  end
157
146
  when osc
158
147
  lines.last << osc
159
- seq << osc
148
+ seq << osc unless in_zero_width
160
149
  when gc
161
150
  unless in_zero_width
162
151
  mbchar_width = get_mbchar_width(gc)
@@ -179,6 +168,10 @@ class Reline::Unicode
179
168
  [lines, height]
180
169
  end
181
170
 
171
+ def self.strip_non_printing_start_end(prompt)
172
+ prompt.gsub(/\x01([^\x02]*)(?:\x02|\z)/) { $1 }
173
+ end
174
+
182
175
  # Take a chunk of a String cut by width with escape sequences.
183
176
  def self.take_range(str, start_col, max_width)
184
177
  take_mbchar_range(str, start_col, max_width).first
@@ -198,10 +191,8 @@ class Reline::Unicode
198
191
  case
199
192
  when non_printing_start
200
193
  in_zero_width = true
201
- chunk << NON_PRINTING_START
202
194
  when non_printing_end
203
195
  in_zero_width = false
204
- chunk << NON_PRINTING_END
205
196
  when csi
206
197
  has_csi = true
207
198
  chunk << csi
@@ -1,3 +1,3 @@
1
1
  module Reline
2
- VERSION = '0.5.9'
2
+ VERSION = '0.5.11'
3
3
  end
data/lib/reline.rb CHANGED
@@ -308,7 +308,7 @@ module Reline
308
308
  otio = io_gate.prep
309
309
 
310
310
  may_req_ambiguous_char_width
311
- line_editor.reset(prompt, encoding: encoding)
311
+ line_editor.reset(prompt)
312
312
  if multiline
313
313
  line_editor.multiline_on
314
314
  if block_given?
@@ -324,14 +324,17 @@ module Reline
324
324
  line_editor.prompt_proc = prompt_proc
325
325
  line_editor.auto_indent_proc = auto_indent_proc
326
326
  line_editor.dig_perfect_match_proc = dig_perfect_match_proc
327
+
328
+ # Readline calls pre_input_hook just after printing the first prompt.
329
+ line_editor.print_nomultiline_prompt
327
330
  pre_input_hook&.call
331
+
328
332
  unless Reline::IOGate.dumb?
329
333
  @dialog_proc_list.each_pair do |name_sym, d|
330
334
  line_editor.add_dialog_proc(name_sym, d.dialog_proc, d.context)
331
335
  end
332
336
  end
333
337
 
334
- line_editor.print_nomultiline_prompt(prompt)
335
338
  line_editor.update_dialogs
336
339
  line_editor.rerender
337
340
 
@@ -343,7 +346,7 @@ module Reline
343
346
  inputs.each do |key|
344
347
  if key.char == :bracketed_paste_start
345
348
  text = io_gate.read_bracketed_paste
346
- line_editor.insert_pasted_text(text)
349
+ line_editor.insert_multiline_text(text)
347
350
  line_editor.scroll_into_view
348
351
  else
349
352
  line_editor.update(key)
@@ -409,7 +412,7 @@ module Reline
409
412
  end
410
413
 
411
414
  private def may_req_ambiguous_char_width
412
- @ambiguous_width = 2 if io_gate.dumb? || !STDIN.tty? || !STDOUT.tty?
415
+ @ambiguous_width = 1 if io_gate.dumb? || !STDIN.tty? || !STDOUT.tty?
413
416
  return if defined? @ambiguous_width
414
417
  io_gate.move_cursor_column(0)
415
418
  begin
@@ -418,7 +421,7 @@ module Reline
418
421
  # LANG=C
419
422
  @ambiguous_width = 1
420
423
  else
421
- @ambiguous_width = io_gate.cursor_pos.x
424
+ @ambiguous_width = io_gate.cursor_pos.x == 2 ? 2 : 1
422
425
  end
423
426
  io_gate.move_cursor_column(0)
424
427
  io_gate.erase_after_cursor
@@ -457,8 +460,8 @@ module Reline
457
460
  def_single_delegator :line_editor, :byte_pointer, :point
458
461
  def_single_delegator :line_editor, :byte_pointer=, :point=
459
462
 
460
- def self.insert_text(*args, &block)
461
- line_editor.insert_text(*args, &block)
463
+ def self.insert_text(text)
464
+ line_editor.insert_multiline_text(text)
462
465
  self
463
466
  end
464
467
 
@@ -484,7 +487,7 @@ module Reline
484
487
  @core ||= Core.new { |core|
485
488
  core.config = Reline::Config.new
486
489
  core.key_stroke = Reline::KeyStroke.new(core.config)
487
- core.line_editor = Reline::LineEditor.new(core.config, core.encoding)
490
+ core.line_editor = Reline::LineEditor.new(core.config)
488
491
 
489
492
  core.basic_word_break_characters = " \t\n`><=;|&{("
490
493
  core.completer_word_break_characters = " \t\n`><=;|&{("
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reline
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.9
4
+ version: 0.5.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - aycabta
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-06-12 00:00:00.000000000 Z
10
+ date: 2024-11-08 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: io-console
@@ -63,7 +62,6 @@ metadata:
63
62
  bug_tracker_uri: https://github.com/ruby/reline/issues
64
63
  changelog_uri: https://github.com/ruby/reline/releases
65
64
  source_code_uri: https://github.com/ruby/reline
66
- post_install_message:
67
65
  rdoc_options: []
68
66
  require_paths:
69
67
  - lib
@@ -78,8 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
76
  - !ruby/object:Gem::Version
79
77
  version: '0'
80
78
  requirements: []
81
- rubygems_version: 3.5.9
82
- signing_key:
79
+ rubygems_version: 3.6.0.dev
83
80
  specification_version: 4
84
81
  summary: Alternative GNU Readline or Editline implementation by pure Ruby.
85
82
  test_files: []