From 7ea8a7d45fee82fd4ba74a067796f189b86dbcfc Mon Sep 17 00:00:00 2001 From: pagedown Date: Sat, 15 Jan 2022 18:38:05 +0800 Subject: [PATCH 1/5] Fix searching the last command output --- kitty/screen.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kitty/screen.c b/kitty/screen.c index 442ad79d0..126c3381a 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -2756,12 +2756,14 @@ cmd_output(Screen *self, PyObject *args) { switch (which) { case 0: // last run cmd - found = find_cmd_output(self, &oo, self->cursor->y, self->scrolled_by, -1, false); + // When scrolled, the starting point of the search for the last command output + // is actually out of the screen, so add the number of scrolled lines + found = find_cmd_output(self, &oo, self->cursor->y + self->scrolled_by, self->scrolled_by, -1, false); break; case 1: // first on screen found = find_cmd_output(self, &oo, 0, self->scrolled_by, 1, true); break; - case 2: // last visited cmd + case 2: // last visited cmd if (self->last_visited_prompt.scrolled_by <= self->historybuf->count && self->last_visited_prompt.is_set) { found = find_cmd_output(self, &oo, self->last_visited_prompt.y, self->last_visited_prompt.scrolled_by, 0, false); } break; From ce32e646922e02d8f85052eaf0c84e2915fa606f Mon Sep 17 00:00:00 2001 From: pagedown Date: Sat, 15 Jan 2022 20:19:12 +0800 Subject: [PATCH 2/5] Check the continued attribute when searching for prompt marks --- kitty/screen.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kitty/screen.c b/kitty/screen.c index 126c3381a..8b874638f 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -2684,7 +2684,7 @@ find_cmd_output(Screen *self, OutputOffset *oo, index_type start_y, unsigned int found_prompt = true; // change direction to downwards to find command output direction = 1; - } else if (line && line->attrs.prompt_kind == OUTPUT_START) { + } else if (line && line->attrs.prompt_kind == OUTPUT_START && !line->attrs.continued) { found_output = true; start = y1; found_prompt = true; // keep finding the first output start upwards @@ -2698,14 +2698,14 @@ find_cmd_output(Screen *self, OutputOffset *oo, index_type start_y, unsigned int // find upwards: find prompt after the output, and the first output while (y1 >= upward_limit) { line = checked_range_line(self, y1); - if (line && line->attrs.prompt_kind == PROMPT_START) { + if (line && line->attrs.prompt_kind == PROMPT_START && !line->attrs.continued) { if (direction == 0) { // find around: stop at prompt start start = y1 + 1; break; } found_next_prompt = true; end = y1; - } else if (line && line->attrs.prompt_kind == OUTPUT_START) { + } else if (line && line->attrs.prompt_kind == OUTPUT_START && !line->attrs.continued) { start = y1; break; } From f0d2d01a36337aa84c219f792f5174971aa6242e Mon Sep 17 00:00:00 2001 From: pagedown Date: Sun, 16 Jan 2022 04:02:13 +0800 Subject: [PATCH 3/5] Fix calculating the end of the command output --- kitty/screen.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kitty/screen.c b/kitty/screen.c index 8b874638f..6de09427f 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -2668,10 +2668,10 @@ get_line_from_offset(void *x, int y) { } static bool -find_cmd_output(Screen *self, OutputOffset *oo, index_type start_y, unsigned int scrolled_by, int direction, bool on_screen_only) { +find_cmd_output(Screen *self, OutputOffset *oo, index_type start_screen_y, unsigned int scrolled_by, int direction, bool on_screen_only) { bool found_prompt = false, found_output = false, found_next_prompt = false; int start = 0, end = 0; - int y1 = start_y - scrolled_by, y2 = y1; + int init_y = start_screen_y - scrolled_by, y1 = init_y, y2 = init_y; const int upward_limit = -self->historybuf->count; const int downward_limit = self->lines - 1; const int screen_limit = -scrolled_by + downward_limit; @@ -2736,7 +2736,7 @@ find_cmd_output(Screen *self, OutputOffset *oo, index_type start_y, unsigned int if (found_next_prompt) { oo->num_lines = end >= start ? end - start : 0; } else if (found_output) { - end = direction < 0 ? start_y : (unsigned int)downward_limit; + end = direction < 0 ? init_y : downward_limit; oo->num_lines = end >= start ? end - start : 0; } else return false; oo->start = start; From 30b81d98f1224c9a7e16006a944b33a4496e99dd Mon Sep 17 00:00:00 2001 From: pagedown Date: Sun, 16 Jan 2022 04:10:16 +0800 Subject: [PATCH 4/5] Add tests for finding command output --- kitty_tests/screen.py | 59 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/kitty_tests/screen.py b/kitty_tests/screen.py index 5a638aff8..ba2575b8c 100644 --- a/kitty_tests/screen.py +++ b/kitty_tests/screen.py @@ -974,14 +974,19 @@ class TestScreen(BaseTest): self.assertTrue(s.scroll_to_prompt()) self.ae(str(s.visual_line(0)), '$ 1') + def lco(): + a = [] + s.cmd_output(0, a.append) + return ''.join(a) + def fco(): a = [] s.cmd_output(1, a.append) return ''.join(a) - def lco(): + def lvco(): a = [] - s.cmd_output(0, a.append) + s.cmd_output(2, a.append) return ''.join(a) s = self.create_screen() @@ -998,3 +1003,53 @@ class TestScreen(BaseTest): mark_prompt(), s.draw('$ 1') self.ae(fco(), 'abcd\n12') self.ae(lco(), 'abcd\n12') + + def draw_prompt(x): + mark_prompt(), s.draw(f'$ {x}'), s.carriage_return(), s.index() + + def draw_output(n, x='', m=True): + if m: + mark_output() + for i in range(n): + s.draw(f'{i}{x}'), s.index(), s.carriage_return() + + s = self.create_screen(cols=5, lines=5, scrollback=15) + draw_output(1, 'start', False) + draw_prompt('0'), draw_output(3) + draw_prompt('1') + draw_prompt('2'), draw_output(2, 'x') + + # last cmd output + # test: find upwards + self.ae(s.scrolled_by, 0) + self.ae(lco(), '0x\n1x') + # get output after scroll up + s.scroll_to_prompt() + self.ae(s.scrolled_by, 4) + self.ae(str(s.visual_line(0)), '$ 0') + self.ae(lco(), '0x\n1x') + + # first cmd output on screen + # test: find around + self.ae(fco(), '0\n1\n2') + s.scroll(2, False) + self.ae(s.scrolled_by, 2) + self.ae(str(s.visual_line(0)), '1') + self.ae(fco(), '0x\n1x') + # test: find downwards + s.scroll(2, False) + self.ae(str(s.visual_line(0)), '$ 1') + self.ae(fco(), '0x\n1x') + + # resize + # get last cmd output with continued output mark + draw_prompt('3'), draw_output(1, 'long_line'), draw_output(2, 'l') + s.resize(4, 5) + s.scroll_to_prompt(-4) + self.ae(str(s.visual_line(0)), '$ 0') + self.ae(lco(), '0l\n1l') + + # last visited cmd output + self.ae(lvco(), '0\n1\n2') + s.scroll_to_prompt(1) + self.ae(lvco(), '0x\n1x') From ce6f99044e8ca016d3686da66ac2af3528c833a0 Mon Sep 17 00:00:00 2001 From: pagedown Date: Sun, 16 Jan 2022 04:14:59 +0800 Subject: [PATCH 5/5] ... --- kitty_tests/screen.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kitty_tests/screen.py b/kitty_tests/screen.py index ba2575b8c..d39d1d0d9 100644 --- a/kitty_tests/screen.py +++ b/kitty_tests/screen.py @@ -1043,11 +1043,11 @@ class TestScreen(BaseTest): # resize # get last cmd output with continued output mark - draw_prompt('3'), draw_output(1, 'long_line'), draw_output(2, 'l') + draw_prompt('3'), draw_output(1, 'long_line'), draw_output(2, 'l', False) s.resize(4, 5) s.scroll_to_prompt(-4) self.ae(str(s.visual_line(0)), '$ 0') - self.ae(lco(), '0l\n1l') + self.ae(lco(), '0long_line\n0l\n1l') # last visited cmd output self.ae(lvco(), '0\n1\n2')