| 1 | """ |
| 2 | Key sequence definitions for terminal input simulation. |
| 3 | |
| 4 | These escape sequences follow standard xterm/VT100 conventions. |
| 5 | """ |
| 6 | |
| 7 | # Arrow keys (CSI sequences) |
| 8 | ARROW_UP = "\x1b[A" |
| 9 | ARROW_DOWN = "\x1b[B" |
| 10 | ARROW_RIGHT = "\x1b[C" |
| 11 | ARROW_LEFT = "\x1b[D" |
| 12 | |
| 13 | # Control keys (ASCII control characters) |
| 14 | CTRL_A = "\x01" # Beginning of line |
| 15 | CTRL_B = "\x02" # Back one character |
| 16 | CTRL_C = "\x03" # Interrupt (SIGINT) |
| 17 | CTRL_D = "\x04" # Delete char / EOF |
| 18 | CTRL_E = "\x05" # End of line |
| 19 | CTRL_F = "\x06" # Forward one character |
| 20 | CTRL_G = "\x07" # Cancel |
| 21 | CTRL_H = "\x08" # Backspace (alternative) |
| 22 | CTRL_I = "\x09" # Tab |
| 23 | CTRL_J = "\x0a" # Newline |
| 24 | CTRL_K = "\x0b" # Kill to end of line |
| 25 | CTRL_L = "\x0c" # Clear screen |
| 26 | CTRL_M = "\x0d" # Carriage return (Enter) |
| 27 | CTRL_N = "\x0e" # Next history |
| 28 | CTRL_O = "\x0f" # Operate and get next |
| 29 | CTRL_P = "\x10" # Previous history |
| 30 | CTRL_Q = "\x11" # Resume output |
| 31 | CTRL_R = "\x12" # Reverse search |
| 32 | CTRL_S = "\x13" # Forward search / Suspend output |
| 33 | CTRL_T = "\x14" # Transpose characters |
| 34 | CTRL_U = "\x15" # Kill to beginning of line |
| 35 | CTRL_V = "\x16" # Quoted insert |
| 36 | CTRL_W = "\x17" # Kill word backward |
| 37 | CTRL_X = "\x18" # Prefix |
| 38 | CTRL_Y = "\x19" # Yank |
| 39 | CTRL_Z = "\x1a" # Suspend (SIGTSTP) |
| 40 | |
| 41 | # Alt/Meta keys (ESC + key) |
| 42 | ALT_B = "\x1bb" # Back one word |
| 43 | ALT_C = "\x1bc" # Capitalize word |
| 44 | ALT_D = "\x1bd" # Delete word forward |
| 45 | ALT_F = "\x1bf" # Forward one word |
| 46 | ALT_L = "\x1bl" # Lowercase word |
| 47 | ALT_T = "\x1bt" # Transpose words |
| 48 | ALT_U = "\x1bu" # Uppercase word |
| 49 | ALT_Y = "\x1by" # Yank pop |
| 50 | ALT_DOT = "\x1b." # Insert last argument |
| 51 | ALT_BACKSPACE = "\x1b\x7f" # Delete word backward |
| 52 | |
| 53 | # Special keys |
| 54 | TAB = "\t" |
| 55 | ENTER = "\r" |
| 56 | NEWLINE = "\n" |
| 57 | BACKSPACE = "\x7f" |
| 58 | ESCAPE = "\x1b" |
| 59 | |
| 60 | # Extended keys (xterm sequences) |
| 61 | DELETE = "\x1b[3~" |
| 62 | HOME = "\x1b[H" |
| 63 | END = "\x1b[F" |
| 64 | PAGE_UP = "\x1b[5~" |
| 65 | PAGE_DOWN = "\x1b[6~" |
| 66 | INSERT = "\x1b[2~" |
| 67 | |
| 68 | # Alternative Home/End sequences (some terminals use these) |
| 69 | HOME_ALT = "\x1b[1~" |
| 70 | END_ALT = "\x1b[4~" |
| 71 | |
| 72 | # Function keys |
| 73 | F1 = "\x1bOP" |
| 74 | F2 = "\x1bOQ" |
| 75 | F3 = "\x1bOR" |
| 76 | F4 = "\x1bOS" |
| 77 | F5 = "\x1b[15~" |
| 78 | F6 = "\x1b[17~" |
| 79 | F7 = "\x1b[18~" |
| 80 | F8 = "\x1b[19~" |
| 81 | F9 = "\x1b[20~" |
| 82 | F10 = "\x1b[21~" |
| 83 | F11 = "\x1b[23~" |
| 84 | F12 = "\x1b[24~" |
| 85 | |
| 86 | # Key name to sequence mapping (for YAML test specs) |
| 87 | KEYS = { |
| 88 | # Arrow keys |
| 89 | "Up": ARROW_UP, |
| 90 | "Down": ARROW_DOWN, |
| 91 | "Right": ARROW_RIGHT, |
| 92 | "Left": ARROW_LEFT, |
| 93 | |
| 94 | # Control keys |
| 95 | "C-a": CTRL_A, |
| 96 | "C-b": CTRL_B, |
| 97 | "C-c": CTRL_C, |
| 98 | "C-d": CTRL_D, |
| 99 | "C-e": CTRL_E, |
| 100 | "C-f": CTRL_F, |
| 101 | "C-g": CTRL_G, |
| 102 | "C-h": CTRL_H, |
| 103 | "C-k": CTRL_K, |
| 104 | "C-l": CTRL_L, |
| 105 | "C-n": CTRL_N, |
| 106 | "C-p": CTRL_P, |
| 107 | "C-r": CTRL_R, |
| 108 | "C-s": CTRL_S, |
| 109 | "C-t": CTRL_T, |
| 110 | "C-u": CTRL_U, |
| 111 | "C-w": CTRL_W, |
| 112 | "C-y": CTRL_Y, |
| 113 | "C-z": CTRL_Z, |
| 114 | |
| 115 | # Alt/Meta keys |
| 116 | "M-b": ALT_B, |
| 117 | "M-c": ALT_C, |
| 118 | "M-d": ALT_D, |
| 119 | "M-f": ALT_F, |
| 120 | "M-l": ALT_L, |
| 121 | "M-t": ALT_T, |
| 122 | "M-u": ALT_U, |
| 123 | "M-y": ALT_Y, |
| 124 | "M-.": ALT_DOT, |
| 125 | "M-Backspace": ALT_BACKSPACE, |
| 126 | |
| 127 | # Special keys |
| 128 | "Tab": TAB, |
| 129 | "Enter": ENTER, |
| 130 | "Return": ENTER, |
| 131 | "Backspace": BACKSPACE, |
| 132 | "Delete": DELETE, |
| 133 | "Home": HOME, |
| 134 | "End": END, |
| 135 | "PageUp": PAGE_UP, |
| 136 | "PageDown": PAGE_DOWN, |
| 137 | "Insert": INSERT, |
| 138 | "Escape": ESCAPE, |
| 139 | "Esc": ESCAPE, |
| 140 | |
| 141 | # Function keys |
| 142 | "F1": F1, |
| 143 | "F2": F2, |
| 144 | "F3": F3, |
| 145 | "F4": F4, |
| 146 | "F5": F5, |
| 147 | "F6": F6, |
| 148 | "F7": F7, |
| 149 | "F8": F8, |
| 150 | "F9": F9, |
| 151 | "F10": F10, |
| 152 | "F11": F11, |
| 153 | "F12": F12, |
| 154 | } |
| 155 | |
| 156 | |
| 157 | def get_key(name: str) -> str: |
| 158 | """ |
| 159 | Get the escape sequence for a key name. |
| 160 | |
| 161 | Args: |
| 162 | name: Key name (e.g., "Up", "C-a", "M-f", "Enter") |
| 163 | |
| 164 | Returns: |
| 165 | The escape sequence for that key |
| 166 | |
| 167 | Raises: |
| 168 | KeyError: If the key name is not recognized |
| 169 | """ |
| 170 | if name not in KEYS: |
| 171 | raise KeyError(f"Unknown key: {name}. Available keys: {sorted(KEYS.keys())}") |
| 172 | return KEYS[name] |
| 173 | |
| 174 | |
| 175 | def key_sequence(*keys: str) -> str: |
| 176 | """ |
| 177 | Build a sequence of multiple keys. |
| 178 | |
| 179 | Args: |
| 180 | *keys: Key names to combine |
| 181 | |
| 182 | Returns: |
| 183 | Combined escape sequence string |
| 184 | |
| 185 | Example: |
| 186 | key_sequence("C-a", "C-k") # Move to beginning, kill to end |
| 187 | """ |
| 188 | return "".join(get_key(k) for k in keys) |