Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

gh-132267: fix unsynchronized cursor position and buffer mismatch after resize#132313

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
ImFeH2 wants to merge6 commits intopython:mainfromImFeH2:gh-132267
Closed
Show file tree
Hide file tree
Changes from1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
PrevPrevious commit
NextNext commit
feat: synchronize Console.screen after resize
  • Loading branch information
@ImFeH2
ImFeH2 committedApr 9, 2025
commitd8ba5032fa390b82cf1cef28c372ee7e21802221
2 changes: 1 addition & 1 deletionLib/_pyrepl/console.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,7 @@ def __init__(
self.output_fd = f_out.fileno()

@abstractmethod
def refresh(self, screen: list[str], xy: tuple[int, int], repaint: bool) -> None: ...
def refresh(self, screen: list[str], xy: tuple[int, int]) -> None: ...

@abstractmethod
def prepare(self) -> None: ...
Expand Down
6 changes: 3 additions & 3 deletionsLib/_pyrepl/reader.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -631,14 +631,14 @@ def update_screen(self) -> None:
if self.dirty:
self.refresh()

def refresh(self, repaint: bool = False) -> None:
def refresh(self) -> None:
"""Recalculate and refresh the screen."""
if self.in_bracketed_paste and self.buffer and not self.buffer[-1] == "\n":
return

# this call sets up self.cxy, so call it first.
self.screen = self.calc_screen()
self.console.refresh(self.screen, self.cxy, repaint)
self.console.refresh(self.screen, self.cxy)
self.dirty = False

def do_cmd(self, cmd: tuple[str, list[str]]) -> None:
Expand DownExpand Up@@ -717,7 +717,7 @@ def handle1(self, block: bool = True) -> bool:
self.refresh()
elif event.evt == "resize":
self.console.sync_screen()
self.refresh(repaint=True)
self.refresh()
else:
translate = False

Expand Down
61 changes: 36 additions & 25 deletionsLib/_pyrepl/unix_console.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -226,7 +226,7 @@ def change_encoding(self, encoding: str) -> None:
"""
self.encoding = encoding

def refresh(self, screen, c_xy, repaint: bool = False):
def refresh(self, screen, c_xy):
"""
Refresh the console screen.

Expand DownExpand Up@@ -293,14 +293,7 @@ def refresh(self, screen, c_xy, repaint: bool = False):
oldline,
newline,
) in zip(range(offset, offset + height), oldscr, newscr):
if repaint:
# repaint the whole line
self.__hide_cursor()
self.__move(0, y)
self.__write_code(self._el)
self.__write(newline)
self.posxy = wlen(newline), y
elif oldline != newline:
if oldline != newline:
self.__write_changed_line(y, oldline, newline, px)

y = len(newscr)
Expand DownExpand Up@@ -334,40 +327,58 @@ def move_cursor(self, x, y):

def sync_screen(self):
"""
Synchronize self.posxy, self.width and self.height.
Synchronize self.posxy, self.screen, self.width and self.height.
Assuming that the content of the screen doesn't change, only the width changes.
"""
if not self.screen:
self.posxy = 0, 0
return

px, py = self.posxy
old_height, old_width = self.height, self.width
new_height, new_width = self.getheightwidth()

