1"""
2Mappings from VT100 (ANSI) escape sequences to the corresponding prompt_toolkit
3keys.
4"""
5from __future__ import unicode_literals
6
7from ..keys import Keys
8
9__all__ = [
10    'ANSI_SEQUENCES',
11    'REVERSE_ANSI_SEQUENCES',
12]
13
14
15# Mapping of vt100 escape codes to Keys.
16ANSI_SEQUENCES = {
17    '\x00': Keys.ControlAt,  # Control-At (Also for Ctrl-Space)
18    '\x01': Keys.ControlA,  # Control-A (home)
19    '\x02': Keys.ControlB,  # Control-B (emacs cursor left)
20    '\x03': Keys.ControlC,  # Control-C (interrupt)
21    '\x04': Keys.ControlD,  # Control-D (exit)
22    '\x05': Keys.ControlE,  # Control-E (end)
23    '\x06': Keys.ControlF,  # Control-F (cursor forward)
24    '\x07': Keys.ControlG,  # Control-G
25    '\x08': Keys.ControlH,  # Control-H (8) (Identical to '\b')
26    '\x09': Keys.ControlI,  # Control-I (9) (Identical to '\t')
27    '\x0a': Keys.ControlJ,  # Control-J (10) (Identical to '\n')
28    '\x0b': Keys.ControlK,  # Control-K (delete until end of line; vertical tab)
29    '\x0c': Keys.ControlL,  # Control-L (clear; form feed)
30    '\x0d': Keys.ControlM,  # Control-M (13) (Identical to '\r')
31    '\x0e': Keys.ControlN,  # Control-N (14) (history forward)
32    '\x0f': Keys.ControlO,  # Control-O (15)
33    '\x10': Keys.ControlP,  # Control-P (16) (history back)
34    '\x11': Keys.ControlQ,  # Control-Q
35    '\x12': Keys.ControlR,  # Control-R (18) (reverse search)
36    '\x13': Keys.ControlS,  # Control-S (19) (forward search)
37    '\x14': Keys.ControlT,  # Control-T
38    '\x15': Keys.ControlU,  # Control-U
39    '\x16': Keys.ControlV,  # Control-V
40    '\x17': Keys.ControlW,  # Control-W
41    '\x18': Keys.ControlX,  # Control-X
42    '\x19': Keys.ControlY,  # Control-Y (25)
43    '\x1a': Keys.ControlZ,  # Control-Z
44
45    '\x1b': Keys.Escape,            # Also Control-[
46    '\x1c': Keys.ControlBackslash,  # Both Control-\ (also Ctrl-| )
47    '\x1d': Keys.ControlSquareClose,  # Control-]
48    '\x1e': Keys.ControlCircumflex,  # Control-^
49    '\x1f': Keys.ControlUnderscore,  # Control-underscore (Also for Ctrl-hyphen.)
50
51    # ASCII Delete (0x7f)
52    # Vt220 (and Linux terminal) send this when pressing backspace. We map this
53    # to ControlH, because that will make it easier to create key bindings that
54    # work everywhere, with the trade-off that it's no longer possible to
55    # handle backspace and control-h individually for the few terminals that
56    # support it. (Most terminals send ControlH when backspace is pressed.)
57    # See: http://www.ibb.net/~anne/keyboard.html
58    '\x7f': Keys.ControlH,
59
60    '\x1b[A': Keys.Up,
61    '\x1b[B': Keys.Down,
62    '\x1b[C': Keys.Right,
63    '\x1b[D': Keys.Left,
64    '\x1b[H': Keys.Home,
65    '\x1bOH': Keys.Home,
66    '\x1b[F': Keys.End,
67    '\x1bOF': Keys.End,
68    '\x1b[3~': Keys.Delete,
69    '\x1b[3;2~': Keys.ShiftDelete,  # xterm, gnome-terminal.
70    '\x1b[3;5~': Keys.ControlDelete,  # xterm, gnome-terminal.
71    '\x1b[1~': Keys.Home,  # tmux
72    '\x1b[4~': Keys.End,  # tmux
73    '\x1b[5~': Keys.PageUp,
74    '\x1b[6~': Keys.PageDown,
75    '\x1b[7~': Keys.Home,  # xrvt
76    '\x1b[8~': Keys.End,  # xrvt
77    '\x1b[Z': Keys.BackTab,  # shift + tab
78    '\x1b[2~': Keys.Insert,
79
80    '\x1bOP': Keys.F1,
81    '\x1bOQ': Keys.F2,
82    '\x1bOR': Keys.F3,
83    '\x1bOS': Keys.F4,
84    '\x1b[[A': Keys.F1,  # Linux console.
85    '\x1b[[B': Keys.F2,  # Linux console.
86    '\x1b[[C': Keys.F3,  # Linux console.
87    '\x1b[[D': Keys.F4,  # Linux console.
88    '\x1b[[E': Keys.F5,  # Linux console.
89    '\x1b[11~': Keys.F1,  # rxvt-unicode
90    '\x1b[12~': Keys.F2,  # rxvt-unicode
91    '\x1b[13~': Keys.F3,  # rxvt-unicode
92    '\x1b[14~': Keys.F4,  # rxvt-unicode
93    '\x1b[15~': Keys.F5,
94    '\x1b[17~': Keys.F6,
95    '\x1b[18~': Keys.F7,
96    '\x1b[19~': Keys.F8,
97    '\x1b[20~': Keys.F9,
98    '\x1b[21~': Keys.F10,
99    '\x1b[23~': Keys.F11,
100    '\x1b[24~': Keys.F12,
101    '\x1b[25~': Keys.F13,
102    '\x1b[26~': Keys.F14,
103    '\x1b[28~': Keys.F15,
104    '\x1b[29~': Keys.F16,
105    '\x1b[31~': Keys.F17,
106    '\x1b[32~': Keys.F18,
107    '\x1b[33~': Keys.F19,
108    '\x1b[34~': Keys.F20,
109
110    # Xterm
111    '\x1b[1;2P': Keys.F13,
112    '\x1b[1;2Q': Keys.F14,
113    # '\x1b[1;2R': Keys.F15,  # Conflicts with CPR response.
114    '\x1b[1;2S': Keys.F16,
115    '\x1b[15;2~': Keys.F17,
116    '\x1b[17;2~': Keys.F18,
117    '\x1b[18;2~': Keys.F19,
118    '\x1b[19;2~': Keys.F20,
119    '\x1b[20;2~': Keys.F21,
120    '\x1b[21;2~': Keys.F22,
121    '\x1b[23;2~': Keys.F23,
122    '\x1b[24;2~': Keys.F24,
123
124    '\x1b[1;5A': Keys.ControlUp,     # Cursor Mode
125    '\x1b[1;5B': Keys.ControlDown,   # Cursor Mode
126    '\x1b[1;5C': Keys.ControlRight,  # Cursor Mode
127    '\x1b[1;5D': Keys.ControlLeft,   # Cursor Mode
128
129    '\x1b[1;2A': Keys.ShiftUp,
130    '\x1b[1;2B': Keys.ShiftDown,
131    '\x1b[1;2C': Keys.ShiftRight,
132    '\x1b[1;2D': Keys.ShiftLeft,
133
134    # Tmux sends following keystrokes when control+arrow is pressed, but for
135    # Emacs ansi-term sends the same sequences for normal arrow keys. Consider
136    # it a normal arrow press, because that's more important.
137    '\x1bOA': Keys.Up,
138    '\x1bOB': Keys.Down,
139    '\x1bOC': Keys.Right,
140    '\x1bOD': Keys.Left,
141
142    '\x1b[5A': Keys.ControlUp,
143    '\x1b[5B': Keys.ControlDown,
144    '\x1b[5C': Keys.ControlRight,
145    '\x1b[5D': Keys.ControlLeft,
146
147    '\x1bOc': Keys.ControlRight,  # rxvt
148    '\x1bOd': Keys.ControlLeft,  # rxvt
149
150    # Tmux (Win32 subsystem) sends the following scroll events.
151    '\x1b[62~': Keys.ScrollUp,
152    '\x1b[63~': Keys.ScrollDown,
153
154    '\x1b[200~': Keys.BracketedPaste,  # Start of bracketed paste.
155
156    # Meta + arrow keys. Several terminals handle this differently.
157    # The following sequences are for xterm and gnome-terminal.
158    #     (Iterm sends ESC followed by the normal arrow_up/down/left/right
159    #     sequences, and the OSX Terminal sends ESCb and ESCf for "alt
160    #     arrow_left" and "alt arrow_right." We don't handle these
161    #     explicitly, in here, because would could not distinguish between
162    #     pressing ESC (to go to Vi navigation mode), followed by just the
163    #     'b' or 'f' key. These combinations are handled in
164    #     the input processor.)
165    '\x1b[1;3D': (Keys.Escape, Keys.Left),
166    '\x1b[1;3C': (Keys.Escape, Keys.Right),
167    '\x1b[1;3A': (Keys.Escape, Keys.Up),
168    '\x1b[1;3B': (Keys.Escape, Keys.Down),
169
170    # Option+arrow on (some?) Macs when using iTerm defaults
171    # (see issue #483)
172    '\x1b[1;9A': (Keys.Escape, Keys.Up),
173    '\x1b[1;9B': (Keys.Escape, Keys.Down),
174    '\x1b[1;9C': (Keys.Escape, Keys.Right),
175    '\x1b[1;9D': (Keys.Escape, Keys.Left),
176
177    # Sequences generated by numpad 5. Not sure what it means. (It doesn't
178    # appear in 'infocmp'. Just ignore.
179    '\x1b[E': Keys.Ignore,  # Xterm.
180    '\x1b[G': Keys.Ignore,  # Linux console.
181}
182
183
184def _get_reverse_ansi_sequences():
185    """
186    Create a dictionary that maps prompt_toolkit keys back to the VT100 escape
187    sequences.
188    """
189    result = {}
190
191    for sequence, key in ANSI_SEQUENCES.items():
192        if not isinstance(key, tuple):
193            if key not in result:
194                result[key] = sequence
195
196    return result
197
198
199REVERSE_ANSI_SEQUENCES = _get_reverse_ansi_sequences()
200