|
1 | 1 | # -*- coding: utf-8 -*-
|
2 |
| -# Initially taken from: |
3 |
| -# http://code.activestate.com/recipes/134892/ |
4 |
| -# Thanks to Danny Yoo |
| 2 | +# Copyright (c) 2014, 2015 Miguel Ángel García (@magmax9). |
| 3 | +# Based on previous work on gist getch()-like unbuffered character |
| 4 | +# reading from stdin on both Windows and Unix (Python recipe), |
| 5 | +# started by Danny Yoo. Licensed under the MIT license. |
| 6 | + |
5 | 7 | import sys
|
6 | 8 | import os
|
7 | 9 | import select
|
|
13 | 15 | def readchar(wait_for_char=True):
|
14 | 16 | old_settings = termios.tcgetattr(sys.stdin)
|
15 | 17 | tty.setcbreak(sys.stdin.fileno())
|
16 |
| - char_buffer = '' |
| 18 | + charbuffer = '' |
| 19 | + |
| 20 | + while True: |
| 21 | + if charbuffer in key.ESCAPE_SEQUENCES: |
| 22 | + char1 = getkey(False, old_settings) |
| 23 | + else: |
| 24 | + char1 = getkey(wait_for_char, old_settings) |
| 25 | + if (charbuffer + char1) not in key.ESCAPE_SEQUENCES: |
| 26 | + # escape sequence complete or not an escape character.. |
| 27 | + return convertchar(charbuffer + char1) |
| 28 | + |
| 29 | + # handle cases where the escape is finished, but looks incomplete - |
| 30 | + # such as a plain old 'ESC' (\x1b) that is not followed by other |
| 31 | + # codes: |
| 32 | + if (charbuffer + char1) == charbuffer: |
| 33 | + return convertchar(charbuffer) |
| 34 | + |
| 35 | + charbuffer += char1 |
| 36 | + |
| 37 | + |
| 38 | +def getkey(wait_for_char, old_settings): |
| 39 | + charbuffer = '' |
17 | 40 | try:
|
18 | 41 | if wait_for_char or select.select([sys.stdin, ], [], [], 0.0)[0]:
|
19 | 42 | char = os.read(sys.stdin.fileno(), 1)
|
20 |
| - char_buffer = char if type(char) is str else char.decode() |
| 43 | + charbuffer = char if type(char) is str else char.decode() |
21 | 44 | except Exception:
|
22 |
| - char_buffer = '' |
| 45 | + pass |
23 | 46 | finally:
|
24 | 47 | termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)
|
| 48 | + return charbuffer |
25 | 49 |
|
26 |
| - while True: |
27 |
| - if char_buffer not in key.ESCAPE_SEQUENCES: |
28 |
| - return char_buffer |
29 |
| - else: |
30 |
| - c = readchar(False) |
31 |
| - if c is None: |
32 |
| - return char_buffer |
33 |
| - else: |
34 |
| - char_buffer += c |
| 50 | + |
| 51 | +def convertchar(charbuffer): |
| 52 | + if charbuffer in key.linux_keys: |
| 53 | + return key.linux_keys[charbuffer] |
| 54 | + return charbuffer |
0 commit comments