ESC = '\x1b' def assert_type(thing,_type): ''' if thing is not of type _type raise an exception ''' if type(thing) is not _type: raise(TypeError, "%s is of %s, should be of %s" % (str(thing),type(thing),_type) ) class Key: ''' a keyboard keypress object ''' def __init__(self,name,*modifiers): assert_type(name,str) for m in modifiers: assert isinstance(m,Key), "Modifiers expected to be instances of Key" self.name = name self.modifiers = list(modifiers) self.modifiers.sort() def __eq__(self,other): if not isinstance(other,Key): return False return str(self) == str(other) def __ne__(self,other): if isinstance(Key,other): return True return str(self) != str(other) def __str__(self): to_return = str() for m in self.modifiers: to_return += '%s ' % str(m) to_return += self.name return to_return def has_modifier(self,modifier): ''' does this object have the modifier? ''' if modifier in self.modifiers: return True return False def modify(self,modifier): ''' add a modifier ''' if modifier not in self.modifiers: self.modifiers.append(modifier) self.modifiers.sort() return self ALT = Key('Alt') CTRL = Key('Control') table = { ESC : Key('Escape'), '\t': Key('Tab'), ' ': Key('Space'), '\n': Key('Enter'), '\x7f' : Key('Backspace'), '%sOF' % ESC: Key('End'), '%sOH' % ESC: Key('Home'), '%s[3~' % ESC: Key('Del'), '%s[2~' % ESC: Key('Insert'), '%s[5~' % ESC: Key('PageUp'), '%s[6~' % ESC: Key('PageDown'), '%sOP' % ESC: Key('F1'), '%sOQ' % ESC: Key('F2'), '%sOR' % ESC: Key('F3'), '%sOS' % ESC: Key('F4'), '%s[15~' % ESC: Key('F5'), '%s[17~' % ESC: Key('F6'), '%s[18~' % ESC: Key('F7'), '%s[19~' % ESC: Key('F8'), '%s[20~' % ESC: Key('F9'), '%s[21~' % ESC: Key('F10'), '%s[23~' % ESC: Key('F11'), '%s[24~' % ESC: Key('F12'), '%s[A' % ESC: Key('Up'), '%s[B' % ESC: Key('Down'), '%s[D' % ESC: Key('Left'), '%s[C' % ESC: Key('Right'), } def is_alt(code): ''' is this the code of a combination modified by Alt? ''' assert_type(code,str) if len(code) == 2 and code[0] == ESC: return True return False def is_ctrl_alpha(code): ''' is this the code of a combination modified by Ctrl? ''' assert_type(code,str) if code < '\x20': return True return False def get_ctrl_alpha(code): ''' get alphabetic key modified by Ctrl ''' assert_type(code,str) letter = chr(ord(code) + 0x40) return Key(letter,CTRL) def parse_code(code): ''' get Key object from code ''' assert_type(code,str) if code in table.keys(): return table[code] elif is_alt(code): return parse_code(code[1:]).modify(ALT) elif is_ctrl_alpha(code): return get_ctrl_alpha(code) else: return Key(code)