Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/prompt_toolkit/input/ansi_escape_sequences.py: 100%
13 statements
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 06:07 +0000
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 06:07 +0000
1"""
2Mappings from VT100 (ANSI) escape sequences to the corresponding prompt_toolkit
3keys.
5We are not using the terminfo/termcap databases to detect the ANSI escape
6sequences for the input. Instead, we recognize 99% of the most common
7sequences. This works well, because in practice, every modern terminal is
8mostly Xterm compatible.
10Some useful docs:
11- Mintty: https://github.com/mintty/mintty/blob/master/wiki/Keycodes.md
12"""
13from __future__ import annotations
15from typing import Dict, Tuple, Union
17from ..keys import Keys
19__all__ = [
20 "ANSI_SEQUENCES",
21 "REVERSE_ANSI_SEQUENCES",
22]
24# Mapping of vt100 escape codes to Keys.
25ANSI_SEQUENCES: dict[str, Keys | tuple[Keys, ...]] = {
26 # Control keys.
27 "\x00": Keys.ControlAt, # Control-At (Also for Ctrl-Space)
28 "\x01": Keys.ControlA, # Control-A (home)
29 "\x02": Keys.ControlB, # Control-B (emacs cursor left)
30 "\x03": Keys.ControlC, # Control-C (interrupt)
31 "\x04": Keys.ControlD, # Control-D (exit)
32 "\x05": Keys.ControlE, # Control-E (end)
33 "\x06": Keys.ControlF, # Control-F (cursor forward)
34 "\x07": Keys.ControlG, # Control-G
35 "\x08": Keys.ControlH, # Control-H (8) (Identical to '\b')
36 "\x09": Keys.ControlI, # Control-I (9) (Identical to '\t')
37 "\x0a": Keys.ControlJ, # Control-J (10) (Identical to '\n')
38 "\x0b": Keys.ControlK, # Control-K (delete until end of line; vertical tab)
39 "\x0c": Keys.ControlL, # Control-L (clear; form feed)
40 "\x0d": Keys.ControlM, # Control-M (13) (Identical to '\r')
41 "\x0e": Keys.ControlN, # Control-N (14) (history forward)
42 "\x0f": Keys.ControlO, # Control-O (15)
43 "\x10": Keys.ControlP, # Control-P (16) (history back)
44 "\x11": Keys.ControlQ, # Control-Q
45 "\x12": Keys.ControlR, # Control-R (18) (reverse search)
46 "\x13": Keys.ControlS, # Control-S (19) (forward search)
47 "\x14": Keys.ControlT, # Control-T
48 "\x15": Keys.ControlU, # Control-U
49 "\x16": Keys.ControlV, # Control-V
50 "\x17": Keys.ControlW, # Control-W
51 "\x18": Keys.ControlX, # Control-X
52 "\x19": Keys.ControlY, # Control-Y (25)
53 "\x1a": Keys.ControlZ, # Control-Z
54 "\x1b": Keys.Escape, # Also Control-[
55 "\x9b": Keys.ShiftEscape,
56 "\x1c": Keys.ControlBackslash, # Both Control-\ (also Ctrl-| )
57 "\x1d": Keys.ControlSquareClose, # Control-]
58 "\x1e": Keys.ControlCircumflex, # Control-^
59 "\x1f": Keys.ControlUnderscore, # Control-underscore (Also for Ctrl-hyphen.)
60 # ASCII Delete (0x7f)
61 # Vt220 (and Linux terminal) send this when pressing backspace. We map this
62 # to ControlH, because that will make it easier to create key bindings that
63 # work everywhere, with the trade-off that it's no longer possible to
64 # handle backspace and control-h individually for the few terminals that
65 # support it. (Most terminals send ControlH when backspace is pressed.)
66 # See: http://www.ibb.net/~anne/keyboard.html
67 "\x7f": Keys.ControlH,
68 # --
69 # Various
70 "\x1b[1~": Keys.Home, # tmux
71 "\x1b[2~": Keys.Insert,
72 "\x1b[3~": Keys.Delete,
73 "\x1b[4~": Keys.End, # tmux
74 "\x1b[5~": Keys.PageUp,
75 "\x1b[6~": Keys.PageDown,
76 "\x1b[7~": Keys.Home, # xrvt
77 "\x1b[8~": Keys.End, # xrvt
78 "\x1b[Z": Keys.BackTab, # shift + tab
79 "\x1b\x09": Keys.BackTab, # Linux console
80 "\x1b[~": Keys.BackTab, # Windows console
81 # --
82 # Function keys.
83 "\x1bOP": Keys.F1,
84 "\x1bOQ": Keys.F2,
85 "\x1bOR": Keys.F3,
86 "\x1bOS": Keys.F4,
87 "\x1b[[A": Keys.F1, # Linux console.
88 "\x1b[[B": Keys.F2, # Linux console.
89 "\x1b[[C": Keys.F3, # Linux console.
90 "\x1b[[D": Keys.F4, # Linux console.
91 "\x1b[[E": Keys.F5, # Linux console.
92 "\x1b[11~": Keys.F1, # rxvt-unicode
93 "\x1b[12~": Keys.F2, # rxvt-unicode
94 "\x1b[13~": Keys.F3, # rxvt-unicode
95 "\x1b[14~": Keys.F4, # rxvt-unicode
96 "\x1b[15~": Keys.F5,
97 "\x1b[17~": Keys.F6,
98 "\x1b[18~": Keys.F7,
99 "\x1b[19~": Keys.F8,
100 "\x1b[20~": Keys.F9,
101 "\x1b[21~": Keys.F10,
102 "\x1b[23~": Keys.F11,
103 "\x1b[24~": Keys.F12,
104 "\x1b[25~": Keys.F13,
105 "\x1b[26~": Keys.F14,
106 "\x1b[28~": Keys.F15,
107 "\x1b[29~": Keys.F16,
108 "\x1b[31~": Keys.F17,
109 "\x1b[32~": Keys.F18,
110 "\x1b[33~": Keys.F19,
111 "\x1b[34~": Keys.F20,
112 # Xterm
113 "\x1b[1;2P": Keys.F13,
114 "\x1b[1;2Q": Keys.F14,
115 # '\x1b[1;2R': Keys.F15, # Conflicts with CPR response.
116 "\x1b[1;2S": Keys.F16,
117 "\x1b[15;2~": Keys.F17,
118 "\x1b[17;2~": Keys.F18,
119 "\x1b[18;2~": Keys.F19,
120 "\x1b[19;2~": Keys.F20,
121 "\x1b[20;2~": Keys.F21,
122 "\x1b[21;2~": Keys.F22,
123 "\x1b[23;2~": Keys.F23,
124 "\x1b[24;2~": Keys.F24,
125 # --
126 # CSI 27 disambiguated modified "other" keys (xterm)
127 # Ref: https://invisible-island.net/xterm/modified-keys.html
128 # These are currently unsupported, so just re-map some common ones to the
129 # unmodified versions
130 "\x1b[27;2;13~": Keys.ControlM, # Shift + Enter
131 "\x1b[27;5;13~": Keys.ControlM, # Ctrl + Enter
132 "\x1b[27;6;13~": Keys.ControlM, # Ctrl + Shift + Enter
133 # --
134 # Control + function keys.
135 "\x1b[1;5P": Keys.ControlF1,
136 "\x1b[1;5Q": Keys.ControlF2,
137 # "\x1b[1;5R": Keys.ControlF3, # Conflicts with CPR response.
138 "\x1b[1;5S": Keys.ControlF4,
139 "\x1b[15;5~": Keys.ControlF5,
140 "\x1b[17;5~": Keys.ControlF6,
141 "\x1b[18;5~": Keys.ControlF7,
142 "\x1b[19;5~": Keys.ControlF8,
143 "\x1b[20;5~": Keys.ControlF9,
144 "\x1b[21;5~": Keys.ControlF10,
145 "\x1b[23;5~": Keys.ControlF11,
146 "\x1b[24;5~": Keys.ControlF12,
147 "\x1b[1;6P": Keys.ControlF13,
148 "\x1b[1;6Q": Keys.ControlF14,
149 # "\x1b[1;6R": Keys.ControlF15, # Conflicts with CPR response.
150 "\x1b[1;6S": Keys.ControlF16,
151 "\x1b[15;6~": Keys.ControlF17,
152 "\x1b[17;6~": Keys.ControlF18,
153 "\x1b[18;6~": Keys.ControlF19,
154 "\x1b[19;6~": Keys.ControlF20,
155 "\x1b[20;6~": Keys.ControlF21,
156 "\x1b[21;6~": Keys.ControlF22,
157 "\x1b[23;6~": Keys.ControlF23,
158 "\x1b[24;6~": Keys.ControlF24,
159 # --
160 # Tmux (Win32 subsystem) sends the following scroll events.
161 "\x1b[62~": Keys.ScrollUp,
162 "\x1b[63~": Keys.ScrollDown,
163 "\x1b[200~": Keys.BracketedPaste, # Start of bracketed paste.
164 # --
165 # Sequences generated by numpad 5. Not sure what it means. (It doesn't
166 # appear in 'infocmp'. Just ignore.
167 "\x1b[E": Keys.Ignore, # Xterm.
168 "\x1b[G": Keys.Ignore, # Linux console.
169 # --
170 # Meta/control/escape + pageup/pagedown/insert/delete.
171 "\x1b[3;2~": Keys.ShiftDelete, # xterm, gnome-terminal.
172 "\x1b[5;2~": Keys.ShiftPageUp,
173 "\x1b[6;2~": Keys.ShiftPageDown,
174 "\x1b[2;3~": (Keys.Escape, Keys.Insert),
175 "\x1b[3;3~": (Keys.Escape, Keys.Delete),
176 "\x1b[5;3~": (Keys.Escape, Keys.PageUp),
177 "\x1b[6;3~": (Keys.Escape, Keys.PageDown),
178 "\x1b[2;4~": (Keys.Escape, Keys.ShiftInsert),
179 "\x1b[3;4~": (Keys.Escape, Keys.ShiftDelete),
180 "\x1b[5;4~": (Keys.Escape, Keys.ShiftPageUp),
181 "\x1b[6;4~": (Keys.Escape, Keys.ShiftPageDown),
182 "\x1b[3;5~": Keys.ControlDelete, # xterm, gnome-terminal.
183 "\x1b[5;5~": Keys.ControlPageUp,
184 "\x1b[6;5~": Keys.ControlPageDown,
185 "\x1b[3;6~": Keys.ControlShiftDelete,
186 "\x1b[5;6~": Keys.ControlShiftPageUp,
187 "\x1b[6;6~": Keys.ControlShiftPageDown,
188 "\x1b[2;7~": (Keys.Escape, Keys.ControlInsert),
189 "\x1b[5;7~": (Keys.Escape, Keys.ControlPageDown),
190 "\x1b[6;7~": (Keys.Escape, Keys.ControlPageDown),
191 "\x1b[2;8~": (Keys.Escape, Keys.ControlShiftInsert),
192 "\x1b[5;8~": (Keys.Escape, Keys.ControlShiftPageDown),
193 "\x1b[6;8~": (Keys.Escape, Keys.ControlShiftPageDown),
194 # --
195 # Arrows.
196 # (Normal cursor mode).
197 "\x1b[A": Keys.Up,
198 "\x1b[B": Keys.Down,
199 "\x1b[C": Keys.Right,
200 "\x1b[D": Keys.Left,
201 "\x1b[H": Keys.Home,
202 "\x1b[F": Keys.End,
203 # Tmux sends following keystrokes when control+arrow is pressed, but for
204 # Emacs ansi-term sends the same sequences for normal arrow keys. Consider
205 # it a normal arrow press, because that's more important.
206 # (Application cursor mode).
207 "\x1bOA": Keys.Up,
208 "\x1bOB": Keys.Down,
209 "\x1bOC": Keys.Right,
210 "\x1bOD": Keys.Left,
211 "\x1bOF": Keys.End,
212 "\x1bOH": Keys.Home,
213 # Shift + arrows.
214 "\x1b[1;2A": Keys.ShiftUp,
215 "\x1b[1;2B": Keys.ShiftDown,
216 "\x1b[1;2C": Keys.ShiftRight,
217 "\x1b[1;2D": Keys.ShiftLeft,
218 "\x1b[1;2F": Keys.ShiftEnd,
219 "\x1b[1;2H": Keys.ShiftHome,
220 # Meta + arrow keys. Several terminals handle this differently.
221 # The following sequences are for xterm and gnome-terminal.
222 # (Iterm sends ESC followed by the normal arrow_up/down/left/right
223 # sequences, and the OSX Terminal sends ESCb and ESCf for "alt
224 # arrow_left" and "alt arrow_right." We don't handle these
225 # explicitly, in here, because would could not distinguish between
226 # pressing ESC (to go to Vi navigation mode), followed by just the
227 # 'b' or 'f' key. These combinations are handled in
228 # the input processor.)
229 "\x1b[1;3A": (Keys.Escape, Keys.Up),
230 "\x1b[1;3B": (Keys.Escape, Keys.Down),
231 "\x1b[1;3C": (Keys.Escape, Keys.Right),
232 "\x1b[1;3D": (Keys.Escape, Keys.Left),
233 "\x1b[1;3F": (Keys.Escape, Keys.End),
234 "\x1b[1;3H": (Keys.Escape, Keys.Home),
235 # Alt+shift+number.
236 "\x1b[1;4A": (Keys.Escape, Keys.ShiftDown),
237 "\x1b[1;4B": (Keys.Escape, Keys.ShiftUp),
238 "\x1b[1;4C": (Keys.Escape, Keys.ShiftRight),
239 "\x1b[1;4D": (Keys.Escape, Keys.ShiftLeft),
240 "\x1b[1;4F": (Keys.Escape, Keys.ShiftEnd),
241 "\x1b[1;4H": (Keys.Escape, Keys.ShiftHome),
242 # Control + arrows.
243 "\x1b[1;5A": Keys.ControlUp, # Cursor Mode
244 "\x1b[1;5B": Keys.ControlDown, # Cursor Mode
245 "\x1b[1;5C": Keys.ControlRight, # Cursor Mode
246 "\x1b[1;5D": Keys.ControlLeft, # Cursor Mode
247 "\x1b[1;5F": Keys.ControlEnd,
248 "\x1b[1;5H": Keys.ControlHome,
249 # Tmux sends following keystrokes when control+arrow is pressed, but for
250 # Emacs ansi-term sends the same sequences for normal arrow keys. Consider
251 # it a normal arrow press, because that's more important.
252 "\x1b[5A": Keys.ControlUp,
253 "\x1b[5B": Keys.ControlDown,
254 "\x1b[5C": Keys.ControlRight,
255 "\x1b[5D": Keys.ControlLeft,
256 "\x1bOc": Keys.ControlRight, # rxvt
257 "\x1bOd": Keys.ControlLeft, # rxvt
258 # Control + shift + arrows.
259 "\x1b[1;6A": Keys.ControlShiftDown,
260 "\x1b[1;6B": Keys.ControlShiftUp,
261 "\x1b[1;6C": Keys.ControlShiftRight,
262 "\x1b[1;6D": Keys.ControlShiftLeft,
263 "\x1b[1;6F": Keys.ControlShiftEnd,
264 "\x1b[1;6H": Keys.ControlShiftHome,
265 # Control + Meta + arrows.
266 "\x1b[1;7A": (Keys.Escape, Keys.ControlDown),
267 "\x1b[1;7B": (Keys.Escape, Keys.ControlUp),
268 "\x1b[1;7C": (Keys.Escape, Keys.ControlRight),
269 "\x1b[1;7D": (Keys.Escape, Keys.ControlLeft),
270 "\x1b[1;7F": (Keys.Escape, Keys.ControlEnd),
271 "\x1b[1;7H": (Keys.Escape, Keys.ControlHome),
272 # Meta + Shift + arrows.
273 "\x1b[1;8A": (Keys.Escape, Keys.ControlShiftDown),
274 "\x1b[1;8B": (Keys.Escape, Keys.ControlShiftUp),
275 "\x1b[1;8C": (Keys.Escape, Keys.ControlShiftRight),
276 "\x1b[1;8D": (Keys.Escape, Keys.ControlShiftLeft),
277 "\x1b[1;8F": (Keys.Escape, Keys.ControlShiftEnd),
278 "\x1b[1;8H": (Keys.Escape, Keys.ControlShiftHome),
279 # Meta + arrow on (some?) Macs when using iTerm defaults (see issue #483).
280 "\x1b[1;9A": (Keys.Escape, Keys.Up),
281 "\x1b[1;9B": (Keys.Escape, Keys.Down),
282 "\x1b[1;9C": (Keys.Escape, Keys.Right),
283 "\x1b[1;9D": (Keys.Escape, Keys.Left),
284 # --
285 # Control/shift/meta + number in mintty.
286 # (c-2 will actually send c-@ and c-6 will send c-^.)
287 "\x1b[1;5p": Keys.Control0,
288 "\x1b[1;5q": Keys.Control1,
289 "\x1b[1;5r": Keys.Control2,
290 "\x1b[1;5s": Keys.Control3,
291 "\x1b[1;5t": Keys.Control4,
292 "\x1b[1;5u": Keys.Control5,
293 "\x1b[1;5v": Keys.Control6,
294 "\x1b[1;5w": Keys.Control7,
295 "\x1b[1;5x": Keys.Control8,
296 "\x1b[1;5y": Keys.Control9,
297 "\x1b[1;6p": Keys.ControlShift0,
298 "\x1b[1;6q": Keys.ControlShift1,
299 "\x1b[1;6r": Keys.ControlShift2,
300 "\x1b[1;6s": Keys.ControlShift3,
301 "\x1b[1;6t": Keys.ControlShift4,
302 "\x1b[1;6u": Keys.ControlShift5,
303 "\x1b[1;6v": Keys.ControlShift6,
304 "\x1b[1;6w": Keys.ControlShift7,
305 "\x1b[1;6x": Keys.ControlShift8,
306 "\x1b[1;6y": Keys.ControlShift9,
307 "\x1b[1;7p": (Keys.Escape, Keys.Control0),
308 "\x1b[1;7q": (Keys.Escape, Keys.Control1),
309 "\x1b[1;7r": (Keys.Escape, Keys.Control2),
310 "\x1b[1;7s": (Keys.Escape, Keys.Control3),
311 "\x1b[1;7t": (Keys.Escape, Keys.Control4),
312 "\x1b[1;7u": (Keys.Escape, Keys.Control5),
313 "\x1b[1;7v": (Keys.Escape, Keys.Control6),
314 "\x1b[1;7w": (Keys.Escape, Keys.Control7),
315 "\x1b[1;7x": (Keys.Escape, Keys.Control8),
316 "\x1b[1;7y": (Keys.Escape, Keys.Control9),
317 "\x1b[1;8p": (Keys.Escape, Keys.ControlShift0),
318 "\x1b[1;8q": (Keys.Escape, Keys.ControlShift1),
319 "\x1b[1;8r": (Keys.Escape, Keys.ControlShift2),
320 "\x1b[1;8s": (Keys.Escape, Keys.ControlShift3),
321 "\x1b[1;8t": (Keys.Escape, Keys.ControlShift4),
322 "\x1b[1;8u": (Keys.Escape, Keys.ControlShift5),
323 "\x1b[1;8v": (Keys.Escape, Keys.ControlShift6),
324 "\x1b[1;8w": (Keys.Escape, Keys.ControlShift7),
325 "\x1b[1;8x": (Keys.Escape, Keys.ControlShift8),
326 "\x1b[1;8y": (Keys.Escape, Keys.ControlShift9),
327}
330def _get_reverse_ansi_sequences() -> dict[Keys, str]:
331 """
332 Create a dictionary that maps prompt_toolkit keys back to the VT100 escape
333 sequences.
334 """
335 result: dict[Keys, str] = {}
337 for sequence, key in ANSI_SEQUENCES.items():
338 if not isinstance(key, tuple):
339 if key not in result:
340 result[key] = sequence
342 return result
345REVERSE_ANSI_SEQUENCES = _get_reverse_ansi_sequences()