11import contextlib
22import json
3- import select
43import sys
5- import termios
64import time
7- import tty
85from itertools import cycle
96from typing import Callable , Iterator , Literal , Optional
107
@@ -69,6 +66,13 @@ def _raw_tty_mode() -> Iterator[bool]:
6966 if not sys .stdin .isatty ():
7067 yield False
7168 return
69+ if sys .platform == "win32" :
70+ yield True
71+ return
72+
73+ import termios
74+ import tty
75+
7276 fd = sys .stdin .fileno ()
7377 old = termios .tcgetattr (fd )
7478 try :
@@ -81,6 +85,35 @@ def _raw_tty_mode() -> Iterator[bool]:
8185def _read_key (timeout : float = 0.0 ) -> Optional [str ]:
8286 if not sys .stdin .isatty ():
8387 return None
88+ if sys .platform == "win32" :
89+ return _read_windows_key (timeout )
90+ return _read_posix_key (timeout )
91+
92+
93+ def _read_windows_key (timeout : float = 0.0 ) -> Optional [str ]:
94+ import msvcrt
95+
96+ deadline = time .time () + timeout
97+ while not msvcrt .kbhit ():
98+ if timeout <= 0 or time .time () >= deadline :
99+ return None
100+ time .sleep (min (0.01 , max (0.0 , deadline - time .time ())))
101+
102+ first = msvcrt .getwch ()
103+ if first not in {"\x00 " , "\xe0 " }:
104+ return first
105+
106+ second = msvcrt .getwch ()
107+ if second == "H" :
108+ return "\x1b [A"
109+ if second == "P" :
110+ return "\x1b [B"
111+ return first + second
112+
113+
114+ def _read_posix_key (timeout : float = 0.0 ) -> Optional [str ]:
115+ import select
116+
84117 ready , _ , _ = select .select ([sys .stdin ], [], [], timeout )
85118 if not ready :
86119 return None
0 commit comments