Skip to content

Commit 25e9557

Browse files
committed
Fixed most issues on Windows + Python 3.5
Moved the linux loop in the linux code file
1 parent 775d5df commit 25e9557

File tree

5 files changed

+148
-19
lines changed

5 files changed

+148
-19
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ venv/
1010
coverage.xml
1111
.eggs
1212
*.egg
13+
.idea

readchar/key_windows.py

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# These following keys are ones that have 2 meanings.
2+
# The first key command is the one that is not in the dict below:
3+
# ctrl_i is tab
4+
# ctrl_[ is escape
5+
# ctrl_2 is ctrl_c
6+
# ctrl_h is backspace
7+
# ctrl_j is ctrl_enter
8+
# ctrl_m is enter
9+
10+
windows_special_keys = {
11+
# Single keys:
12+
'H': 'up',
13+
'M': 'right',
14+
'P': 'down',
15+
'K': 'left',
16+
';': 'f1',
17+
'<': 'f2',
18+
'=': 'f3',
19+
'>': 'f4',
20+
'?': 'f5',
21+
'@': 'f6',
22+
'A': 'f7',
23+
'B': 'f8',
24+
'C': 'f9',
25+
'D': 'f10',
26+
'S': 'delete',
27+
# key combos & shifted_keys
28+
'T': 'shift_f1',
29+
'U': 'shift_f2',
30+
'V': 'shift_f3',
31+
'W': 'shift_f4',
32+
'X': 'shift_f5',
33+
'Y': 'shift_f6',
34+
'Z': 'shift_f7',
35+
'[': 'shift_f8',
36+
'\\\\': 'shift_f9',
37+
']': 'shift_f10',
38+
# ctrl_keys
39+
'^': 'ctrl_f1',
40+
'_': 'ctrl_f2',
41+
'`': 'ctrl_f3',
42+
'a': 'ctrl_f4',
43+
'b': 'ctrl_f5',
44+
'c': 'ctrl_f6',
45+
'd': 'ctrl_f7',
46+
'e': 'ctrl_f8',
47+
'f': 'ctrl_f9',
48+
'g': 'ctrl_f10',
49+
'\\x8d': 'ctrl_up',
50+
'\\x91': 'ctrl_down',
51+
's': 'ctrl_left',
52+
't': 'ctrl_right',
53+
}
54+
55+
windows_keys = {
56+
# Single keys:
57+
'\\x1b': 'escape',
58+
' ': 'space',
59+
'\\x85': 'f11',
60+
'\\x86': 'f12',
61+
'\\x08': 'backspace',
62+
'\\r': 'enter',
63+
'\\t': 'tab',
64+
# key combos & shifted_keys
65+
'\\x87': 'shift_f11',
66+
'\\x88': 'shift_f12',
67+
# ctrl_keys
68+
'\\x89': 'ctrl_f11',
69+
'\\x8a': 'ctrl_f12',
70+
'\\x93': 'ctrl_delete',
71+
'\\n': 'ctrl_enter',
72+
'\\x94': 'ctrl_tab',
73+
'\\x7f': 'ctrl_backspace',
74+
'\\x1c': 'ctrl_\\',
75+
'\\x1d': 'ctrl_]',
76+
# ctrl letters
77+
'\\x01': 'ctrl_a',
78+
'\\x02': 'ctrl_b',
79+
'\\x03': 'ctrl_c',
80+
'\\x04': 'ctrl_d',
81+
'\\x05': 'ctrl_e',
82+
'\\x06': 'ctrl_f',
83+
'\\x07': 'ctrl_g',
84+
'\\x0b': 'ctrl_k',
85+
'\\x0c': 'ctrl_l',
86+
'\\x0e': 'ctrl_n',
87+
'\\x0f': 'ctrl_o',
88+
'\\x10': 'ctrl_p',
89+
'\\x11': 'ctrl_q',
90+
'\\x12': 'ctrl_r',
91+
'\\x13': 'ctrl_s',
92+
'\\x14': 'ctrl_t',
93+
'\\x15': 'ctrl_u',
94+
'\\x16': 'ctrl_v',
95+
'\\x17': 'ctrl_w',
96+
'\\x18': 'ctrl_x',
97+
'\\x19': 'ctrl_y',
98+
'\\x1a': 'ctrl_z',
99+
'\\\\': '\\',
100+
}

readchar/readchar.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,7 @@
1717
raise NotImplemented('The platform %s is not supported yet' % sys.platform)
1818

1919

20-
def readkey(getchar_fn=None):
20+
def readkey(getchar_fn=None, blocking=True):
2121
getchar = getchar_fn or readchar
22-
buffer = getchar(True)
23-
24-
while True:
25-
if buffer not in key.ESCAPE_SEQUENCES:
26-
return buffer
27-
c = getchar(False)
28-
if c is None:
29-
return buffer
30-
buffer += c
22+
buffer = getchar(blocking)
3123
return buffer

readchar/readchar_linux.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,27 @@
77
import select
88
import tty
99
import termios
10+
from . import key
1011

1112

1213
def readchar(wait_for_char=True):
1314
old_settings = termios.tcgetattr(sys.stdin)
1415
tty.setcbreak(sys.stdin.fileno())
16+
buffer = ''
1517
try:
1618
if wait_for_char or select.select([sys.stdin, ], [], [], 0.0)[0]:
1719
char = os.read(sys.stdin.fileno(), 1)
18-
return char if type(char) is str else char.decode()
20+
buffer = char if type(char) is str else char.decode()
21+
except Exception:
22+
buffer = ''
1923
finally:
2024
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)
25+
26+
while True:
27+
if buffer not in key.ESCAPE_SEQUENCES:
28+
return buffer
29+
c = readchar(False)
30+
if c is None:
31+
return buffer
32+
buffer += c
33+
return buffer

readchar/readchar_windows.py

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,38 @@
33
# http://code.activestate.com/recipes/134892/#c9
44
# Thanks to Stephen Chappell
55
import msvcrt
6+
from .key_windows import windows_keys, windows_special_keys
67

78

8-
def readchar(blocking=False):
9-
"Get a single character on Windows."
10-
11-
while msvcrt.kbhit():
12-
msvcrt.getch()
9+
def get_char():
10+
"""Get a single character on Windows."""
1311
ch = msvcrt.getch()
14-
while ch in '\x00\xe0':
15-
msvcrt.getch()
12+
if ch in b'\x00\xe0':
1613
ch = msvcrt.getch()
17-
return ch.decode()
14+
ch = repr(ch)[2:-1]
15+
ch = windows_special_keys.get(ch, ch)
16+
else:
17+
ch = repr(ch)[2:-1]
18+
if str(ch)[0] == '\\' or ch == ' ':
19+
ch = windows_keys.get(ch, ch)
20+
return ch
21+
22+
23+
def readchar(blocking=False):
24+
"""gets a character or combo on windows and returns a string.
25+
If blocking is True then it will catch ctrl+c and not have them end the program.
26+
It will also wait for a key to be pressed before continuing on with the loop."""
27+
if blocking:
28+
return get_char()
29+
else:
30+
if msvcrt.kbhit():
31+
return get_char()
32+
33+
34+
if __name__ == '__main__':
35+
while True:
36+
c = readchar()
37+
if c:
38+
print(c)
39+
if c == 'e':
40+
break

0 commit comments

Comments
 (0)