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