Skip to content

Commit 21c951a

Browse files
Support more ANSI escape sequences.
1 parent 68e5b8e commit 21c951a

File tree

2 files changed

+260
-78
lines changed

2 files changed

+260
-78
lines changed

prompt_toolkit/input/ansi_escape_sequences.py

Lines changed: 184 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
"""
22
Mappings from VT100 (ANSI) escape sequences to the corresponding prompt_toolkit
33
keys.
4+
5+
We are not using the terminfo/termcap databases to detect the ANSI escape
6+
sequences for the input. Instead, we recognize 99% of the most common
7+
sequences. This works well, because in practice, every modern terminal is
8+
mostly Xterm compatible.
9+
10+
Some useful docs:
11+
- Mintty: https://github.com/mintty/mintty/blob/master/wiki/Keycodes.md
412
"""
513
from typing import Dict, Tuple, Union
614

@@ -11,9 +19,9 @@
1119
"REVERSE_ANSI_SEQUENCES",
1220
]
1321

14-
1522
# Mapping of vt100 escape codes to Keys.
1623
ANSI_SEQUENCES: Dict[str, Union[Keys, Tuple[Keys, ...]]] = {
24+
# Control keys.
1725
"\x00": Keys.ControlAt, # Control-At (Also for Ctrl-Space)
1826
"\x01": Keys.ControlA, # Control-A (home)
1927
"\x02": Keys.ControlB, # Control-B (emacs cursor left)
@@ -55,25 +63,18 @@
5563
# support it. (Most terminals send ControlH when backspace is pressed.)
5664
# See: http://www.ibb.net/~anne/keyboard.html
5765
"\x7f": Keys.ControlH,
58-
"\x1b[A": Keys.Up,
59-
"\x1b[B": Keys.Down,
60-
"\x1b[C": Keys.Right,
61-
"\x1b[D": Keys.Left,
62-
"\x1b[H": Keys.Home,
63-
"\x1bOH": Keys.Home,
64-
"\x1b[F": Keys.End,
65-
"\x1bOF": Keys.End,
66-
"\x1b[3~": Keys.Delete,
67-
"\x1b[3;2~": Keys.ShiftDelete, # xterm, gnome-terminal.
68-
"\x1b[3;5~": Keys.ControlDelete, # xterm, gnome-terminal.
66+
6967
"\x1b[1~": Keys.Home, # tmux
68+
"\x1b[2~": Keys.Insert,
69+
"\x1b[3~": Keys.Delete,
7070
"\x1b[4~": Keys.End, # tmux
7171
"\x1b[5~": Keys.PageUp,
7272
"\x1b[6~": Keys.PageDown,
7373
"\x1b[7~": Keys.Home, # xrvt
7474
"\x1b[8~": Keys.End, # xrvt
7575
"\x1b[Z": Keys.BackTab, # shift + tab
76-
"\x1b[2~": Keys.Insert,
76+
77+
# Function keys.
7778
"\x1bOP": Keys.F1,
7879
"\x1bOQ": Keys.F2,
7980
"\x1bOR": Keys.F3,
@@ -116,35 +117,91 @@
116117
"\x1b[21;2~": Keys.F22,
117118
"\x1b[23;2~": Keys.F23,
118119
"\x1b[24;2~": Keys.F24,
119-
"\x1b[1;5A": Keys.ControlUp, # Cursor Mode
120-
"\x1b[1;5B": Keys.ControlDown, # Cursor Mode
121-
"\x1b[1;5C": Keys.ControlRight, # Cursor Mode
122-
"\x1b[1;5D": Keys.ControlLeft, # Cursor Mode
123-
"\x1b[1;5H": Keys.ControlHome,
124-
"\x1b[1;5F": Keys.ControlEnd,
125-
"\x1b[1;2A": Keys.ShiftUp,
126-
"\x1b[1;2B": Keys.ShiftDown,
127-
"\x1b[1;2C": Keys.ShiftRight,
128-
"\x1b[1;2D": Keys.ShiftLeft,
129-
"\x1b[1;2H": Keys.ShiftHome,
130-
"\x1b[1;2F": Keys.ShiftEnd,
120+
121+
# Control + function keys.
122+
"\x1b[1;5P": Keys.ControlF1,
123+
"\x1b[1;5Q": Keys.ControlF2,
124+
# "\x1b[1;5R": Keys.ControlF3, # Conflicts with CPR response.
125+
"\x1b[1;5S": Keys.ControlF4,
126+
"\x1b[15;5~": Keys.ControlF5,
127+
"\x1b[17;5~": Keys.ControlF6,
128+
"\x1b[18;5~": Keys.ControlF7,
129+
"\x1b[19;5~": Keys.ControlF8,
130+
"\x1b[20;5~": Keys.ControlF9,
131+
"\x1b[21;5~": Keys.ControlF10,
132+
"\x1b[23;5~": Keys.ControlF11,
133+
"\x1b[24;5~": Keys.ControlF12,
134+
"\x1b[1;6P": Keys.ControlF13,
135+
"\x1b[1;6Q": Keys.ControlF14,
136+
# "\x1b[1;6R": Keys.ControlF15, # Conflicts with CPR response.
137+
"\x1b[1;6S": Keys.ControlF16,
138+
"\x1b[15;6~": Keys.ControlF17,
139+
"\x1b[17;6~": Keys.ControlF18,
140+
"\x1b[18;6~": Keys.ControlF19,
141+
"\x1b[19;6~": Keys.ControlF20,
142+
"\x1b[20;6~": Keys.ControlF21,
143+
"\x1b[21;6~": Keys.ControlF22,
144+
"\x1b[23;6~": Keys.ControlF23,
145+
"\x1b[24;6~": Keys.ControlF24,
146+
147+
# Tmux (Win32 subsystem) sends the following scroll events.
148+
"\x1b[62~": Keys.ScrollUp,
149+
"\x1b[63~": Keys.ScrollDown,
150+
"\x1b[200~": Keys.BracketedPaste, # Start of bracketed paste.
151+
152+
# Sequences generated by numpad 5. Not sure what it means. (It doesn't
153+
# appear in 'infocmp'. Just ignore.
154+
"\x1b[E": Keys.Ignore, # Xterm.
155+
"\x1b[G": Keys.Ignore, # Linux console.
156+
157+
# Meta/control/escape + pageup/pagedown/insert/delete.
158+
"\x1b[3;2~": Keys.ShiftDelete, # xterm, gnome-terminal.
159+
"\x1b[5;2~": Keys.ShiftPageUp,
160+
"\x1b[6;2~": Keys.ShiftPageDown,
161+
"\x1b[2;3~": (Keys.Escape, Keys.Insert),
162+
"\x1b[3;3~": (Keys.Escape, Keys.Delete),
163+
"\x1b[5;3~": (Keys.Escape, Keys.PageUp),
164+
"\x1b[6;3~": (Keys.Escape, Keys.PageDown),
165+
"\x1b[2;4~": (Keys.Escape, Keys.ShiftInsert),
166+
"\x1b[3;4~": (Keys.Escape, Keys.ShiftDelete),
167+
"\x1b[5;4~": (Keys.Escape, Keys.ShiftPageUp),
168+
"\x1b[6;4~": (Keys.Escape, Keys.ShiftPageDown),
169+
"\x1b[3;5~": Keys.ControlDelete, # xterm, gnome-terminal.
170+
"\x1b[5;5~": Keys.ControlPageUp,
171+
"\x1b[6;5~": Keys.ControlPageDown,
172+
"\x1b[3;6~": Keys.ShiftControlDelete,
173+
"\x1b[5;6~": Keys.ShiftControlPageUp,
174+
"\x1b[6;6~": Keys.ShiftControlPageDown,
175+
"\x1b[2;7~": (Keys.Escape, Keys.ControlInsert),
176+
"\x1b[5;7~": (Keys.Escape, Keys.ControlPageDown),
177+
"\x1b[6;7~": (Keys.Escape, Keys.ControlPageDown),
178+
"\x1b[2;8~": (Keys.Escape, Keys.ShiftControlInsert),
179+
"\x1b[5;8~": (Keys.Escape, Keys.ShiftControlPageDown),
180+
"\x1b[6;8~": (Keys.Escape, Keys.ShiftControlPageDown),
181+
182+
# Arrows.
183+
"\x1b[A": Keys.Up,
184+
"\x1b[B": Keys.Down,
185+
"\x1b[C": Keys.Right,
186+
"\x1b[D": Keys.Left,
187+
"\x1b[H": Keys.Home,
188+
"\x1b[F": Keys.End,
131189
# Tmux sends following keystrokes when control+arrow is pressed, but for
132190
# Emacs ansi-term sends the same sequences for normal arrow keys. Consider
133191
# it a normal arrow press, because that's more important.
134192
"\x1bOA": Keys.Up,
135193
"\x1bOB": Keys.Down,
136194
"\x1bOC": Keys.Right,
137195
"\x1bOD": Keys.Left,
138-
"\x1b[5A": Keys.ControlUp,
139-
"\x1b[5B": Keys.ControlDown,
140-
"\x1b[5C": Keys.ControlRight,
141-
"\x1b[5D": Keys.ControlLeft,
142-
"\x1bOc": Keys.ControlRight, # rxvt
143-
"\x1bOd": Keys.ControlLeft, # rxvt
144-
# Tmux (Win32 subsystem) sends the following scroll events.
145-
"\x1b[62~": Keys.ScrollUp,
146-
"\x1b[63~": Keys.ScrollDown,
147-
"\x1b[200~": Keys.BracketedPaste, # Start of bracketed paste.
196+
"\x1bOF": Keys.End,
197+
"\x1bOH": Keys.Home,
198+
# Shift + arrows.
199+
"\x1b[1;2A": Keys.ShiftUp,
200+
"\x1b[1;2B": Keys.ShiftDown,
201+
"\x1b[1;2C": Keys.ShiftRight,
202+
"\x1b[1;2D": Keys.ShiftLeft,
203+
"\x1b[1;2F": Keys.ShiftEnd,
204+
"\x1b[1;2H": Keys.ShiftHome,
148205
# Meta + arrow keys. Several terminals handle this differently.
149206
# The following sequences are for xterm and gnome-terminal.
150207
# (Iterm sends ESC followed by the normal arrow_up/down/left/right
@@ -154,34 +211,104 @@
154211
# pressing ESC (to go to Vi navigation mode), followed by just the
155212
# 'b' or 'f' key. These combinations are handled in
156213
# the input processor.)
157-
"\x1b[1;3D": (Keys.Escape, Keys.Left),
158-
"\x1b[1;3C": (Keys.Escape, Keys.Right),
159214
"\x1b[1;3A": (Keys.Escape, Keys.Up),
160215
"\x1b[1;3B": (Keys.Escape, Keys.Down),
161-
# Option+arrow on (some?) Macs when using iTerm defaults
162-
# (see issue #483)
216+
"\x1b[1;3C": (Keys.Escape, Keys.Right),
217+
"\x1b[1;3D": (Keys.Escape, Keys.Left),
218+
"\x1b[1;3F": (Keys.Escape, Keys.End),
219+
"\x1b[1;3H": (Keys.Escape, Keys.Home),
220+
# Alt+shift+number.
221+
"\x1b[1;4A": (Keys.Escape, Keys.ShiftDown),
222+
"\x1b[1;4B": (Keys.Escape, Keys.ShiftUp),
223+
"\x1b[1;4C": (Keys.Escape, Keys.ShiftRight),
224+
"\x1b[1;4D": (Keys.Escape, Keys.ShiftLeft),
225+
"\x1b[1;4F": (Keys.Escape, Keys.ShiftEnd),
226+
"\x1b[1;4H": (Keys.Escape, Keys.ShiftHome),
227+
# Control + arrows.
228+
"\x1b[1;5A": Keys.ControlUp, # Cursor Mode
229+
"\x1b[1;5B": Keys.ControlDown, # Cursor Mode
230+
"\x1b[1;5C": Keys.ControlRight, # Cursor Mode
231+
"\x1b[1;5D": Keys.ControlLeft, # Cursor Mode
232+
"\x1b[1;5F": Keys.ControlEnd,
233+
"\x1b[1;5H": Keys.ControlHome,
234+
# Tmux sends following keystrokes when control+arrow is pressed, but for
235+
# Emacs ansi-term sends the same sequences for normal arrow keys. Consider
236+
# it a normal arrow press, because that's more important.
237+
"\x1b[5A": Keys.ControlUp,
238+
"\x1b[5B": Keys.ControlDown,
239+
"\x1b[5C": Keys.ControlRight,
240+
"\x1b[5D": Keys.ControlLeft,
241+
"\x1bOc": Keys.ControlRight, # rxvt
242+
"\x1bOd": Keys.ControlLeft, # rxvt
243+
# Control + shift + arrows.
244+
"\x1b[1;6A": Keys.ShiftControlDown,
245+
"\x1b[1;6B": Keys.ShiftControlUp,
246+
"\x1b[1;6C": Keys.ShiftControlRight,
247+
"\x1b[1;6D": Keys.ShiftControlLeft,
248+
"\x1b[1;6F": Keys.ShiftControlEnd,
249+
"\x1b[1;6H": Keys.ShiftControlHome,
250+
# Control + Meta + arrows.
251+
"\x1b[1;7A": (Keys.Escape, Keys.ControlDown),
252+
"\x1b[1;7B": (Keys.Escape, Keys.ControlUp),
253+
"\x1b[1;7C": (Keys.Escape, Keys.ControlRight),
254+
"\x1b[1;7D": (Keys.Escape, Keys.ControlLeft),
255+
"\x1b[1;7F": (Keys.Escape, Keys.ControlEnd),
256+
"\x1b[1;7H": (Keys.Escape, Keys.ControlHome),
257+
# Meta + Shift + arrows.
258+
"\x1b[1;8A": (Keys.Escape, Keys.ShiftControlDown),
259+
"\x1b[1;8B": (Keys.Escape, Keys.ShiftControlUp),
260+
"\x1b[1;8C": (Keys.Escape, Keys.ShiftControlRight),
261+
"\x1b[1;8D": (Keys.Escape, Keys.ShiftControlLeft),
262+
"\x1b[1;8F": (Keys.Escape, Keys.ShiftControlEnd),
263+
"\x1b[1;8H": (Keys.Escape, Keys.ShiftControlHome),
264+
# Meta + arrow on (some?) Macs when using iTerm defaults (see issue #483).
163265
"\x1b[1;9A": (Keys.Escape, Keys.Up),
164266
"\x1b[1;9B": (Keys.Escape, Keys.Down),
165267
"\x1b[1;9C": (Keys.Escape, Keys.Right),
166268
"\x1b[1;9D": (Keys.Escape, Keys.Left),
167-
# Sequences generated by numpad 5. Not sure what it means. (It doesn't
168-
# appear in 'infocmp'. Just ignore.
169-
"\x1b[E": Keys.Ignore, # Xterm.
170-
"\x1b[G": Keys.Ignore, # Linux console.
171-
# Alt + home/end/page-up/page-down/insert.
172-
"\x1b[1;3H": (Keys.Escape, Keys.Home),
173-
"\x1b[1;3F": (Keys.Escape, Keys.End),
174-
"\x1b[5;3~": (Keys.Escape, Keys.PageUp),
175-
"\x1b[6;3~": (Keys.Escape, Keys.PageDown),
176-
"\x1b[2;3~": (Keys.Escape, Keys.Insert),
177-
"\x1b[3;3~": (Keys.Escape, Keys.Delete),
178-
# Control+Shift in mintty/wsltty
179-
"\x1b[1;6D": Keys.ShiftControlLeft,
180-
"\x1b[1;6C": Keys.ShiftControlRight,
181-
"\x1b[1;6B": Keys.ShiftControlUp,
182-
"\x1b[1;6A": Keys.ShiftControlDown,
183-
"\x1b[1;6H": Keys.ShiftControlHome,
184-
"\x1b[1;6F": Keys.ShiftControlEnd,
269+
270+
# Control/shift/meta + number in mintty.
271+
# (c-2 will actually send c-@ and c-6 will send c-^.)
272+
"\x1b[1;5p": Keys.Control0,
273+
"\x1b[1;5q": Keys.Control1,
274+
"\x1b[1;5r": Keys.Control2,
275+
"\x1b[1;5s": Keys.Control3,
276+
"\x1b[1;5t": Keys.Control4,
277+
"\x1b[1;5u": Keys.Control5,
278+
"\x1b[1;5v": Keys.Control6,
279+
"\x1b[1;5w": Keys.Control7,
280+
"\x1b[1;5x": Keys.Control8,
281+
"\x1b[1;5y": Keys.Control9,
282+
"\x1b[1;6p": Keys.ShiftControl0,
283+
"\x1b[1;6q": Keys.ShiftControl1,
284+
"\x1b[1;6r": Keys.ShiftControl2,
285+
"\x1b[1;6s": Keys.ShiftControl3,
286+
"\x1b[1;6t": Keys.ShiftControl4,
287+
"\x1b[1;6u": Keys.ShiftControl5,
288+
"\x1b[1;6v": Keys.ShiftControl6,
289+
"\x1b[1;6w": Keys.ShiftControl7,
290+
"\x1b[1;6x": Keys.ShiftControl8,
291+
"\x1b[1;6y": Keys.ShiftControl9,
292+
"\x1b[1;7p": (Keys.Escape, Keys.Control0),
293+
"\x1b[1;7q": (Keys.Escape, Keys.Control1),
294+
"\x1b[1;7r": (Keys.Escape, Keys.Control2),
295+
"\x1b[1;7s": (Keys.Escape, Keys.Control3),
296+
"\x1b[1;7t": (Keys.Escape, Keys.Control4),
297+
"\x1b[1;7u": (Keys.Escape, Keys.Control5),
298+
"\x1b[1;7v": (Keys.Escape, Keys.Control6),
299+
"\x1b[1;7w": (Keys.Escape, Keys.Control7),
300+
"\x1b[1;7x": (Keys.Escape, Keys.Control8),
301+
"\x1b[1;7y": (Keys.Escape, Keys.Control9),
302+
"\x1b[1;8p": (Keys.Escape, Keys.ShiftControl0),
303+
"\x1b[1;8q": (Keys.Escape, Keys.ShiftControl1),
304+
"\x1b[1;8r": (Keys.Escape, Keys.ShiftControl2),
305+
"\x1b[1;8s": (Keys.Escape, Keys.ShiftControl3),
306+
"\x1b[1;8t": (Keys.Escape, Keys.ShiftControl4),
307+
"\x1b[1;8u": (Keys.Escape, Keys.ShiftControl5),
308+
"\x1b[1;8v": (Keys.Escape, Keys.ShiftControl6),
309+
"\x1b[1;8w": (Keys.Escape, Keys.ShiftControl7),
310+
"\x1b[1;8x": (Keys.Escape, Keys.ShiftControl8),
311+
"\x1b[1;8y": (Keys.Escape, Keys.ShiftControl9),
185312
}
186313

187314

0 commit comments

Comments
 (0)