diff --git a/bin/kitty_keytester.py b/bin/kitty_keytester.py new file mode 100644 index 0000000000..1575d3bb2a --- /dev/null +++ b/bin/kitty_keytester.py @@ -0,0 +1,196 @@ +from termios import tcgetattr, tcsetattr, TCSADRAIN, TIOCGWINSZ, TCSAFLUSH +from tty import setcbreak, setraw +import os +import sys +from contextlib import contextmanager +from select import select +from time import sleep +from json import dumps, loads +from typing import Optional, Tuple, Union + + +class TerminalContext: + def __init__(self, fd: int, close_fd=False) -> None: + if not os.isatty(fd): + raise TypeError('fd is not a terminal') + self.close_fd = close_fd + self.fd = fd + self.is_cbreak = False + self.is_raw = False + self._initial_attr = self.termios_attributes + + @classmethod + def from_cterm(cls): + fd = os.open(os.ctermid(), os.O_RDWR) + return TerminalContext(fd, True) + + def close(self) -> None: + tcsetattr(self.fd, TCSADRAIN, self._initial_attr) + if self.close_fd: + os.close(self.fd) + + @property + def termios_attributes(self) -> list: + return tcgetattr(self.fd) + + @property + def ttyname(self) -> str: + return os.ttyname(self.fd) + + @contextmanager + def cbreak_mode(self): + """ + Enter cbreak mode context. + """ + if self.is_cbreak: + yield + return + tattr = self.termios_attributes + try: + setcbreak(self.fd, TCSADRAIN) + self.is_cbreak = True + yield + finally: + tcsetattr(self.fd, TCSADRAIN, tattr) + self.is_cbreak = False + + @contextmanager + def raw_mode(self): + """ + Enter cbreak mode context. + """ + if self.is_raw: + yield + return + tattr = self.termios_attributes + try: + setraw(self.fd, TCSADRAIN) + self.is_raw = True + yield + finally: + tcsetattr(self.fd, TCSADRAIN, tattr) + self.is_raw = False + + @contextmanager + def custom_state(self, undo=None): + """ + Enter custom terminal state, that needs to to be undone by ``undo``. + Useful, if you want to apply a custom terminal state and + have to make sure, that it gets properly reset to previous state. + """ + try: + yield + finally: + if undo: + undo() + + def write(self, data: Union[str, bytes]) -> None: + """ + Write string or bytes directly to the terminal. + """ + if isinstance(data, str): + data = data.encode('utf-8') + sent = os.write(self.fd, data) + while sent: + data = data[sent:] + sent = os.write(self.fd, data) + + def read(self, amount: int = 1024, timeout: Optional[float] = None) -> bytes: + """ + Blocking read from the terminal. + If nothing was sent from the terminal within ``timeout``, + empty bytes are returned. + """ + can_read, _, _ = select([self.fd], [], [], timeout) + if can_read: + return os.read(self.fd, amount) + return b'' + + +@contextmanager +def cterminal_context(): + t = TerminalContext.from_cterm() + try: + yield t + finally: + t.close() + + +def extract_events(data: list[str]): + if len(data) < 5: + raise Exception('not enough reports') + types = set(data) + if len(types) == 1: + return {'PRESS': data[0], 'REPEAT': data[0], 'RELEASE': None} + if len(types) == 2: + last = data.pop() + if last != data[0] and len(set(data)) == 1: + return {'PRESS': data[0], 'REPEAT': data[0], 'RELEASE': last} + raise Exception('weird reports, 2 types') + if len(types) == 3: + first = data.pop(0) + last = data.pop() + if first != last and first != data[0] and last != data[0]: + return {'PRESS': first, 'REPEAT': data[0], 'RELEASE': last} + raise Exception('weird reports, 3 types') + raise Exception('more than 3 types') + + +def query(term: TerminalContext, mode: int): + with term.custom_state(undo=lambda:term.write('\x1b[{mode}u') + term.read(timeout=.1) + print('PRESS (within 5s) and HOLD (for 5s)\r') + data: list[bytes] = [] + cur = term.read(timeout=5) + while cur: + data.append(cur) + cur = term.read(timeout=.5) + if len(data) > 5: + print('RELEASE\r', end='') + try: + return extract_events([b.decode('utf-8') for b in data]) + except Exception as e: + print('Error:', e, '\r') + print(data, '\r') + term.read(timeout=.1) + + +def save(filedata: dict[str, dict[str, str]], filename, entry, mode, events): + try: + filedata[entry][mode] = events + except KeyError: + filedata[entry] = {mode: events} + with open(filename, 'w') as f: + f.write(dumps(filedata, indent=2)) + + +def main(): + mode = 1 + filedata = {} + print(sys.argv) + if len(sys.argv) != 3: + print('ERROR: not enough arguments') + print('Usage: python kitty_keytester.py ') + return + mode = int(sys.argv[1]) + filename = sys.argv[2] + if os.path.exists(filename): + with open(filename) as f: + filedata = loads(f.read()) + with cterminal_context() as term: + while True: + with term.raw_mode(): + events = query(term, mode) + if events: + print(events) + entry = input('Entry: ') + if entry: + save(filedata, filename, entry, str(mode), events) + cont = input('Continue? (y)') + if cont not in ['y', '']: + break + + +if __name__ == '__main__': + main() diff --git a/fixtures/kitty_keyboard/german_qwertz_capslock_numlock.json b/fixtures/kitty_keyboard/german_qwertz_capslock_numlock.json new file mode 100644 index 0000000000..97e063c475 --- /dev/null +++ b/fixtures/kitty_keyboard/german_qwertz_capslock_numlock.json @@ -0,0 +1,373 @@ +{ + "Escape +CapsLock": { + "1": { + "PRESS": "\u001b[27;65u", + "REPEAT": "\u001b[27;65u", + "RELEASE": null + } + }, + "F1 +CapsLock": { + "1": { + "PRESS": "\u001b[1;65P", + "REPEAT": "\u001b[1;65P", + "RELEASE": null + } + }, + "Insert +CapsLock": { + "1": { + "PRESS": "\u001b[2;65~", + "REPEAT": "\u001b[2;65~", + "RELEASE": null + } + }, + "Delete +CapsLock": { + "1": { + "PRESS": "\u001b[3;65~", + "REPEAT": "\u001b[3;65~", + "RELEASE": null + } + }, + "PageUp +CapsLock": { + "1": { + "PRESS": "\u001b[5;65~", + "REPEAT": "\u001b[5;65~", + "RELEASE": null + } + }, + "Dead (Backquote) +CapsLock": { + "1": { + "PRESS": "^", + "REPEAT": "^", + "RELEASE": null + } + }, + "1 (Digit1) +CapsLock": { + "1": { + "PRESS": "1", + "REPEAT": "1", + "RELEASE": null + } + }, + "\u00df (Minus) +CapsLock": { + "1": { + "PRESS": "\u1e9e", + "REPEAT": "\u1e9e", + "RELEASE": null + } + }, + "Dead (Equal) +CapsLock": { + "1": { + "PRESS": "\u00b4", + "REPEAT": "\u00b4", + "RELEASE": null + } + }, + "Backspace +CapsLock": { + "1": { + "PRESS": "\u007f", + "REPEAT": "\u007f", + "RELEASE": null + } + }, + "Tab +CapsLock": { + "1": { + "PRESS": "\t", + "REPEAT": "\t", + "RELEASE": null + } + }, + "Q (KeyQ) +CapsLock": { + "1": { + "PRESS": "Q", + "REPEAT": "Q", + "RELEASE": null + } + }, + "\u00dc (BracketLeft) +CapsLock": { + "1": { + "PRESS": "\u00dc", + "REPEAT": "\u00dc", + "RELEASE": null + } + }, + "+ (BracketRight) +CapsLock": { + "1": { + "PRESS": "+", + "REPEAT": "+", + "RELEASE": null + } + }, + "Enter +CapsLock": { + "1": { + "PRESS": "\r", + "REPEAT": "\r", + "RELEASE": null + } + }, + "\u00d6 (Semicolon) +CapsLock": { + "1": { + "PRESS": "\u00d6", + "REPEAT": "\u00d6", + "RELEASE": null + } + }, + "\u00c4 (Quote) +CapsLock": { + "1": { + "PRESS": "\u00c4", + "REPEAT": "\u00c4", + "RELEASE": null + } + }, + "# (Bashslash) +CapsLock": { + "1": { + "PRESS": "#", + "REPEAT": "#", + "RELEASE": null + } + }, + "< (IntlBackslash) +CapsLock": { + "1": { + "PRESS": "<", + "REPEAT": "<", + "RELEASE": null + } + }, + ", (Comma) +CapsLock": { + "1": { + "PRESS": ",", + "REPEAT": ",", + "RELEASE": null + } + }, + ". (Period) +CapsLock": { + "1": { + "PRESS": ".", + "REPEAT": ".", + "RELEASE": null + } + }, + "- (Slash) +CapsLock": { + "1": { + "PRESS": "-", + "REPEAT": "-", + "RELEASE": null + } + }, + "ArrowUp +CapsLock": { + "1": { + "PRESS": "\u001b[1;65A", + "REPEAT": "\u001b[1;65A", + "RELEASE": null + } + }, + "PageDown +CapsLock": { + "1": { + "PRESS": "\u001b[6;65~", + "REPEAT": "\u001b[6;65~", + "RELEASE": null + } + }, + "Home +CapsLock": { + "1": { + "PRESS": "\u001b[1;65H", + "REPEAT": "\u001b[1;65H", + "RELEASE": null + } + }, + "End +CapsLock": { + "1": { + "PRESS": "\u001b[1;65F", + "REPEAT": "\u001b[1;65F", + "RELEASE": null + } + }, + "+ (NumpadAdd) +CapsLock": { + "1": { + "PRESS": "+", + "REPEAT": "+", + "RELEASE": null + } + }, + "Enter (NumpadEnter) +CapsLock": { + "1": { + "PRESS": "\u001b[57414;65u", + "REPEAT": "\u001b[57414;65u", + "RELEASE": null + } + }, + "Insert (Numpad0) +CapsLock": { + "1": { + "PRESS": "\u001b[57425;65u", + "REPEAT": "\u001b[57425;65u", + "RELEASE": null + } + }, + "\u0000 (NumpadDecimal) +CapsLock": { + "1": { + "PRESS": "\u001b[57426;65u", + "REPEAT": "\u001b[57426;65u", + "RELEASE": null + } + }, + "Numlock +CapsLock": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + "CapsLock +CapsLock": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + "Shift (ShiftLeft) +CapsLock": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + "Shift (ShiftRight) +CapsLock": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + "Control (ControlLeft) +CapsLock": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + "Meta (MetaLeft) +CapsLock": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + "Alt (AltLeft) +CapsLock": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + "AltGraph (AltRight) +CapsLock": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + "Control (ControlRight) +CapsLock": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + "/ (NumpadDivide) +NumLock": { + "1": { + "PRESS": "/", + "REPEAT": "/", + "RELEASE": null + } + }, + "* (NumpadMultiply) +NumLock": { + "1": { + "PRESS": "*", + "REPEAT": "*", + "RELEASE": null + } + }, + "- (NumpadSubtract) +NumLock": { + "1": { + "PRESS": "-", + "REPEAT": "-", + "RELEASE": null + } + }, + "0 (Numpad0) +NumLock": { + "1": { + "PRESS": "0", + "REPEAT": "0", + "RELEASE": null + } + }, + "1 (Numpad1) +NumLock": { + "1": { + "PRESS": "1", + "REPEAT": "1", + "RELEASE": null + } + }, + "2 (Numpad2) +NumLock": { + "1": { + "PRESS": "2", + "REPEAT": "2", + "RELEASE": null + } + }, + "3 (Numpad3) +NumLock": { + "1": { + "PRESS": "3", + "REPEAT": "3", + "RELEASE": null + } + }, + "4 (Numpad4) +NumLock": { + "1": { + "PRESS": "4", + "REPEAT": "4", + "RELEASE": null + } + }, + "5 (Numpad5) +NumLock": { + "1": { + "PRESS": "5", + "REPEAT": "5", + "RELEASE": null + } + }, + "6 (Numpad6) +NumLock": { + "1": { + "PRESS": "6", + "REPEAT": "6", + "RELEASE": null + } + }, + "7 (Numpad7) +NumLock": { + "1": { + "PRESS": "7", + "REPEAT": "7", + "RELEASE": null + } + }, + "8 (Numpad8) +NumLock": { + "1": { + "PRESS": "8", + "REPEAT": "8", + "RELEASE": null + } + }, + "9 (Numpad9) +NumLock": { + "1": { + "PRESS": "9", + "REPEAT": "9", + "RELEASE": null + } + }, + ", (NumpadDecimal) +NumLock": { + "1": { + "PRESS": ",", + "REPEAT": ",", + "RELEASE": null + } + } +} \ No newline at end of file diff --git a/fixtures/kitty_keyboard/german_qwertz_no_modifier.json b/fixtures/kitty_keyboard/german_qwertz_no_modifier.json new file mode 100644 index 0000000000..472f939ddf --- /dev/null +++ b/fixtures/kitty_keyboard/german_qwertz_no_modifier.json @@ -0,0 +1,702 @@ +{ + "Escape": { + "1": { + "PRESS": "\u001b[27u", + "REPEAT": "\u001b[27u", + "RELEASE": null + } + }, + "F1": { + "1": { + "PRESS": "\u001b[P", + "REPEAT": "\u001b[P", + "RELEASE": null + } + }, + "F2": { + "1": { + "PRESS": "\u001b[Q", + "REPEAT": "\u001b[Q", + "RELEASE": null + } + }, + "F3": { + "1": { + "PRESS": "\u001b[13~", + "REPEAT": "\u001b[13~", + "RELEASE": null + } + }, + "F4": { + "1": { + "PRESS": "\u001b[S", + "REPEAT": "\u001b[S", + "RELEASE": null + } + }, + "F5": { + "1": { + "PRESS": "\u001b[15~", + "REPEAT": "\u001b[15~", + "RELEASE": null + } + }, + "F6": { + "1": { + "PRESS": "\u001b[17~", + "REPEAT": "\u001b[17~", + "RELEASE": null + } + }, + "F7": { + "1": { + "PRESS": "\u001b[18~", + "REPEAT": "\u001b[18~", + "RELEASE": null + } + }, + "F8": { + "1": { + "PRESS": "\u001b[19~", + "REPEAT": "\u001b[19~", + "RELEASE": null + } + }, + "F9": { + "1": { + "PRESS": "\u001b[20~", + "REPEAT": "\u001b[20~", + "RELEASE": null + } + }, + "F10": { + "1": { + "PRESS": "\u001b[21~", + "REPEAT": "\u001b[21~", + "RELEASE": null + } + }, + "F11": { + "1": { + "PRESS": "\u001b[23~", + "REPEAT": "\u001b[23~", + "RELEASE": null + } + }, + "F12": { + "1": { + "PRESS": "\u001b[24~", + "REPEAT": "\u001b[24~", + "RELEASE": null + } + }, + "Insert": { + "1": { + "PRESS": "\u001b[2~", + "REPEAT": "\u001b[2~", + "RELEASE": null + } + }, + "Delete": { + "1": { + "PRESS": "\u001b[3~", + "REPEAT": "\u001b[3~", + "RELEASE": null + } + }, + "PageUp": { + "1": { + "PRESS": "\u001b[5~", + "REPEAT": "\u001b[5~", + "RELEASE": null + } + }, + "PageDown": { + "1": { + "PRESS": "\u001b[6~", + "REPEAT": "\u001b[6~", + "RELEASE": null + } + }, + "Home": { + "1": { + "PRESS": "\u001b[H", + "REPEAT": "\u001b[H", + "RELEASE": null + } + }, + "End": { + "1": { + "PRESS": "\u001b[F", + "REPEAT": "\u001b[F", + "RELEASE": null + } + }, + "Dead (Backquote)": { + "1": { + "PRESS": "^", + "REPEAT": "^", + "RELEASE": null + } + }, + "1 (Digit1)": { + "1": { + "PRESS": "1", + "REPEAT": "1", + "RELEASE": null + } + }, + "2 (Digit2)": { + "1": { + "PRESS": "2", + "REPEAT": "2", + "RELEASE": null + } + }, + "3 (Digit3)": { + "1": { + "PRESS": "3", + "REPEAT": "3", + "RELEASE": null + } + }, + "4 (Digit4)": { + "1": { + "PRESS": "4", + "REPEAT": "4", + "RELEASE": null + } + }, + "5 (Digit5)": { + "1": { + "PRESS": "5", + "REPEAT": "5", + "RELEASE": null + } + }, + "6 (Digit6)": { + "1": { + "PRESS": "6", + "REPEAT": "6", + "RELEASE": null + } + }, + "7 (Digit7)": { + "1": { + "PRESS": "7", + "REPEAT": "7", + "RELEASE": null + } + }, + "8 (Digit8)": { + "1": { + "PRESS": "8", + "REPEAT": "8", + "RELEASE": null + } + }, + "9 (Digit9)": { + "1": { + "PRESS": "9", + "REPEAT": "9", + "RELEASE": null + } + }, + "0 (Digit0)": { + "1": { + "PRESS": "0", + "REPEAT": "0", + "RELEASE": null + } + }, + "\u00df (Minus)": { + "1": { + "PRESS": "\u00df", + "REPEAT": "\u00df", + "RELEASE": null + } + }, + "Dead (Equal)": { + "1": { + "PRESS": "\u00b4", + "REPEAT": "\u00b4", + "RELEASE": null + } + }, + "Backspace": { + "1": { + "PRESS": "\u007f", + "REPEAT": "\u007f", + "RELEASE": null + } + }, + "Tab": { + "1": { + "PRESS": "\t", + "REPEAT": "\t", + "RELEASE": null + } + }, + "q (KeyQ)": { + "1": { + "PRESS": "q", + "REPEAT": "q", + "RELEASE": null + } + }, + "w (KeyW)": { + "1": { + "PRESS": "w", + "REPEAT": "w", + "RELEASE": null + } + }, + "e (KeyE)": { + "1": { + "PRESS": "e", + "REPEAT": "e", + "RELEASE": null + } + }, + "r (KeyR)": { + "1": { + "PRESS": "r", + "REPEAT": "r", + "RELEASE": null + } + }, + "t (KeyT)": { + "1": { + "PRESS": "t", + "REPEAT": "t", + "RELEASE": null + } + }, + "z (KeyY)": { + "1": { + "PRESS": "z", + "REPEAT": "z", + "RELEASE": null + } + }, + "u (KeyU)": { + "1": { + "PRESS": "u", + "REPEAT": "u", + "RELEASE": null + } + }, + "i (KeyI)": { + "1": { + "PRESS": "i", + "REPEAT": "i", + "RELEASE": null + } + }, + "o (KeyO)": { + "1": { + "PRESS": "o", + "REPEAT": "o", + "RELEASE": null + } + }, + "p (KeyP)": { + "1": { + "PRESS": "p", + "REPEAT": "p", + "RELEASE": null + } + }, + "\u00fc (BracketLeft)": { + "1": { + "PRESS": "\u00fc", + "REPEAT": "\u00fc", + "RELEASE": null + } + }, + "+ (BracketRight)": { + "1": { + "PRESS": "+", + "REPEAT": "+", + "RELEASE": null + } + }, + "Enter": { + "1": { + "PRESS": "\r", + "REPEAT": "\r", + "RELEASE": null + } + }, + "a (KeyA)": { + "1": { + "PRESS": "a", + "REPEAT": "a", + "RELEASE": null + } + }, + "s (KeyS)": { + "1": { + "PRESS": "s", + "REPEAT": "s", + "RELEASE": null + } + }, + "d (KeyD)": { + "1": { + "PRESS": "d", + "REPEAT": "d", + "RELEASE": null + } + }, + "f (KeyF)": { + "1": { + "PRESS": "f", + "REPEAT": "f", + "RELEASE": null + } + }, + "g (KeyG)": { + "1": { + "PRESS": "g", + "REPEAT": "g", + "RELEASE": null + } + }, + "h (KeyH)": { + "1": { + "PRESS": "h", + "REPEAT": "h", + "RELEASE": null + } + }, + "j (KeyJ)": { + "1": { + "PRESS": "j", + "REPEAT": "j", + "RELEASE": null + } + }, + "k (KeyK)": { + "1": { + "PRESS": "k", + "REPEAT": "k", + "RELEASE": null + } + }, + "l (KeyL)": { + "1": { + "PRESS": "l", + "REPEAT": "l", + "RELEASE": null + } + }, + "\u00f6 (Semicolon)": { + "1": { + "PRESS": "\u00f6", + "REPEAT": "\u00f6", + "RELEASE": null + } + }, + "\u00e4 (Quote)": { + "1": { + "PRESS": "\u00e4", + "REPEAT": "\u00e4", + "RELEASE": null + } + }, + "# (Backslash)": { + "1": { + "PRESS": "#", + "REPEAT": "#", + "RELEASE": null + } + }, + "< (IntlBackslash)": { + "1": { + "PRESS": "<", + "REPEAT": "<", + "RELEASE": null + } + }, + "y (KeyZ)": { + "1": { + "PRESS": "y", + "REPEAT": "y", + "RELEASE": null + } + }, + "x (KeyX)": { + "1": { + "PRESS": "x", + "REPEAT": "x", + "RELEASE": null + } + }, + "c (KeyC)": { + "1": { + "PRESS": "c", + "REPEAT": "c", + "RELEASE": null + } + }, + "v (KeyV)": { + "1": { + "PRESS": "v", + "REPEAT": "v", + "RELEASE": null + } + }, + "b (KeyB)": { + "1": { + "PRESS": "b", + "REPEAT": "b", + "RELEASE": null + } + }, + "n (KeyN)": { + "1": { + "PRESS": "n", + "REPEAT": "n", + "RELEASE": null + } + }, + "m (KeyM)": { + "1": { + "PRESS": "m", + "REPEAT": "m", + "RELEASE": null + } + }, + ", (Comma)": { + "1": { + "PRESS": ",", + "REPEAT": ",", + "RELEASE": null + } + }, + ". (Period)": { + "1": { + "PRESS": ".", + "REPEAT": ".", + "RELEASE": null + } + }, + "- (Slash)": { + "1": { + "PRESS": "-", + "REPEAT": "-", + "RELEASE": null + } + }, + "ArrowLeft": { + "1": { + "PRESS": "\u001b[D", + "REPEAT": "\u001b[D", + "RELEASE": null + } + }, + "ArrowUp": { + "1": { + "PRESS": "\u001b[A", + "REPEAT": "\u001b[A", + "RELEASE": null + } + }, + "ArrowRight": { + "1": { + "PRESS": "\u001b[C", + "REPEAT": "\u001b[C", + "RELEASE": null + } + }, + "ArrowDown": { + "1": { + "PRESS": "\u001b[B", + "REPEAT": "\u001b[B", + "RELEASE": null + } + }, + "/ (NumpadDivide)": { + "1": { + "PRESS": "/", + "REPEAT": "/", + "RELEASE": null + } + }, + "* (NumpadMultiply)": { + "1": { + "PRESS": "*", + "REPEAT": "*", + "RELEASE": null + } + }, + "- (NumpadSubtract)": { + "1": { + "PRESS": "-", + "REPEAT": "-", + "RELEASE": null + } + }, + "Home (Numpad7)": { + "1": { + "PRESS": "\u001b[57423u", + "REPEAT": "\u001b[57423u", + "RELEASE": null + } + }, + "ArrowUp (Numpad8)": { + "1": { + "PRESS": "\u001b[57419u", + "REPEAT": "\u001b[57419u", + "RELEASE": null + } + }, + "PageUp (Numpad9)": { + "1": { + "PRESS": "\u001b[57421u", + "REPEAT": "\u001b[57421u", + "RELEASE": null + } + }, + "+ (NumpadAdd)": { + "1": { + "PRESS": "+", + "REPEAT": "+", + "RELEASE": null + } + }, + "ArrowLeft (Numpad4)": { + "1": { + "PRESS": "\u001b[57417u", + "REPEAT": "\u001b[57417u", + "RELEASE": null + } + }, + "Clear (Numpad5)": { + "1": { + "PRESS": "\u001b[E", + "REPEAT": "\u001b[E", + "RELEASE": null + } + }, + "ArrowRight (Numpad6)": { + "1": { + "PRESS": "\u001b[57418u", + "REPEAT": "\u001b[57418u", + "RELEASE": null + } + }, + "End (Numpad1)": { + "1": { + "PRESS": "\u001b[57424u", + "REPEAT": "\u001b[57424u", + "RELEASE": null + } + }, + "ArrowDown (Numpad2)": { + "1": { + "PRESS": "\u001b[57420u", + "REPEAT": "\u001b[57420u", + "RELEASE": null + } + }, + "PageDown (Numpad3)": { + "1": { + "PRESS": "\u001b[57422u", + "REPEAT": "\u001b[57422u", + "RELEASE": null + } + }, + "Enter (NumpadEnter)": { + "1": { + "PRESS": "\u001b[57414u", + "REPEAT": "\u001b[57414u", + "RELEASE": null + } + }, + "Insert (Numpad0)": { + "1": { + "PRESS": "\u001b[57425u", + "REPEAT": "\u001b[57425u", + "RELEASE": null + } + }, + "\u0000 (NumpadDecimal)": { + "1": { + "PRESS": "\u001b[57426u", + "REPEAT": "\u001b[57426u", + "RELEASE": null + } + }, + "Numlock": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + "CapsLock": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + "Shift (ShiftLeft)": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + "Shift (ShiftRight)": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + "Control (ControlLeft)": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + "Meta (MetaLeft)": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + "Alt (AltLeft)": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + " (Space)": { + "1": { + "PRESS": " ", + "REPEAT": " ", + "RELEASE": null + } + }, + "AltGraph (AltRight)": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + "Control (ControlRight)": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + } +} \ No newline at end of file diff --git a/fixtures/kitty_keyboard/german_qwertz_shift.json b/fixtures/kitty_keyboard/german_qwertz_shift.json new file mode 100644 index 0000000000..36dea1f943 --- /dev/null +++ b/fixtures/kitty_keyboard/german_qwertz_shift.json @@ -0,0 +1,331 @@ +{ + "Escape +Shift": { + "1": { + "PRESS": "\u001b[27;2u", + "REPEAT": "\u001b[27;2u", + "RELEASE": null + } + }, + "F1 +Shift": { + "1": { + "PRESS": "\u001b[1;2P", + "REPEAT": "\u001b[1;2P", + "RELEASE": null + } + }, + "Delete +Shift": { + "1": { + "PRESS": "\u001b[3;2~", + "REPEAT": "\u001b[3;2~", + "RELEASE": null + } + }, + "PageUp +Shift": { + "1": { + "PRESS": "\u001b[5;2~", + "REPEAT": "\u001b[5;2~", + "RELEASE": null + } + }, + "Dead (Backquote) +Shift": { + "1": { + "PRESS": "\u00b0", + "REPEAT": "\u00b0", + "RELEASE": null + } + }, + "! (Digit1) +Shift": { + "1": { + "PRESS": "!", + "REPEAT": "!", + "RELEASE": null + } + }, + "\" (Digit2) +Shift": { + "1": { + "PRESS": "\"", + "REPEAT": "\"", + "RELEASE": null + } + }, + "\u00a7 (Digit3) +Shift": { + "1": { + "PRESS": "\u00a7", + "REPEAT": "\u00a7", + "RELEASE": null + } + }, + "$ (Digit4) +Shifft": { + "1": { + "PRESS": "$", + "REPEAT": "$", + "RELEASE": null + } + }, + "% (Digit5) +Shift": { + "1": { + "PRESS": "%", + "REPEAT": "%", + "RELEASE": null + } + }, + "& (Digit6) +Shift": { + "1": { + "PRESS": "&", + "REPEAT": "&", + "RELEASE": null + } + }, + "/ (Digit7) +Shift": { + "1": { + "PRESS": "/", + "REPEAT": "/", + "RELEASE": null + } + }, + "( (Digit8) +Shift": { + "1": { + "PRESS": "(", + "REPEAT": "(", + "RELEASE": null + } + }, + ") (Digit9) +Shift": { + "1": { + "PRESS": ")", + "REPEAT": ")", + "RELEASE": null + } + }, + "= (Digit0) +Shift": { + "1": { + "PRESS": "=", + "REPEAT": "=", + "RELEASE": null + } + }, + "? (Minus) +Shift": { + "1": { + "PRESS": "?", + "REPEAT": "?", + "RELEASE": null + } + }, + "Backspace +Shift": { + "1": { + "PRESS": "\u001b[127;2u", + "REPEAT": "\u001b[127;2u", + "RELEASE": null + } + }, + "Tab +Shift": { + "1": { + "PRESS": "\u001b[9;2u", + "REPEAT": "\u001b[9;2u", + "RELEASE": null + } + }, + "Q (KeyQ) +Shift": { + "1": { + "PRESS": "Q", + "REPEAT": "Q", + "RELEASE": null + } + }, + "\u00dc (BracketLeft) +Shift": { + "1": { + "PRESS": "\u00dc", + "REPEAT": "\u00dc", + "RELEASE": null + } + }, + "* (BracketRight) +Shift": { + "1": { + "PRESS": "*", + "REPEAT": "*", + "RELEASE": null + } + }, + "Enter +Shift": { + "1": { + "PRESS": "\u001b[13;2u", + "REPEAT": "\u001b[13;2u", + "RELEASE": null + } + }, + "\u00d6 (Semicolon) +Shift": { + "1": { + "PRESS": "\u00d6", + "REPEAT": "\u00d6", + "RELEASE": null + } + }, + "\u00c4 (Quote) +Shift": { + "1": { + "PRESS": "\u00c4", + "REPEAT": "\u00c4", + "RELEASE": null + } + }, + "' (Backslash) +Shift": { + "1": { + "PRESS": "'", + "REPEAT": "'", + "RELEASE": null + } + }, + "> (IntlBackslash) +Shift": { + "1": { + "PRESS": ">", + "REPEAT": ">", + "RELEASE": null + } + }, + "; (Comma) +Shift": { + "1": { + "PRESS": ";", + "REPEAT": ";", + "RELEASE": null + } + }, + ": (Period) +Shift": { + "1": { + "PRESS": ":", + "REPEAT": ":", + "RELEASE": null + } + }, + "_ (Slash) +Shift": { + "1": { + "PRESS": "_", + "REPEAT": "_", + "RELEASE": null + } + }, + "ArrowUp +Shift": { + "1": { + "PRESS": "\u001b[1;2A", + "REPEAT": "\u001b[1;2A", + "RELEASE": null + } + }, + "PageDown +Shift": { + "1": { + "PRESS": "\u001b[6;2~", + "REPEAT": "\u001b[6;2~", + "RELEASE": null + } + }, + "Home +Shift": { + "1": { + "PRESS": "\u001b[1;2H", + "REPEAT": "\u001b[1;2H", + "RELEASE": null + } + }, + "Home (Numpad7) +Shift": { + "1": { + "PRESS": "\u001b[57423;2u", + "REPEAT": "\u001b[57423;2u", + "RELEASE": null + } + }, + "ArrowUp (Numapd8) +Shift": { + "1": { + "PRESS": "\u001b[57419;2u", + "REPEAT": "\u001b[57419;2u", + "RELEASE": null + } + }, + "Clear (Numpad5) +Shift": { + "1": { + "PRESS": "\u001b[1;2E", + "REPEAT": "\u001b[1;2E", + "RELEASE": null + } + }, + "Enter (NumpadEnter) +Shift": { + "1": { + "PRESS": "\u001b[57414;2u", + "REPEAT": "\u001b[57414;2u", + "RELEASE": null + } + }, + "Insert (Numpad0) +Shift": { + "1": { + "PRESS": "\u001b[57425;2u", + "REPEAT": "\u001b[57425;2u", + "RELEASE": null + } + }, + "\u0000 (NumpadDecimal) +Shift": { + "1": { + "PRESS": "\u001b[57426;2u", + "REPEAT": "\u001b[57426;2u", + "RELEASE": null + } + }, + "Numlock +Shift": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + "CapsLock +Shift": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + "Shift (ShiftRight) +Shift": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + "Control (ControlLeft) +Shift": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + "Meta (MetaLeft) +Shift": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + "Alt (AltLeft) +Shift": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + " (Space) +Shift": { + "1": { + "PRESS": " ", + "REPEAT": " ", + "RELEASE": null + } + }, + "AltGraph (AltRight) +Shift": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + }, + "Control (ControlRight) +Shift": { + "1": { + "PRESS": null, + "REPEAT": null, + "RELEASE": null + } + } +} \ No newline at end of file