MOVE_DOWN = "\x1b[{}B"
CLEAR = "\x1b[H\x1b[J"
+# State of control keys: https://learn.microsoft.com/en-us/windows/console/key-event-record-str
+ALT_ACTIVE = 0x01 | 0x02
+CTRL_ACTIVE = 0x04 | 0x08
+
class _error(Exception):
pass
continue
return None
- key = rec.Event.KeyEvent.uChar.UnicodeChar
+ key_event = rec.Event.KeyEvent
+ raw_key = key = key_event.uChar.UnicodeChar
- if rec.Event.KeyEvent.uChar.UnicodeChar == "\r":
- # Make enter make unix-like
+ if key == "\r":
+ # Make enter unix-like
return Event(evt="key", data="\n", raw=b"\n")
- elif rec.Event.KeyEvent.wVirtualKeyCode == 8:
+ elif key_event.wVirtualKeyCode == 8:
# Turn backspace directly into the command
- return Event(
- evt="key",
- data="backspace",
- raw=rec.Event.KeyEvent.uChar.UnicodeChar,
- )
- elif rec.Event.KeyEvent.uChar.UnicodeChar == "\x00":
+ key = "backspace"
+ elif key == "\x00":
# Handle special keys like arrow keys and translate them into the appropriate command
- code = VK_MAP.get(rec.Event.KeyEvent.wVirtualKeyCode)
- if code:
- return Event(
- evt="key", data=code, raw=rec.Event.KeyEvent.uChar.UnicodeChar
- )
+ key = VK_MAP.get(key_event.wVirtualKeyCode)
+ if key:
+ if key_event.dwControlKeyState & CTRL_ACTIVE:
+ key = f"ctrl {key}"
+ elif key_event.dwControlKeyState & ALT_ACTIVE:
+ # queue the key, return the meta command
+ self.event_queue.insert(0, Event(evt="key", data=key, raw=key))
+ return Event(evt="key", data="\033") # keymap.py uses this for meta
+ return Event(evt="key", data=key, raw=key)
if block:
continue
return None
- return Event(evt="key", data=key, raw=rec.Event.KeyEvent.uChar.UnicodeChar)
+ if key_event.dwControlKeyState & ALT_ACTIVE:
+ # queue the key, return the meta command
+ self.event_queue.insert(0, Event(evt="key", data=key, raw=raw_key))
+ return Event(evt="key", data="\033") # keymap.py uses this for meta
+
+ return Event(evt="key", data=key, raw=raw_key)
def push_char(self, char: int | bytes) -> None:
"""