summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/reline/line_editor.rb27
-rw-r--r--lib/reline/unicode.rb4
2 files changed, 19 insertions, 12 deletions
diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb
index c4ae651556..686a101869 100644
--- a/lib/reline/line_editor.rb
+++ b/lib/reline/line_editor.rb
@@ -295,8 +295,8 @@ class Reline::LineEditor
end
end
- private def split_by_width(str, max_width)
- Reline::Unicode.split_by_width(str, max_width, @encoding)
+ private def split_by_width(str, max_width, offset: 0)
+ Reline::Unicode.split_by_width(str, max_width, @encoding, offset: offset)
end
def current_byte_pointer_cursor
@@ -370,7 +370,7 @@ class Reline::LineEditor
@scroll_partial_screen
end
- def wrapped_lines
+ def wrapped_prompt_and_input_lines
with_cache(__method__, @buffer_of_lines.size, modified_lines, prompt_list, screen_width) do |n, lines, prompts, width, prev_cache_key, cached_value|
prev_n, prev_lines, prev_prompts, prev_width = prev_cache_key
cached_wraps = {}
@@ -381,9 +381,14 @@ class Reline::LineEditor
end
n.times.map do |i|
- prompt = prompts[i]
- line = lines[i]
- cached_wraps[[prompt, line]] || split_by_width("#{prompt}#{line}", width).first.compact
+ prompt = prompts[i] || ''
+ line = lines[i] || ''
+ if (cached = cached_wraps[[prompt, line]])
+ next cached
+ end
+ *wrapped_prompts, code_line_prompt = split_by_width(prompt, width).first.compact
+ wrapped_lines = split_by_width(line, width, offset: calculate_width(code_line_prompt)).first.compact
+ wrapped_prompts.map { |p| [p, ''] } + [[code_line_prompt, wrapped_lines.first]] + wrapped_lines.drop(1).map { |c| ['', c] }
end
end
end
@@ -426,7 +431,7 @@ class Reline::LineEditor
prompt_width = calculate_width(prompt_list[@line_index], true)
line_before_cursor = whole_lines[@line_index].byteslice(0, @byte_pointer)
wrapped_line_before_cursor = split_by_width(' ' * prompt_width + line_before_cursor, screen_width).first.compact
- wrapped_cursor_y = wrapped_lines[0...@line_index].sum(&:size) + wrapped_line_before_cursor.size - 1
+ wrapped_cursor_y = wrapped_prompt_and_input_lines[0...@line_index].sum(&:size) + wrapped_line_before_cursor.size - 1
wrapped_cursor_x = calculate_width(wrapped_line_before_cursor.last)
[wrapped_cursor_x, wrapped_cursor_y]
end
@@ -490,8 +495,9 @@ class Reline::LineEditor
wrapped_cursor_x, wrapped_cursor_y = wrapped_cursor_position
rendered_lines = @rendered_screen.lines
- new_lines = wrapped_lines.flatten[screen_scroll_top, screen_height].map do |l|
- [[0, Reline::Unicode.calculate_width(l, true), l]]
+ new_lines = wrapped_prompt_and_input_lines.flatten(1)[screen_scroll_top, screen_height].map do |prompt, line|
+ prompt_width = Reline::Unicode.calculate_width(prompt, true)
+ [[0, prompt_width, prompt], [prompt_width, Reline::Unicode.calculate_width(line, true), line]]
end
if @menu_info
@menu_info.lines(screen_width).each do |item|
@@ -507,7 +513,8 @@ class Reline::LineEditor
y_range.each do |row|
next if row < 0 || row >= screen_height
dialog_rows = new_lines[row] ||= []
- dialog_rows[index + 1] = [x_range.begin, dialog.width, dialog.contents[row - y_range.begin]]
+ # index 0 is for prompt, index 1 is for line, index 2.. is for dialog
+ dialog_rows[index + 2] = [x_range.begin, dialog.width, dialog.contents[row - y_range.begin]]
end
end
diff --git a/lib/reline/unicode.rb b/lib/reline/unicode.rb
index 26ef207ba6..1a916b4b98 100644
--- a/lib/reline/unicode.rb
+++ b/lib/reline/unicode.rb
@@ -128,10 +128,10 @@ class Reline::Unicode
end
end
- def self.split_by_width(str, max_width, encoding = str.encoding)
+ def self.split_by_width(str, max_width, encoding = str.encoding, offset: 0)
lines = [String.new(encoding: encoding)]
height = 1
- width = 0
+ width = offset
rest = str.encode(Encoding::UTF_8)
in_zero_width = false
seq = String.new(encoding: encoding)