Skip to content

Commit

Permalink
Merge pull request #406 from aycabta/support-halfwidth-kana-correctly
Browse files Browse the repository at this point in the history
Character merging may increase the character width
  • Loading branch information
aycabta committed Dec 23, 2021
2 parents 50ed575 + 0895a0d commit a5d8a6c
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 3 deletions.
12 changes: 10 additions & 2 deletions lib/reline/line_editor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2029,8 +2029,16 @@ def finish
last_byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer)
@byte_pointer += bytesize
last_mbchar = @line.byteslice((@byte_pointer - bytesize - last_byte_size), last_byte_size)
if last_byte_size != 0 and (last_mbchar + str).grapheme_clusters.size == 1
width = 0
combined_char = last_mbchar + str
if last_byte_size != 0 and combined_char.grapheme_clusters.size == 1
# combined char
last_mbchar_width = Reline::Unicode.get_mbchar_width(last_mbchar)
combined_char_width = Reline::Unicode.get_mbchar_width(combined_char)
if combined_char_width > last_mbchar_width
width = combined_char_width - last_mbchar_width
else
width = 0
end
end
@cursor += width
@cursor_max += width
Expand Down
10 changes: 9 additions & 1 deletion lib/reline/unicode.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ def self.escape_for_print(str)

require 'reline/unicode/east_asian_width'

HalfwidthDakutenHandakuten = /[\u{FF9E}\u{FF9F}]/

MBCharWidthRE = /
(?<width_2_1>
[#{ EscapedChars.map {|c| "\\x%02x" % c.ord }.join }] (?# ^ + char, such as ^M, ^H, ^[, ...)
Expand All @@ -93,6 +95,12 @@ def self.escape_for_print(str)
#{ EastAsianWidth::TYPE_H }
| #{ EastAsianWidth::TYPE_NA }
| #{ EastAsianWidth::TYPE_N }
)(?!#{ HalfwidthDakutenHandakuten })
| (?<width_2_3>
(?: #{ EastAsianWidth::TYPE_H }
| #{ EastAsianWidth::TYPE_NA }
| #{ EastAsianWidth::TYPE_N })
#{ HalfwidthDakutenHandakuten }
)
| (?<ambiguous_width>
#{EastAsianWidth::TYPE_A}
Expand All @@ -109,7 +117,7 @@ def self.get_mbchar_width(mbchar)
m = mbchar.encode(Encoding::UTF_8).match(MBCharWidthRE)
case
when m.nil? then 1 # TODO should be U+FFFD � REPLACEMENT CHARACTER
when m[:width_2_1], m[:width_2_2] then 2
when m[:width_2_1], m[:width_2_2], m[:width_2_3] then 2
when m[:width_3] then 3
when m[:width_0] then 0
when m[:width_1] then 1
Expand Down
16 changes: 16 additions & 0 deletions test/reline/test_key_actor_emacs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2306,6 +2306,22 @@ def test_ed_argument_digit_by_meta_num
assert_line('abcd')
end

def test_halfwidth_kana_width_dakuten
input_keys('ガギゲゴ')
assert_byte_pointer_size('ガギゲゴ')
assert_cursor(8)
assert_cursor_max(8)
input_keys("\C-b\C-b", false)
assert_byte_pointer_size('ガギ')
assert_cursor(4)
assert_cursor_max(8)
input_keys('グ', false)
assert_byte_pointer_size('ガギグ')
assert_cursor(6)
assert_cursor_max(10)
assert_line('ガギグゲゴ')
end

def test_input_unknown_char
input_keys('͸') # U+0378 (unassigned)
assert_line('͸')
Expand Down

0 comments on commit a5d8a6c

Please sign in to comment.