11import sys
22import termios
3+ from copy import copy
4+ from select import select
35
46from ._config import config
57
@@ -12,28 +14,53 @@ def __init__(self, cfg: config = None) -> None:
1214 self .config = cfg if cfg is not None else config
1315
1416 def __enter__ (self ) -> "ReadChar" :
15- raise NotImplementedError ("ToDo" )
17+ self .fd = sys .stdin .fileno ()
18+ term = termios .tcgetattr (self .fd )
19+ self .old_settings = copy (term )
20+ term [3 ] &= ~ (termios .ICANON | termios .ECHO | termios .IGNBRK | termios .BRKINT )
21+ termios .tcsetattr (self .fd , termios .TCSAFLUSH , term )
1622 return self
1723
1824 def __exit__ (self , type , value , traceback ) -> None :
19- raise NotImplementedError ( "ToDo" )
25+ termios . tcsetattr ( self . fd , termios . TCSADRAIN , self . old_settings )
2026
2127 @property
2228 def key_waiting (self ) -> bool :
2329 """True if a key has been pressed and is waiting to be read. False if not."""
24- raise NotImplementedError ( "ToDo" )
30+ return sys . stdin in select ([ sys . stdin ], [], [], 0 )[ 0 ]
2531
2632 def char (self ) -> str :
2733 """Reads a singel char from the input stream and returns it as a string of
2834 length one. Does not require the user to press ENTER."""
29- raise NotImplementedError ( "ToDo" )
35+ return sys . stdin . read ( 1 )
3036
3137 def key (self ) -> str :
3238 """Reads a keypress from the input stream and returns it as a string. Keypressed
3339 consisting of multiple characterrs will be read completly and be returned as a
3440 string matching the definitions in `key.py`.
3541 Does not require the user to press ENTER."""
36- raise NotImplementedError ("ToDo" )
42+ c1 = self .char ()
43+
44+ if c1 in self .config .INTERRUPT_KEYS :
45+ raise KeyboardInterrupt
46+
47+ if c1 != "\x1B " :
48+ return c1
49+
50+ c2 = self .char ()
51+ if c2 not in "\x4F \x5B " :
52+ return c1 + c2
53+
54+ c3 = self .char ()
55+ if c3 not in "\x31 \x32 \x33 \x35 \x36 " :
56+ return c1 + c2 + c3
57+
58+ c4 = self .char ()
59+ if c4 not in "\x30 \x31 \x33 \x34 \x35 \x37 \x38 \x39 " :
60+ return c1 + c2 + c3 + c4
61+
62+ c5 = self .char ()
63+ return c1 + c2 + c3 + c4 + c5
3764
3865
3966# Initially taken from:
0 commit comments