Skip to content

Commit 4e401cb

Browse files
authored
Implement screen clear for Windows (python#42)
1 parent 86b050f commit 4e401cb

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

Lib/_pyrepl/windows_console.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ class CHAR_INFO(Structure):
8686
FillConsoleOutputCharacter.argtypes = [HANDLE, CHAR, DWORD, _COORD, POINTER(DWORD)]
8787
FillConsoleOutputCharacter.restype = BOOL
8888

89+
FillConsoleOutputAttribute = windll.kernel32.FillConsoleOutputAttribute
90+
FillConsoleOutputAttribute.use_last_error = True
91+
FillConsoleOutputAttribute.argtypes = [HANDLE, WORD, DWORD, _COORD, POINTER(DWORD)]
92+
FillConsoleOutputAttribute.restype = BOOL
93+
8994
ScrollConsoleScreenBuffer = windll.kernel32.ScrollConsoleScreenBufferW
9095
ScrollConsoleScreenBuffer.use_last_error = True
9196
ScrollConsoleScreenBuffer.argtypes = [HANDLE, POINTER(SMALL_RECT), POINTER(SMALL_RECT), _COORD, POINTER(CHAR_INFO)]
@@ -99,7 +104,7 @@ class CHAR_INFO(Structure):
99104
class Char(Union):
100105
_fields_ = [
101106
("UnicodeChar",WCHAR),
102-
("Char", CHAR),
107+
("Char", CHAR),
103108
]
104109

105110
class KeyEvent(ctypes.Structure):
@@ -191,7 +196,7 @@ def __init__(
191196
term: str = "",
192197
encoding: str = "",
193198
):
194-
199+
195200
SetConsoleMode(OutHandle, ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING)
196201
self.encoding = encoding or sys.getdefaultencoding()
197202

@@ -487,14 +492,14 @@ def move_cursor(self, x: int, y: int) -> None:
487492
trace(f'move to {x} {y}')
488493

489494
if x < 0 or y < 0:
490-
raise ValueError(f"Bad cussor position {x}, {y}")
495+
raise ValueError(f"Bad cursor position {x}, {y}")
491496

492497
self.__move(x, y)
493498
self.__posxy = x, y
494499
self.flushoutput()
495-
496500

497-
def set_cursor_vis(self, visible: bool) -> None:
501+
502+
def set_cursor_vis(self, visible: bool) -> None:
498503
if visible:
499504
self.__show_cursor()
500505
else:
@@ -506,9 +511,9 @@ def getheightwidth(self) -> tuple[int, int]:
506511
info = CONSOLE_SCREEN_BUFFER_INFO()
507512
if not GetConsoleScreenBufferInfo(OutHandle, info):
508513
raise ctypes.WinError(ctypes.GetLastError())
509-
return (info.srWindow.Bottom - info.srWindow.Top + 1,
514+
return (info.srWindow.Bottom - info.srWindow.Top + 1,
510515
info.srWindow.Right - info.srWindow.Left + 1)
511-
516+
512517
def get_event(self, block: bool = True) -> Event | None:
513518
"""Return an Event instance. Returns None if |block| is false
514519
and there is no event pending, otherwise waits for the
@@ -527,7 +532,7 @@ def get_event(self, block: bool = True) -> Event | None:
527532
key = chr(rec.Event.KeyEvent.uChar.Char[0])
528533
# self.push_char(key)
529534
if rec.Event.KeyEvent.uChar.Char == b'\r':
530-
return Event(evt="key", data="\n", raw="\n")
535+
return Event(evt="key", data="\n", raw="\n")
531536
trace('virtual key code', rec.Event.KeyEvent.wVirtualKeyCode, rec.Event.KeyEvent.uChar.Char)
532537
if rec.Event.KeyEvent.wVirtualKeyCode == 8:
533538
return Event(evt="key", data="backspace", raw=rec.Event.KeyEvent.uChar.Char)
@@ -536,7 +541,7 @@ def get_event(self, block: bool = True) -> Event | None:
536541
if rec.Event.KeyEvent.uChar.Char == b'\x00':
537542
code = VK_MAP.get(rec.Event.KeyEvent.wVirtualKeyCode)
538543
if code:
539-
return Event(evt="key", data=code, raw=rec.Event.KeyEvent.uChar.Char)
544+
return Event(evt="key", data=code, raw=rec.Event.KeyEvent.uChar.Char)
540545
continue
541546
#print(key, rec.Event.KeyEvent.wVirtualKeyCode)
542547
return Event(evt="key", data=key, raw=rec.Event.KeyEvent.uChar.Char)
@@ -557,6 +562,13 @@ def clear(self) -> None:
557562
size = info.dwSize.X * info.dwSize.Y
558563
if not FillConsoleOutputCharacter(OutHandle, b' ', size, _COORD(), DWORD()):
559564
raise ctypes.WinError(ctypes.GetLastError())
565+
if not FillConsoleOutputAttribute(OutHandle, 0, size, _COORD(), DWORD()):
566+
raise ctypes.WinError(ctypes.GetLastError())
567+
y = info.srWindow.Bottom - info.srWindow.Top + 1
568+
self.__move_absolute(0, y - info.dwSize.Y)
569+
self.__posxy = 0, 0
570+
self.screen = [""]
571+
560572

561573
def finish(self) -> None:
562574
"""Move the cursor to the end of the display and otherwise get

0 commit comments

Comments
 (0)