From e8832a86bb3aaa8d6c0544be9dfbc17149311457 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 22 Jul 2021 08:47:51 +0530 Subject: [PATCH] Fix scroll_to_prompt for prompts that have been reflowed over multiple lines --- kitty/screen.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/kitty/screen.c b/kitty/screen.c index 742b1eca1..8b1520695 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -1805,18 +1805,29 @@ shell_prompt_marking(Screen *self, PyObject *data) { static bool screen_history_scroll_to_prompt(Screen *self, int num_of_prompts_to_jump) { - if (self->linebuf != self->main_linebuf) return false; + if (self->linebuf != self->main_linebuf || !num_of_prompts_to_jump) return false; int delta = num_of_prompts_to_jump < 0 ? -1 : 1; num_of_prompts_to_jump = num_of_prompts_to_jump < 0 ? -num_of_prompts_to_jump : num_of_prompts_to_jump; int y = -self->scrolled_by; +#define ensure_y_ok if (y >= (int)self->lines || -y > (int)self->historybuf->count) return false; +#define move_y_to_start_of_promt while (-y + 1 <= (int)self->historybuf->count && range_line_(self, y - 1)->is_prompt_start) y--; +#define move_y_to_end_of_promt while (y + 1 < (int)self->lines && range_line_(self, y + 1)->is_prompt_start) y++; + ensure_y_ok; + if (range_line_(self, y)->is_prompt_start) { + if (delta < 0) { move_y_to_start_of_promt; } else { move_y_to_end_of_promt; } + } while (num_of_prompts_to_jump) { y += delta; - if (y >= (int)self->lines || -y > (int)self->historybuf->count) return false; - if (range_line_(self, y)->is_prompt_start) num_of_prompts_to_jump--; - } - if (delta < 0) { - while (-y + 1 <= (int)self->historybuf->count && range_line_(self, y - 1)->is_prompt_start) y--; + ensure_y_ok; + if (range_line_(self, y)->is_prompt_start) { + num_of_prompts_to_jump--; + if (delta < 0) { move_y_to_start_of_promt; } else { move_y_to_end_of_promt; } + } } + move_y_to_start_of_promt; +#undef ensure_y_ok +#undef move_y_to_start_of_promt +#undef move_y_to_end_of_promt unsigned int old = self->scrolled_by; self->scrolled_by = y >= 0 ? 0 : -y; if (old != self->scrolled_by) self->scroll_changed = true;