0
0
mirror of https://github.com/python/cpython.git synced 2024-11-21 21:09:37 +01:00

gh-123177: Fix prompt for wrapped lines in pyrepl (#123324)

When display lines above the cursor come from the cache, the first line
to not come from the cache may be a wrapped line, starting half way
through a logical line in the buffer. Detect and handle this case to
avoid accidentally drawing a stray prompt in the middle of a logical
line.
This commit is contained in:
Matt Wozniski 2024-08-25 18:54:06 -04:00 committed by GitHub
parent 70bfef52b5
commit 602fcf97df
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 42 additions and 1 deletions

View File

@ -345,7 +345,10 @@ class Reader:
pos = self.pos
pos -= offset
prompt_from_cache = (offset and self.buffer[offset - 1] != "\n")
lines = "".join(self.buffer[offset:]).split("\n")
cursor_found = False
lines_beyond_cursor = 0
for ln, line in enumerate(lines, num_common_lines):
@ -359,7 +362,12 @@ class Reader:
# No need to keep formatting lines.
# The console can't show them.
break
prompt = self.get_prompt(ln, ll >= pos >= 0)
if prompt_from_cache:
# Only the first line's prompt can come from the cache
prompt_from_cache = False
prompt = ""
else:
prompt = self.get_prompt(ln, ll >= pos >= 0)
while "\n" in prompt:
pre_prompt, _, prompt = prompt.partition("\n")
last_refresh_line_end_offsets.append(offset)

View File

@ -30,6 +30,37 @@ class TestReader(TestCase):
reader, _ = handle_events_narrow_console(events)
self.assert_screen_equals(reader, f"{9*"a"}\\\n{9*"a"}\\\naa")
def test_calc_screen_prompt_handling(self):
def prepare_reader_keep_prompts(*args, **kwargs):
reader = prepare_reader(*args, **kwargs)
del reader.get_prompt
reader.ps1 = ">>> "
reader.ps2 = ">>> "
reader.ps3 = "... "
reader.ps4 = ""
reader.can_colorize = False
reader.paste_mode = False
return reader
events = code_to_events("if some_condition:\nsome_function()")
reader, _ = handle_events_narrow_console(
events,
prepare_reader=prepare_reader_keep_prompts,
)
# fmt: off
self.assert_screen_equals(
reader,
(
">>> if so\\\n"
"me_condit\\\n"
"ion:\n"
"... s\\\n"
"ome_funct\\\n"
"ion()"
)
)
# fmt: on
def test_calc_screen_wrap_three_lines_mixed_character(self):
# fmt: off
code = (

View File

@ -0,0 +1,2 @@
Fix a bug causing stray prompts to appear in the middle of wrapped lines in
the new REPL.