Merge branch 'fix-prompt-scroll-and-cmd-paging' of https://github.com/rivenirvana/kitty

This commit is contained in:
Kovid Goyal 2025-02-19 04:26:12 +05:30
commit a57cb3c1d1
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
2 changed files with 88 additions and 14 deletions

View file

@ -4078,7 +4078,7 @@ find_cmd_output(Screen *self, OutputOffset *oo, index_type start_screen_y, unsig
} else if (line && line->attrs.prompt_kind == OUTPUT_START && !range_line_is_continued(self, y1)) {
found_output = true; start = y1;
found_prompt = true;
// keep finding the first output start upwards
direction = 1;
}
y1--; y2++;
}
@ -4091,22 +4091,21 @@ find_cmd_output(Screen *self, OutputOffset *oo, index_type start_screen_y, unsig
line = checked_range_line(self, y1);
if (line && line->attrs.prompt_kind == PROMPT_START && !range_line_is_continued(self, y1)) {
if (direction == 0) {
// find around: stop at prompt start
start = y1 + 1;
found_prompt = true;
break;
}
found_next_prompt = true; end = y1;
} else if (line && line->attrs.prompt_kind == OUTPUT_START && !range_line_is_continued(self, y1)) {
start = y1;
found_output = true; start = y1;
found_prompt = true;
break;
}
y1--;
}
if (y1 < upward_limit) {
oo->reached_upper_limit = true;
start = upward_limit;
found_output = true; start = upward_limit;
}
found_output = true; found_prompt = true;
}
// find downwards
@ -4116,12 +4115,18 @@ find_cmd_output(Screen *self, OutputOffset *oo, index_type start_screen_y, unsig
line = checked_range_line(self, y2);
if (line && line->attrs.prompt_kind == PROMPT_START) {
if (!found_prompt) found_prompt = true;
else if (found_output && !found_next_prompt) {
else if (found_prompt && !found_output) {
// skip fetching wrapped prompt lines
while (range_line_is_continued(self, y2)) {
y2++;
}
} else if (found_output && !found_next_prompt) {
found_next_prompt = true; end = y2;
break;
}
} else if (line && line->attrs.prompt_kind == OUTPUT_START && found_prompt && !found_output) {
} else if (line && line->attrs.prompt_kind == OUTPUT_START && !found_output) {
found_output = true; start = y2;
if (!found_prompt) found_prompt = true;
}
y2++;
}

View file

@ -1147,22 +1147,44 @@ def draw_output(n, x='', m=True):
s.toggle_alt_screen()
self.assertFalse(str(s.line(s.cursor.y)))
s = self.create_screen()
s = self.create_screen(scrollback=10)
draw_output(1, 'start')
for i in range(4):
mark_prompt()
s.draw(f'$ {i}')
s.carriage_return()
s.index(), s.index()
draw_prompt(str(i) + 'ab')
draw_output(1, 'ut')
self.ae(s.scrolled_by, 0)
self.ae(str(s.visual_line(0)), '$ 2ab')
self.assertFalse(s.scroll_to_prompt(-3))
self.assertTrue(s.scroll_to_prompt())
self.ae(str(s.visual_line(0)), '$ 1ab')
self.assertTrue(s.scroll_to_prompt())
self.ae(str(s.visual_line(0)), '$ 0ab')
self.assertFalse(s.scroll_to_prompt())
self.assertFalse(s.scroll_to_prompt(4))
self.assertTrue(s.scroll_to_prompt(1))
self.ae(str(s.visual_line(0)), '$ 1ab')
self.assertTrue(s.scroll_to_prompt(1))
self.ae(str(s.visual_line(0)), '$ 2ab')
self.assertFalse(s.scroll_to_prompt(1))
# wrap prompts
s.resize(s.lines + 1, s.columns - 2)
self.ae(s.scrolled_by, 0)
self.ae(str(s.visual_line(0)), 'ab')
self.assertFalse(s.scroll_to_prompt(-4))
self.assertTrue(s.scroll_to_prompt())
self.ae(str(s.visual_line(0)), '$ 2')
self.assertTrue(s.scroll_to_prompt())
self.ae(str(s.visual_line(0)), '$ 1')
self.assertTrue(s.scroll_to_prompt())
self.ae(str(s.visual_line(0)), '$ 0')
self.assertFalse(s.scroll_to_prompt())
self.assertFalse(s.scroll_to_prompt(4))
self.assertTrue(s.scroll_to_prompt(1))
self.ae(str(s.visual_line(0)), '$ 1')
self.assertTrue(s.scroll_to_prompt(1))
self.ae(str(s.visual_line(0)), '$ 2')
self.assertTrue(s.scroll_to_prompt(1))
self.ae(str(s.visual_line(0)), 'ab')
self.assertFalse(s.scroll_to_prompt(1))
s = self.create_screen()
@ -1244,10 +1266,19 @@ def lvco():
s.scroll(2, False)
self.ae(str(s.visual_line(0)), '$ 1')
self.ae(fco(), '0x\n1x\n')
# test: obscure prompt in scrollback
s.resize(3, 5)
self.ae(str(s.visual_line(0)), '0x')
# without succeeding prompt
self.ae(fco(), '0x\n1x\n')
s.resize(4, 5)
draw_prompt('3')
# with succeeding prompt
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', False)
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')
@ -1257,6 +1288,44 @@ def lvco():
self.ae(lvco(), '0\n1\n2')
s.scroll_to_prompt(1)
self.ae(lvco(), '0x\n1x')
# test: obscure prompt
s.scroll(2, False)
self.ae(lvco(), '0x\n1x')
# test: prompts without output
s.scroll(s.scrolled_by, False)
draw_prompt('4')
# resizing resets last visited, rely on scroll_to_prompt
s.resize(2, s.columns + 4)
s.scroll_to_prompt()
s.scroll_to_prompt(1)
self.ae(str(s.visual_line(0)), '$ 4')
self.ae(lvco(), '')
s.resize(5, s.columns)
draw_prompt('wrapcmd')
s.scroll_to_prompt(1)
self.ae(lvco(), '')
draw_output(1, 'wrapout'), draw_output(1, 'y', False)
self.ae(lvco(), '0wrapout\n0y\n')
# wrap long prompt with long output
s.resize(5, s.columns - 4)
self.ae(str(s.visual_line(0)), 'pcmd')
# test: set last visited to previous empty prompt
s.scroll_to_prompt(-2)
self.ae(str(s.visual_line(0)), '$ 4')
self.ae(lvco(), '0wrapout\n0y\n')
mark_prompt(), s.draw('$ end')
self.ae(lvco(), '0wrapout\n0y')
# test: set last visited to continued line of long prompt
s.scroll_to_prompt(2)
self.ae(str(s.visual_line(0)), 'pcmd')
self.ae(lvco(), '0wrapout\n0y')
s.scroll_to_prompt()
self.ae(lvco(), '0wrapout\n0y')
# test: set last visited to continued line of output
s.carriage_return(), s.index()
draw_output(1, 'z')
s.scroll_to_prompt(1)
self.ae(lvco(), '0wrapout\n0y')
# test that post rewrap prompt lines have correct attributes
s = self.create_screen(cols=5, lines=5, scrollback=15)