class Reline::LineEditor
def render_partial(prompt, prompt_width, line_to_render, this_started_from, with_control: true)
def render_partial(prompt, prompt_width, line_to_render, this_started_from, with_control: true) _lines, height = split_by_width(line_to_render.nil? ? prompt : prompt + line_to_render, @screen_size.last) _up_from_last_line = 0 roll_partial_screen _visual_line = this_started_from + (height - 1) _screen_line = @scroll_partial_screen + (@screen_height - 1) @scroll_partial_screen - this_started_from) >= height Render nothing because this line is before the screen. sual_lines = [] f this_started_from > last_screen_line Render nothing because this line is after the screen. sual_lines = [] leted_lines_before_screen = [] @scroll_partial_screen > this_started_from and last_visual_line >= @scroll_partial_screen # A part of visual lines are before the screen. deleted_lines_before_screen = visual_lines.shift((@scroll_partial_screen - this_started_from) * 2) deleted_lines_before_screen.compact! d this_started_from <= last_screen_line and last_screen_line < last_visual_line # A part of visual lines are after the screen. visual_lines.pop((last_visual_line - last_screen_line) * 2) d ve_cursor_up(deleted_lines_before_screen.size - @started_from) rsor_up_from_last_line = @started_from - deleted_lines_before_screen.size h_control eight > @highest_in_this ff = height - @highest_in_this roll_down(diff) ighest_in_all += diff ighest_in_this = height ve_cursor_up(diff) f height < @highest_in_this ff = @highest_in_this - height ighest_in_all -= diff ighest_in_this = height _cursor_up(@started_from) rted_from = calculate_height_by_width(prompt_width + @cursor) - 1 or_up_from_last_line = height - 1 - @started_from ine::Unicode::CSI_REGEXP.match?(prompt + line_to_render) put.write "\e[0m" # clear character decorations _lines.each_with_index do |line, index| ne::IOGate.move_cursor_column(0) ine.nil? calculate_width(visual_lines[index - 1], true) == Reline::IOGate.get_screen_size.last # reaches the end of line if Reline::IOGate.win? and Reline::IOGate.win_legacy_console? # A newline is automatically inserted if a character is rendered at # eol on command prompt. else # When the cursor is at the end of the line and erases characters # after the cursor, some terminals delete the character at the # cursor position. move_cursor_down(1) Reline::IOGate.move_cursor_column(0) end se Reline::IOGate.erase_after_cursor move_cursor_down(1) Reline::IOGate.move_cursor_column(0) d xt put.write line eline::IOGate.win? and Reline::IOGate.win_legacy_console? and calculate_width(line, true) == Reline::IOGate.get_screen_size.last A newline is automatically inserted if a character is rendered at eol on command prompt. est_height -= 1 if @rest_height > 0 put.flush first_prompt irst_prompt = false re_input_hook&.call visual_lines.empty? ne::IOGate.erase_after_cursor ne::IOGate.move_cursor_column(0) h_control st after rendring, so the cursor is on the last line. inished? line::IOGate.move_cursor_column(0) Moves up from bottom of lines to the cursor position. ve_cursor_up(cursor_up_from_last_line) This logic is buggy if a fullwidth char is wrapped because there is only one halfwidth at end of a line. line::IOGate.move_cursor_column((prompt_width + @cursor) % @screen_size.last)