Python · 4135 bytes Raw Blame History
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)