@@ -59,6 +59,7 @@ def __init__(self, err: int | None, descr: str | None = None) -> None:
5959 self .err = err
6060 self .descr = descr
6161
62+
6263# declare nt optional to allow None assignment on other platforms
6364nt : types .ModuleType | None
6465try :
@@ -126,12 +127,14 @@ def __init__(self, err: int | None, descr: str | None = None) -> None:
126127class _error (Exception ):
127128 pass
128129
130+
129131def _supports_vt ():
130132 try :
131133 return nt ._supports_virtual_terminal ()
132134 except AttributeError :
133135 return False
134136
137+
135138class WindowsConsole (Console ):
136139 def __init__ (
137140 self ,
@@ -145,12 +148,12 @@ def __init__(
145148 self .__vt_support = _supports_vt ()
146149
147150 if self .__vt_support :
148- trace (' console supports virtual terminal' )
151+ trace (" console supports virtual terminal" )
149152
150153 # Save original console modes so we can recover on cleanup.
151154 original_input_mode = DWORD ()
152155 GetConsoleMode (InHandle , original_input_mode )
153- trace (f' saved original input mode 0x{ original_input_mode .value :x} ' )
156+ trace (f" saved original input mode 0x{ original_input_mode .value :x} " )
154157 self .__original_input_mode = original_input_mode .value
155158
156159 SetConsoleMode (
@@ -289,7 +292,7 @@ def __write_changed_line(
289292 else :
290293 self .posxy = wlen (newline ), y
291294
292- if "\x1b " in newline or y != self .posxy [1 ] or ' \x1a ' in newline :
295+ if "\x1b " in newline or y != self .posxy [1 ] or " \x1a " in newline :
293296 # ANSI escape characters are present, so we can't assume
294297 # anything about the position of the cursor. Moving the cursor
295298 # to the left margin should work to get to a known position.
@@ -334,7 +337,7 @@ def _disable_bracketed_paste(self) -> None:
334337
335338 def __write (self , text : str ) -> None :
336339 if "\x1a " in text :
337- text = '' .join (["^Z" if x == ' \x1a ' else x for x in text ])
340+ text = "" .join (["^Z" if x == " \x1a " else x for x in text ])
338341
339342 if self .out is not None :
340343 self .out .write (text .encode (self .encoding , "replace" ))
@@ -362,7 +365,9 @@ def prepare(self) -> None:
362365 self .__offset = 0
363366
364367 if self .__vt_support :
365- SetConsoleMode (InHandle , self .__original_input_mode | ENABLE_VIRTUAL_TERMINAL_INPUT )
368+ SetConsoleMode (
369+ InHandle , self .__original_input_mode | ENABLE_VIRTUAL_TERMINAL_INPUT
370+ )
366371 self ._enable_bracketed_paste ()
367372
368373 def restore (self ) -> None :
@@ -427,9 +432,7 @@ def _read_input(self) -> INPUT_RECORD | None:
427432
428433 return rec
429434
430- def _read_input_bulk (
431- self , n : int
432- ) -> tuple [ctypes .Array [INPUT_RECORD ], int ]:
435+ def _read_input_bulk (self , n : int ) -> tuple [ctypes .Array [INPUT_RECORD ], int ]:
433436 rec = (n * INPUT_RECORD )()
434437 read = DWORD ()
435438 if not ReadConsoleInput (InHandle , rec , n , read ):
@@ -477,7 +480,9 @@ def get_event(self, block: bool = True) -> Event | None:
477480 elif key_event .dwControlKeyState & ALT_ACTIVE :
478481 # queue the key, return the meta command
479482 self .event_queue .insert (Event (evt = "key" , data = key ))
480- return Event (evt = "key" , data = "\033 " ) # keymap.py uses this for meta
483+ return Event (
484+ evt = "key" , data = "\033 "
485+ ) # keymap.py uses this for meta
481486 return Event (evt = "key" , data = key )
482487 if block :
483488 continue
@@ -516,6 +521,14 @@ def clear(self) -> None:
516521 self .posxy = 0 , 0
517522 self .screen = ["" ]
518523
524+
525+ def clear_all (self ) -> None :
526+ """Clear screen and scrollback buffer."""
527+ os .system ("cls" ) # This might not clear scrollback
528+ # Fallback to ANSI escape sequences if terminal supports them
529+ self .write_code ("\033 [3J\033 [2J\033 [H" )
530+ self .clear ()
531+
519532 def finish (self ) -> None :
520533 """Move the cursor to the end of the display and otherwise get
521534 ready for end. XXX could be merged with restore? Hmm."""
@@ -697,7 +710,6 @@ class INPUT_RECORD(Structure):
697710 ReadConsoleInput .argtypes = [HANDLE , POINTER (INPUT_RECORD ), DWORD , POINTER (DWORD )]
698711 ReadConsoleInput .restype = BOOL
699712
700-
701713 FlushConsoleInputBuffer = _KERNEL32 .FlushConsoleInputBuffer
702714 FlushConsoleInputBuffer .argtypes = [HANDLE ]
703715 FlushConsoleInputBuffer .restype = BOOL
0 commit comments