Skip to content

Commit 243afdb

Browse files
committed
Consider fullwidth take_range in differential rendering
1 parent 577c35c commit 243afdb

File tree

2 files changed

+36
-11
lines changed

2 files changed

+36
-11
lines changed

lib/reline/line_editor.rb

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -385,9 +385,11 @@ def render_line_differential(old_items, new_items)
385385
Reline::IOGate.move_cursor_column base_x
386386
@output.write "\e[0m#{' ' * width}"
387387
else
388-
x, w, content = new_items[level]
389-
content = Reline::Unicode.take_range(content, base_x - x, width) unless x == base_x && w == width
390-
Reline::IOGate.move_cursor_column base_x
388+
x, _w, content = new_items[level]
389+
cover_begin = base_x != 0 && new_levels[base_x - 1] == level
390+
cover_end = new_levels[base_x + width] == level
391+
content, pos = Reline::Unicode.take_mbchar_range(content, base_x - x, width, cover_begin: cover_begin, cover_end: cover_end, padding: true)
392+
Reline::IOGate.move_cursor_column x + pos
391393
@output.write "\e[0m#{content}\e[0m"
392394
end
393395
base_x += width
@@ -688,13 +690,6 @@ def add_dialog_proc(name, p, context = nil)
688690

689691
DIALOG_DEFAULT_HEIGHT = 20
690692

691-
private def padding_space_with_escape_sequences(str, width)
692-
padding_width = width - calculate_width(str, true)
693-
# padding_width should be only positive value. But macOS and Alacritty returns negative value.
694-
padding_width = 0 if padding_width < 0
695-
str + (' ' * padding_width)
696-
end
697-
698693
private def dialog_range(dialog, dialog_y)
699694
x_range = dialog.column...dialog.column + dialog.width
700695
y_range = dialog_y + dialog.vertical_offset...dialog_y + dialog.vertical_offset + dialog.contents.size
@@ -768,7 +763,7 @@ def add_dialog_proc(name, p, context = nil)
768763
dialog.contents = contents.map.with_index do |item, i|
769764
line_sgr = i == pointer ? enhanced_sgr : default_sgr
770765
str_width = dialog.width - (scrollbar_pos.nil? ? 0 : @block_elem_width)
771-
str = padding_space_with_escape_sequences(Reline::Unicode.take_range(item, 0, str_width), str_width)
766+
str, = Reline::Unicode.take_mbchar_range(item, 0, str_width, padding: true)
772767
colored_content = "#{line_sgr}#{str}"
773768
if scrollbar_pos
774769
if scrollbar_pos <= (i * 2) and (i * 2 + 1) < (scrollbar_pos + bar_height)

test/reline/test_line_editor.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,36 @@ def test_dialog_move
106106
end
107107
end
108108

109+
def test_multibyte
110+
base = [0, 12, '一二三一二三']
111+
left = [0, 3, 'LLL']
112+
right = [9, 3, 'RRR']
113+
front = [3, 6, 'FFFFFF']
114+
# 一 FFFFFF 三
115+
# 一二三一二三
116+
assert_output '[COL_2]二三一二' do
117+
@line_editor.render_line_differential([base, front], [base, nil])
118+
end
119+
120+
# LLLFFFFFF 三
121+
# LLL 三一二三
122+
assert_output '[COL_3] 三一二' do
123+
@line_editor.render_line_differential([base, left, front], [base, left, nil])
124+
end
125+
126+
# 一 FFFFFFRRR
127+
# 一二三一 RRR
128+
assert_output '[COL_2]二三一 ' do
129+
@line_editor.render_line_differential([base, right, front], [base, right, nil])
130+
end
131+
132+
# LLLFFFFFFRRR
133+
# LLL 三一 RRR
134+
assert_output '[COL_3] 三一 ' do
135+
@line_editor.render_line_differential([base, left, right, front], [base, left, right, nil])
136+
end
137+
end
138+
109139
def test_complex
110140
state_a = [nil, [19, 7, 'bbbbbbb'], [15, 8, 'cccccccc'], [10, 5, 'ddddd'], [18, 4, 'eeee'], [1, 3, 'fff'], [17, 2, 'gg'], [7, 1, 'h']]
111141
state_b = [[5, 9, 'aaaaaaaaa'], nil, [15, 8, 'cccccccc'], nil, [18, 4, 'EEEE'], [25, 4, 'ffff'], [17, 2, 'gg'], [2, 2, 'hh']]

0 commit comments

Comments
 (0)