def get_key(): """ Function to retrieve a character (code) given user input. Non-blocking mode available if stdscr.nodelay(False) is called. """ try: # Catch non-blocking errors when attempting to fetch character if sys.platform == 'win32': wch = unicurses.wgetkey(stdscr) # wgetkey is for windows support else: wch = stdscr.get_wch() # get_wch is for linux ( and os x?) except curses_error: # No input error --> return ''; only happens if blocking off return '' if isinstance(wch, int): # if the keycode is a byte, it'll return an int which needs to be converted if unicurses.keyname(wch): # check for a valid key descriptor return unicurses.keyname(wch).decode('utf-8') else: # if no valid key descriptor is available, try using the character in the next conditional wch = chr(wch) if isinstance(wch, str): # already a string; check if KEY_ENTER or KEY_TAB as they are unparsed by keyname(wch) if wch == '\n': # newline = KEY_ENTER return 'KEY_ENTER' elif wch == '\t': # tab = KEY_TAB return 'KEY_TAB' elif wch == '\b': # bs = KEY_BACKSPACE return 'KEY_BACKSPACE' else: # properly formatted, we can return this safely return wch
def getchar(stdscr): while 1: try: char = stdscr.get_wch() break except curses.error: pass stdscr.addstr(key_info(char)) if isinstance(char, str): _ord = ord(char) # Replace special characters with a readable string if _ord == 27: result = 'Esc' elif _ord == 10: result = '\n' elif _ord == 9: result = '\t' elif _ord < 32: result = curses.unctrl(char) result = result.decode() result = 'Ctrl-' + result[1] else: result = char elif isinstance(char, int): # char must be some kind of function key if char == curses.KEY_BACKSPACE: result = '\b' else: result = curses.keyname(char) result = result.decode() result = result[4] + result[5:].lower() # Remove parenthesis for function keys result.replace('(', '') result.replace(')', '') else: raise IOError('Can\'t handle input character type: {}.' .format(str(type(char)))) stdscr.addstr(key_info(result)) return result
def key_info(key): try: _ord = ord(key) except: _ord = -1 try: _chr = chr(key) except: _chr = -1 try: unctrl = curses.unctrl(key) except: unctrl = 'no unctrl' try: name = curses.keyname(key) except: name = 'no name' return ('repr: {}, type: {}, ord: {}, chr: {}, unctrl: {}, name: {}\n' .format(repr(key), type(key), _ord, _chr, unctrl, name))
def key_to_string(key): """Replace special characters with a readable string""" if key == 27: result = 'esc' elif key == 10 or key == 13: result = '\n' elif key == 9: result = '\t' elif key == 8 or key == curses.KEY_BACKSPACE: result = '\b' elif key == 330 or key == curses.KEY_DC: result = 'del' elif key < 32: result = curses.unctrl(key) result = result.decode() result = 'ctrl-' + result[1].lower() elif key < 256: result = chr(key) else: # key must be some kind of function key try: result = curses.keyname(key) except: raise IOError('Can\'t handle input character type: {}.' .format(str(type(key)))) else: try: result = result.decode() except AttributeError: debug('Cant decode ' + repr(result)) result = result[4:].lower() # Remove parenthesis for function keys result.replace('(', '') result.replace(')', '') #debug(result) return result