common.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. # -*- coding: utf-8 -*-
  2. # *****************************************************************************
  3. # Copyright (C) 2003-2006 Gary Bishop.
  4. # Copyright (C) 2006-2020 Jorgen Stenarson. <jorgen.stenarson@bostream.nu>
  5. # Copyright (C) 2020 Bassem Girgis. <brgirgis@gmail.com>
  6. #
  7. # Distributed under the terms of the BSD License. The full license is in
  8. # the file COPYING, distributed as part of this software.
  9. # *****************************************************************************
  10. # table for translating virtual keys to X windows key symbols
  11. try:
  12. set
  13. except NameError:
  14. from sets import Set as set
  15. from pyreadline3.unicode_helper import ensure_unicode
  16. validkey = set(
  17. [
  18. "cancel",
  19. "backspace",
  20. "tab",
  21. "clear",
  22. "return",
  23. "shift_l",
  24. "control_l",
  25. "alt_l",
  26. "pause",
  27. "caps_lock",
  28. "escape",
  29. "space",
  30. "prior",
  31. "next",
  32. "end",
  33. "home",
  34. "left",
  35. "up",
  36. "right",
  37. "down",
  38. "select",
  39. "print",
  40. "execute",
  41. "snapshot",
  42. "insert",
  43. "delete",
  44. "help",
  45. "f1",
  46. "f2",
  47. "f3",
  48. "f4",
  49. "f5",
  50. "f6",
  51. "f7",
  52. "f8",
  53. "f9",
  54. "f10",
  55. "f11",
  56. "f12",
  57. "f13",
  58. "f14",
  59. "f15",
  60. "f16",
  61. "f17",
  62. "f18",
  63. "f19",
  64. "f20",
  65. "f21",
  66. "f22",
  67. "f23",
  68. "f24",
  69. "num_lock",
  70. "scroll_lock",
  71. "vk_apps",
  72. "vk_processkey",
  73. "vk_attn",
  74. "vk_crsel",
  75. "vk_exsel",
  76. "vk_ereof",
  77. "vk_play",
  78. "vk_zoom",
  79. "vk_noname",
  80. "vk_pa1",
  81. "vk_oem_clear",
  82. "numpad0",
  83. "numpad1",
  84. "numpad2",
  85. "numpad3",
  86. "numpad4",
  87. "numpad5",
  88. "numpad6",
  89. "numpad7",
  90. "numpad8",
  91. "numpad9",
  92. "divide",
  93. "multiply",
  94. "add",
  95. "subtract",
  96. "vk_decimal",
  97. ]
  98. )
  99. escape_sequence_to_special_key = {
  100. "\\e[a": "up",
  101. "\\e[b": "down",
  102. "del": "delete",
  103. }
  104. class KeyPress(object):
  105. def __init__(self, char="", shift=False, control=False, meta=False, keyname=""):
  106. if control or meta or shift:
  107. char = char.upper()
  108. self.info = dict(
  109. char=char, shift=shift, control=control, meta=meta, keyname=keyname
  110. )
  111. def create(name):
  112. def get(self):
  113. return self.info[name]
  114. def set(self, value):
  115. self.info[name] = value
  116. return property(get, set)
  117. char = create("char")
  118. shift = create("shift")
  119. control = create("control")
  120. meta = create("meta")
  121. keyname = create("keyname")
  122. def __repr__(self):
  123. return "(%s,%s,%s,%s)" % tuple(map(ensure_unicode, self.tuple()))
  124. def tuple(self):
  125. if self.keyname:
  126. return (self.control, self.meta, self.shift, self.keyname)
  127. else:
  128. if self.control or self.meta or self.shift:
  129. return (self.control, self.meta, self.shift, self.char.upper())
  130. else:
  131. return (self.control, self.meta, self.shift, self.char)
  132. def __eq__(self, other):
  133. if isinstance(other, KeyPress):
  134. s = self.tuple()
  135. o = other.tuple()
  136. return s == o
  137. else:
  138. return False
  139. def make_KeyPress_from_keydescr(keydescr):
  140. keyinfo = KeyPress()
  141. if len(keydescr) > 2 and keydescr[:1] == '"' and keydescr[-1:] == '"':
  142. keydescr = keydescr[1:-1]
  143. while True:
  144. lkeyname = keydescr.lower()
  145. if lkeyname.startswith("control-"):
  146. keyinfo.control = True
  147. keydescr = keydescr[8:]
  148. elif lkeyname.startswith("ctrl-"):
  149. keyinfo.control = True
  150. keydescr = keydescr[5:]
  151. elif keydescr.lower().startswith("\\c-"):
  152. keyinfo.control = True
  153. keydescr = keydescr[3:]
  154. elif keydescr.lower().startswith("\\m-"):
  155. keyinfo.meta = True
  156. keydescr = keydescr[3:]
  157. elif keydescr in escape_sequence_to_special_key:
  158. keydescr = escape_sequence_to_special_key[keydescr]
  159. elif lkeyname.startswith("meta-"):
  160. keyinfo.meta = True
  161. keydescr = keydescr[5:]
  162. elif lkeyname.startswith("alt-"):
  163. keyinfo.meta = True
  164. keydescr = keydescr[4:]
  165. elif lkeyname.startswith("shift-"):
  166. keyinfo.shift = True
  167. keydescr = keydescr[6:]
  168. else:
  169. if len(keydescr) > 1:
  170. if keydescr.strip().lower() in validkey:
  171. keyinfo.keyname = keydescr.strip().lower()
  172. keyinfo.char = ""
  173. else:
  174. raise IndexError("Not a valid key: '%s'" % keydescr)
  175. else:
  176. keyinfo.char = keydescr
  177. return keyinfo
  178. if __name__ == "__main__":
  179. import startup