diff options
author | Stan Lo <stan001212@gmail.com> | 2023-03-28 13:49:44 +0100 |
---|---|---|
committer | git <svn-admin@ruby-lang.org> | 2023-03-28 12:49:49 +0000 |
commit | 1e9a218ade3af90c18f42e3fea08e2fcea81222a (patch) | |
tree | 33531b5ca2e7d304f64a2947b1cf7717c683c60b | |
parent | 417b1a36447cb2c650de55b433ba623541fb8bb3 (diff) | |
download | ruby-1e9a218ade3af90c18f42e3fea08e2fcea81222a.tar.gz |
[ruby/reline] Expand the scanned array to later case statement more
straightforward
(https://github.com/ruby/reline/pull/526)
* Improve test coverage on Unicode.take_range
* Add test for Unicode.calculate_width
* Expand the scanned array to later case statement more straightforward
-rw-r--r-- | lib/reline/unicode.rb | 54 | ||||
-rw-r--r-- | test/reline/test_unicode.rb | 20 |
2 files changed, 43 insertions, 31 deletions
diff --git a/lib/reline/unicode.rb b/lib/reline/unicode.rb index de22d08581..1f0f6432c8 100644 --- a/lib/reline/unicode.rb +++ b/lib/reline/unicode.rb @@ -40,11 +40,6 @@ class Reline::Unicode CSI_REGEXP = /\e\[[\d;]*[ABCDEFGHJKSTfminsuhl]/ OSC_REGEXP = /\e\]\d+(?:;[^;]+)*\a/ WIDTH_SCANNER = /\G(?:(#{NON_PRINTING_START})|(#{NON_PRINTING_END})|(#{CSI_REGEXP})|(#{OSC_REGEXP})|(\X))/o - NON_PRINTING_START_INDEX = 0 - NON_PRINTING_END_INDEX = 1 - CSI_REGEXP_INDEX = 2 - OSC_REGEXP_INDEX = 3 - GRAPHEME_CLUSTER_INDEX = 4 def self.get_mbchar_byte_size_by_first_char(c) # Checks UTF-8 character byte size @@ -132,15 +127,14 @@ class Reline::Unicode width = 0 rest = str.encode(Encoding::UTF_8) in_zero_width = false - rest.scan(WIDTH_SCANNER) do |gc| + rest.scan(WIDTH_SCANNER) do |non_printing_start, non_printing_end, csi, osc, gc| case - when gc[NON_PRINTING_START_INDEX] + when non_printing_start in_zero_width = true - when gc[NON_PRINTING_END_INDEX] + when non_printing_end in_zero_width = false - when gc[CSI_REGEXP_INDEX], gc[OSC_REGEXP_INDEX] - when gc[GRAPHEME_CLUSTER_INDEX] - gc = gc[GRAPHEME_CLUSTER_INDEX] + when csi, osc + when gc unless in_zero_width width += get_mbchar_width(gc) end @@ -161,22 +155,21 @@ class Reline::Unicode rest = str.encode(Encoding::UTF_8) in_zero_width = false seq = String.new(encoding: encoding) - rest.scan(WIDTH_SCANNER) do |gc| + rest.scan(WIDTH_SCANNER) do |non_printing_start, non_printing_end, csi, osc, gc| case - when gc[NON_PRINTING_START_INDEX] + when non_printing_start in_zero_width = true lines.last << NON_PRINTING_START - when gc[NON_PRINTING_END_INDEX] + when non_printing_end in_zero_width = false lines.last << NON_PRINTING_END - when gc[CSI_REGEXP_INDEX] - lines.last << gc[CSI_REGEXP_INDEX] - seq << gc[CSI_REGEXP_INDEX] - when gc[OSC_REGEXP_INDEX] - lines.last << gc[OSC_REGEXP_INDEX] - seq << gc[OSC_REGEXP_INDEX] - when gc[GRAPHEME_CLUSTER_INDEX] - gc = gc[GRAPHEME_CLUSTER_INDEX] + when csi + lines.last << csi + seq << csi + when osc + lines.last << osc + seq << osc + when gc unless in_zero_width mbchar_width = get_mbchar_width(gc) if (width += mbchar_width) > max_width @@ -204,18 +197,17 @@ class Reline::Unicode total_width = 0 rest = str.encode(Encoding::UTF_8) in_zero_width = false - rest.scan(WIDTH_SCANNER) do |gc| + rest.scan(WIDTH_SCANNER) do |non_printing_start, non_printing_end, csi, osc, gc| case - when gc[NON_PRINTING_START_INDEX] + when non_printing_start in_zero_width = true - when gc[NON_PRINTING_END_INDEX] + when non_printing_end in_zero_width = false - when gc[CSI_REGEXP_INDEX] - chunk << gc[CSI_REGEXP_INDEX] - when gc[OSC_REGEXP_INDEX] - chunk << gc[OSC_REGEXP_INDEX] - when gc[GRAPHEME_CLUSTER_INDEX] - gc = gc[GRAPHEME_CLUSTER_INDEX] + when csi + chunk << csi + when osc + chunk << osc + when gc if in_zero_width chunk << gc else diff --git a/test/reline/test_unicode.rb b/test/reline/test_unicode.rb index 0a66fe64c0..ee8e72c0d4 100644 --- a/test/reline/test_unicode.rb +++ b/test/reline/test_unicode.rb @@ -29,6 +29,26 @@ class Reline::Unicode::Test < Reline::TestCase def test_take_range assert_equal 'cdef', Reline::Unicode.take_range('abcdefghi', 2, 4) + assert_equal 'あde', Reline::Unicode.take_range('abあdef', 2, 4) + assert_equal 'zerocdef', Reline::Unicode.take_range("ab\1zero\2cdef", 2, 4) + assert_equal 'bzerocde', Reline::Unicode.take_range("ab\1zero\2cdef", 1, 4) + assert_equal "\e[31mcd\e[42mef", Reline::Unicode.take_range("\e[31mabcd\e[42mefg", 2, 4) + assert_equal "\e]0;1\acd", Reline::Unicode.take_range("ab\e]0;1\acd", 2, 3) assert_equal 'いう', Reline::Unicode.take_range('あいうえお', 2, 4) end + + def test_calculate_width + assert_equal 9, Reline::Unicode.calculate_width('abcdefghi') + assert_equal 9, Reline::Unicode.calculate_width('abcdefghi', true) + assert_equal 7, Reline::Unicode.calculate_width('abあdef') + assert_equal 7, Reline::Unicode.calculate_width('abあdef', true) + assert_equal 14, Reline::Unicode.calculate_width("ab\1zero\2cdef") + assert_equal 6, Reline::Unicode.calculate_width("ab\1zero\2cdef", true) + assert_equal 19, Reline::Unicode.calculate_width("\e[31mabcd\e[42mefg") + assert_equal 7, Reline::Unicode.calculate_width("\e[31mabcd\e[42mefg", true) + assert_equal 12, Reline::Unicode.calculate_width("ab\e]0;1\acd") + assert_equal 4, Reline::Unicode.calculate_width("ab\e]0;1\acd", true) + assert_equal 10, Reline::Unicode.calculate_width('あいうえお') + assert_equal 10, Reline::Unicode.calculate_width('あいうえお', true) + end end |