From e557327860d5dadd952f410e5bebc112fa4289f5 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 24 Nov 2012 21:06:42 -0800 Subject: [PATCH] Coalesce redundant repaints, prepare to address some resizing issues (again!) --- reader.cpp | 19 +++++++++++++++---- screen.cpp | 28 ++++++++++++++++------------ 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/reader.cpp b/reader.cpp index f1bb8a547..6327ad4ba 100644 --- a/reader.cpp +++ b/reader.cpp @@ -2696,6 +2696,9 @@ const wchar_t *reader_readline() std::vector comp; int finished=0; struct termios old_modes; + + /* Coalesce redundant repaints. When we get a repaint, we set this to true, and skip repaints until we get something else. */ + bool coalescing_repaints = false; /* The cycle index in our completion list */ size_t completion_cycle_idx = (size_t)(-1); @@ -2778,8 +2781,13 @@ const wchar_t *reader_readline() break; } + /* If we get something other than a repaint, then stop coalescing them */ + if (c != R_REPAINT) + coalescing_repaints = false; + if (last_char != R_YANK && last_char != R_YANK_POP) yank_len=0; + const wchar_t *buff = data->command_line.c_str(); switch (c) { @@ -2835,10 +2843,13 @@ const wchar_t *reader_readline() case R_REPAINT: { - exec_prompt(); - write_loop(1, "\r", 1); - s_reset(&data->screen, screen_reset_current_line_and_prompt); - reader_repaint(); + if (! coalescing_repaints) + { + coalescing_repaints = true; + exec_prompt(); + s_reset(&data->screen, screen_reset_current_line_contents); + reader_repaint(); + } break; } diff --git a/screen.cpp b/screen.cpp index 34d385f95..d13a087b7 100644 --- a/screen.cpp +++ b/screen.cpp @@ -1205,31 +1205,35 @@ void s_reset(screen_t *s, screen_reset_mode_t mode) s->actual_lines_before_reset = maxi(s->actual_lines_before_reset, s->actual.line_count()); } - int prev_line = s->actual.cursor.y; - if (repaint_prompt) { - /* If the prompt is multi-line, we need to move up to the prompt's initial line. We do this by lying to ourselves and claiming that we're really below what we consider "line 0" (which is the last line of the prompt). This will cause is to move up to try to get back to line 0, but really we're getting back to the initial line of the prompt. */ - const size_t prompt_line_count = calc_prompt_lines(s->actual_left_prompt); - assert(prompt_line_count >= 1); - prev_line += (prompt_line_count - 1); - /* Clear the prompt */ s->actual_left_prompt.clear(); } + if (repaint_prompt && ! abandon_line) + { + + /* If the prompt is multi-line, we need to move up to the prompt's initial line. We do this by lying to ourselves and claiming that we're really below what we consider "line 0" (which is the last line of the prompt). This will cause us to move up to try to get back to line 0, but really we're getting back to the initial line of the prompt. */ + const size_t prompt_line_count = calc_prompt_lines(s->actual_left_prompt); + assert(prompt_line_count >= 1); + s->actual.cursor.y += (prompt_line_count - 1); + } + else if (abandon_line) + { + s->actual.cursor.y = 0; + } + s->actual.resize(0); - s->actual.cursor.x = 0; - s->actual.cursor.y = 0; s->need_clear_lines = true; s->need_clear_screen = s->need_clear_screen || clear_to_eos; - if (!abandon_line) + if (! abandon_line) { - /* This should prevent reseting the cursor position during the next repaint. */ + /* This should prevent resetting the cursor position during the next repaint. */ write_loop(1, "\r", 1); - s->actual.cursor.y = prev_line; + s->actual.cursor.x = 0; } fstat(1, &s->prev_buff_1);