groups = []
x, y = 0, 0
new_line = True
for line in self.screen[:py]:
fori,line inenumerate(self.screen):
l = wlen(line)
if i == py:
if new_line:
y = sum(wlen(g) // new_width for g in groups) + len(groups) - 1
x = px
else:
y = sum(wlen(g) // new_width for g in groups[:-1]) + len(groups) - 1
x = px + wlen(groups[-1])
if x >= new_width:
y += x // new_width
x %= new_width

if new_line:
groups.append(l)
groups.append(line)
new_line = False
else:
groups[-1] +=l
if l !=self.width:
groups[-1] +=line
if l !=old_width:
new_line = True

if new_line:
groups.append(px)
else:
groups[-1] += px

new_height, new_width = self.getheightwidth()

ny = 0
new_screen = []
for group in groups:
ny += group // new_width
nx = groups[-1] % new_width
l = 0
line = ""
for c in group:
cw = wlen(c)
if l + cw > new_width:
new_screen.append(line)
line = c
l = cw
else:
line += c
l += cw
if line:
new_screen.append(line)

self.posxy =nx, ny
self.posxy =x, y
self.height, self.width = new_height, new_width

def prepare(self):
Expand Down
63 changes: 37 additions & 26 deletionsLib/_pyrepl/windows_console.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -158,7 +158,7 @@ def __init__(
# Console I/O is redirected, fallback...
self.out = None

def refresh(self, screen: list[str], c_xy: tuple[int, int], repaint: bool = False) -> None:
def refresh(self, screen: list[str], c_xy: tuple[int, int]) -> None:
"""
Refresh the console screen.

Expand DownExpand Up@@ -212,13 +212,7 @@ def refresh(self, screen: list[str], c_xy: tuple[int, int], repaint: bool = Fals
oldline,
newline,
) in zip(range(offset, offset + height), oldscr, newscr):
if repaint:
self._hide_cursor()
self._move_relative(0, y)
self._erase_to_end()
self.__write(newline)
self.posxy = wlen(newline), y
elif oldline != newline:
if oldline != newline:
self.__write_changed_line(y, oldline, newline, px)

y = len(newscr)
Expand DownExpand Up@@ -393,41 +387,58 @@ def move_cursor(self, x: int, y: int) -> None:

def sync_screen(self):
"""
Synchronize self.posxy, self.width and self.height.
Synchronize self.posxy, self.screen, self.width and self.height.
Assuming that the content of the screen doesn't change, only the width changes.
"""
if not self.screen:
self.posxy = 0, 0
return

px, py = self.posxy
old_height, old_width = self.height, self.width
new_height, new_width = self.getheightwidth()

groups = []
x, y = 0, 0
new_line = True
for line in self.screen[:py]:
fori,line inenumerate(self.screen):
l = wlen(line)
if i == py:
if new_line:
y = sum(wlen(g) // new_width for g in groups) + len(groups) - 1
x = px
else:
y = sum(wlen(g) // new_width for g in groups[:-1]) + len(groups) - 1
x = px + wlen(groups[-1])
if x >= new_width:
y += x // new_width
x %= new_width

if new_line:
groups.append(l)
groups.append(line)
new_line = False
else:
groups[-1] +=l
if l !=self.width:
groups[-1] +=line
if l !=old_width:
new_line = True

if new_line:
groups.append(px)
else:
groups[-1] += px


new_height, new_width = self.getheightwidth()

ny = 0
new_screen = []
for group in groups:
ny += group // new_width
nx = groups[-1] % new_width

self.posxy = nx, ny
l = 0
line = ""
for c in group:
cw = wlen(c)
if l + cw > new_width:
new_screen.append(line)
line = c
l = cw
else:
line += c
l += cw
if line:
new_screen.append(line)

self.posxy = x, y
self.height, self.width = new_height, new_width

def set_cursor_vis(self, visible: bool) -> None:
Expand Down
5 changes: 1 addition & 4 deletionsLib/test/test_pyrepl/support.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -134,7 +134,7 @@ def getpending(self) -> Event:
def getheightwidth(self) -> tuple[int, int]:
return self.height, self.width

def refresh(self, screen: list[str], xy: tuple[int, int], repaint: bool) -> None:
def refresh(self, screen: list[str], xy: tuple[int, int]) -> None:
pass

def prepare(self) -> None:
Expand All@@ -146,9 +146,6 @@ def restore(self) -> None:
def move_cursor(self, x: int, y: int) -> None:
pass

def sync_screen(self) -> None:
pass

def set_cursor_vis(self, visible: bool) -> None:
pass

Expand Down
4 changes: 2 additions & 2 deletionsLib/test/test_pyrepl/test_unix_console.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -257,7 +257,7 @@ def test_resize_bigger_on_multiline_function(self, _os_write):
)

console.height = 2
console.getheightwidth = MagicMock(lambda _:(2, 80))
console.getheightwidth = MagicMock(return_value=(2, 80))

def same_reader(_):
return reader
Expand DownExpand Up@@ -293,7 +293,7 @@ def test_resize_smaller_on_multiline_function(self, _os_write):
reader, console = handle_events_unix_console_height_3(events)

console.height = 1
console.getheightwidth = MagicMock(lambda _:(1, 80))
console.getheightwidth = MagicMock(return_value=(1, 80))

def same_reader(_):
return reader
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp