Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/prompt_toolkit/input/ansi_escape_sequences.py: 100%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

13 statements  

1""" 

2Mappings from VT100 (ANSI) escape sequences to the corresponding prompt_toolkit 

3keys. 

4 

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. 

9 

10Some useful docs: 

11- Mintty: https://github.com/mintty/mintty/blob/master/wiki/Keycodes.md 

12""" 

13 

14from __future__ import annotations 

15 

16from ..keys import Keys 

17 

18__all__ = [ 

19 "ANSI_SEQUENCES", 

20 "REVERSE_ANSI_SEQUENCES", 

21] 

22 

23# Mapping of vt100 escape codes to Keys. 

24ANSI_SEQUENCES: dict[str, Keys | tuple[Keys, ...]] = { 

25 # Control keys. 

26 "\x00": Keys.ControlAt, # Control-At (Also for Ctrl-Space) 

27 "\x01": Keys.ControlA, # Control-A (home) 

28 "\x02": Keys.ControlB, # Control-B (emacs cursor left) 

29 "\x03": Keys.ControlC, # Control-C (interrupt) 

30 "\x04": Keys.ControlD, # Control-D (exit) 

31 "\x05": Keys.ControlE, # Control-E (end) 

32 "\x06": Keys.ControlF, # Control-F (cursor forward) 

33 "\x07": Keys.ControlG, # Control-G 

34 "\x08": Keys.ControlH, # Control-H (8) (Identical to '\b') 

35 "\x09": Keys.ControlI, # Control-I (9) (Identical to '\t') 

36 "\x0a": Keys.ControlJ, # Control-J (10) (Identical to '\n') 

37 "\x0b": Keys.ControlK, # Control-K (delete until end of line; vertical tab) 

38 "\x0c": Keys.ControlL, # Control-L (clear; form feed) 

39 "\x0d": Keys.ControlM, # Control-M (13) (Identical to '\r') 

40 "\x0e": Keys.ControlN, # Control-N (14) (history forward) 

41 "\x0f": Keys.ControlO, # Control-O (15) 

42 "\x10": Keys.ControlP, # Control-P (16) (history back) 

43 "\x11": Keys.ControlQ, # Control-Q 

44 "\x12": Keys.ControlR, # Control-R (18) (reverse search) 

45 "\x13": Keys.ControlS, # Control-S (19) (forward search) 

46 "\x14": Keys.ControlT, # Control-T 

47 "\x15": Keys.ControlU, # Control-U 

48 "\x16": Keys.ControlV, # Control-V 

49 "\x17": Keys.ControlW, # Control-W 

50 "\x18": Keys.ControlX, # Control-X 

51 "\x19": Keys.ControlY, # Control-Y (25) 

52 "\x1a": Keys.ControlZ, # Control-Z 

53 "\x1b": Keys.Escape, # Also Control-[ 

54 "\x9b": Keys.ShiftEscape, 

55 "\x1c": Keys.ControlBackslash, # Both Control-\ (also Ctrl-| ) 

56 "\x1d": Keys.ControlSquareClose, # Control-] 

57 "\x1e": Keys.ControlCircumflex, # Control-^ 

58 "\x1f": Keys.ControlUnderscore, # Control-underscore (Also for Ctrl-hyphen.) 

59 # ASCII Delete (0x7f) 

60 # Vt220 (and Linux terminal) send this when pressing backspace. We map this 

61 # to ControlH, because that will make it easier to create key bindings that 

62 # work everywhere, with the trade-off that it's no longer possible to 

63 # handle backspace and control-h individually for the few terminals that 

64 # support it. (Most terminals send ControlH when backspace is pressed.) 

65 # See: http://www.ibb.net/~anne/keyboard.html 

66 "\x7f": Keys.ControlH, 

67 # -- 

68 # Various 

69 "\x1b[1~": Keys.Home, # tmux 

70 "\x1b[2~": Keys.Insert, 

71 "\x1b[3~": Keys.Delete, 

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\x09": Keys.BackTab, # Linux console 

79 "\x1b[~": Keys.BackTab, # Windows console 

80 # -- 

81 # Function keys. 

82 "\x1bOP": Keys.F1, 

83 "\x1bOQ": Keys.F2, 

84 "\x1bOR": Keys.F3, 

85 "\x1bOS": Keys.F4, 

86 "\x1b[[A": Keys.F1, # Linux console. 

87 "\x1b[[B": Keys.F2, # Linux console. 

88 "\x1b[[C": Keys.F3, # Linux console. 

89 "\x1b[[D": Keys.F4, # Linux console. 

90 "\x1b[[E": Keys.F5, # Linux console. 

91 "\x1b[11~": Keys.F1, # rxvt-unicode 

92 "\x1b[12~": Keys.F2, # rxvt-unicode 

93 "\x1b[13~": Keys.F3, # rxvt-unicode 

94 "\x1b[14~": Keys.F4, # rxvt-unicode 

95 "\x1b[15~": Keys.F5, 

96 "\x1b[17~": Keys.F6, 

97 "\x1b[18~": Keys.F7, 

98 "\x1b[19~": Keys.F8, 

99 "\x1b[20~": Keys.F9, 

100 "\x1b[21~": Keys.F10, 

101 "\x1b[23~": Keys.F11, 

102 "\x1b[24~": Keys.F12, 

103 "\x1b[25~": Keys.F13, 

104 "\x1b[26~": Keys.F14, 

105 "\x1b[28~": Keys.F15, 

106 "\x1b[29~": Keys.F16, 

107 "\x1b[31~": Keys.F17, 

108 "\x1b[32~": Keys.F18, 

109 "\x1b[33~": Keys.F19, 

110 "\x1b[34~": Keys.F20, 

111 # Xterm 

112 "\x1b[1;2P": Keys.F13, 

113 "\x1b[1;2Q": Keys.F14, 

114 # '\x1b[1;2R': Keys.F15, # Conflicts with CPR response. 

115 "\x1b[1;2S": Keys.F16, 

116 "\x1b[15;2~": Keys.F17, 

117 "\x1b[17;2~": Keys.F18, 

118 "\x1b[18;2~": Keys.F19, 

119 "\x1b[19;2~": Keys.F20, 

120 "\x1b[20;2~": Keys.F21, 

121 "\x1b[21;2~": Keys.F22, 

122 "\x1b[23;2~": Keys.F23, 

123 "\x1b[24;2~": Keys.F24, 

124 # -- 

125 # CSI 27 disambiguated modified "other" keys (xterm) 

126 # Ref: https://invisible-island.net/xterm/modified-keys.html 

127 # These are currently unsupported, so just re-map some common ones to the 

128 # unmodified versions 

129 "\x1b[27;2;13~": Keys.ControlM, # Shift + Enter 

130 "\x1b[27;5;13~": Keys.ControlM, # Ctrl + Enter 

131 "\x1b[27;6;13~": Keys.ControlM, # Ctrl + Shift + Enter 

132 # -- 

133 # Control + function keys. 

134 "\x1b[1;5P": Keys.ControlF1, 

135 "\x1b[1;5Q": Keys.ControlF2, 

136 # "\x1b[1;5R": Keys.ControlF3, # Conflicts with CPR response. 

137 "\x1b[1;5S": Keys.ControlF4, 

138 "\x1b[15;5~": Keys.ControlF5, 

139 "\x1b[17;5~": Keys.ControlF6, 

140 "\x1b[18;5~": Keys.ControlF7, 

141 "\x1b[19;5~": Keys.ControlF8, 

142 "\x1b[20;5~": Keys.ControlF9, 

143 "\x1b[21;5~": Keys.ControlF10, 

144 "\x1b[23;5~": Keys.ControlF11, 

145 "\x1b[24;5~": Keys.ControlF12, 

146 "\x1b[1;6P": Keys.ControlF13, 

147 "\x1b[1;6Q": Keys.ControlF14, 

148 # "\x1b[1;6R": Keys.ControlF15, # Conflicts with CPR response. 

149 "\x1b[1;6S": Keys.ControlF16, 

150 "\x1b[15;6~": Keys.ControlF17, 

151 "\x1b[17;6~": Keys.ControlF18, 

152 "\x1b[18;6~": Keys.ControlF19, 

153 "\x1b[19;6~": Keys.ControlF20, 

154 "\x1b[20;6~": Keys.ControlF21, 

155 "\x1b[21;6~": Keys.ControlF22, 

156 "\x1b[23;6~": Keys.ControlF23, 

157 "\x1b[24;6~": Keys.ControlF24, 

158 # -- 

159 # Tmux (Win32 subsystem) sends the following scroll events. 

160 "\x1b[62~": Keys.ScrollUp, 

161 "\x1b[63~": Keys.ScrollDown, 

162 "\x1b[200~": Keys.BracketedPaste, # Start of bracketed paste. 

163 # -- 

164 # Sequences generated by numpad 5. Not sure what it means. (It doesn't 

165 # appear in 'infocmp'. Just ignore. 

166 "\x1b[E": Keys.Ignore, # Xterm. 

167 "\x1b[G": Keys.Ignore, # Linux console. 

168 # -- 

169 # Meta/control/escape + pageup/pagedown/insert/delete. 

170 "\x1b[3;2~": Keys.ShiftDelete, # xterm, gnome-terminal. 

171 "\x1b[5;2~": Keys.ShiftPageUp, 

172 "\x1b[6;2~": Keys.ShiftPageDown, 

173 "\x1b[2;3~": (Keys.Escape, Keys.Insert), 

174 "\x1b[3;3~": (Keys.Escape, Keys.Delete), 

175 "\x1b[5;3~": (Keys.Escape, Keys.PageUp), 

176 "\x1b[6;3~": (Keys.Escape, Keys.PageDown), 

177 "\x1b[2;4~": (Keys.Escape, Keys.ShiftInsert), 

178 "\x1b[3;4~": (Keys.Escape, Keys.ShiftDelete), 

179 "\x1b[5;4~": (Keys.Escape, Keys.ShiftPageUp), 

180 "\x1b[6;4~": (Keys.Escape, Keys.ShiftPageDown), 

181 "\x1b[3;5~": Keys.ControlDelete, # xterm, gnome-terminal. 

182 "\x1b[5;5~": Keys.ControlPageUp, 

183 "\x1b[6;5~": Keys.ControlPageDown, 

184 "\x1b[3;6~": Keys.ControlShiftDelete, 

185 "\x1b[5;6~": Keys.ControlShiftPageUp, 

186 "\x1b[6;6~": Keys.ControlShiftPageDown, 

187 "\x1b[2;7~": (Keys.Escape, Keys.ControlInsert), 

188 "\x1b[5;7~": (Keys.Escape, Keys.ControlPageDown), 

189 "\x1b[6;7~": (Keys.Escape, Keys.ControlPageDown), 

190 "\x1b[2;8~": (Keys.Escape, Keys.ControlShiftInsert), 

191 "\x1b[5;8~": (Keys.Escape, Keys.ControlShiftPageDown), 

192 "\x1b[6;8~": (Keys.Escape, Keys.ControlShiftPageDown), 

193 # -- 

194 # Arrows. 

195 # (Normal cursor mode). 

196 "\x1b[A": Keys.Up, 

197 "\x1b[B": Keys.Down, 

198 "\x1b[C": Keys.Right, 

199 "\x1b[D": Keys.Left, 

200 "\x1b[H": Keys.Home, 

201 "\x1b[F": Keys.End, 

202 # Tmux sends following keystrokes when control+arrow is pressed, but for 

203 # Emacs ansi-term sends the same sequences for normal arrow keys. Consider 

204 # it a normal arrow press, because that's more important. 

205 # (Application cursor mode). 

206 "\x1bOA": Keys.Up, 

207 "\x1bOB": Keys.Down, 

208 "\x1bOC": Keys.Right, 

209 "\x1bOD": Keys.Left, 

210 "\x1bOF": Keys.End, 

211 "\x1bOH": Keys.Home, 

212 # Shift + arrows. 

213 "\x1b[1;2A": Keys.ShiftUp, 

214 "\x1b[1;2B": Keys.ShiftDown, 

215 "\x1b[1;2C": Keys.ShiftRight, 

216 "\x1b[1;2D": Keys.ShiftLeft, 

217 "\x1b[1;2F": Keys.ShiftEnd, 

218 "\x1b[1;2H": Keys.ShiftHome, 

219 # Meta + arrow keys. Several terminals handle this differently. 

220 # The following sequences are for xterm and gnome-terminal. 

221 # (Iterm sends ESC followed by the normal arrow_up/down/left/right 

222 # sequences, and the OSX Terminal sends ESCb and ESCf for "alt 

223 # arrow_left" and "alt arrow_right." We don't handle these 

224 # explicitly, in here, because would could not distinguish between 

225 # pressing ESC (to go to Vi navigation mode), followed by just the 

226 # 'b' or 'f' key. These combinations are handled in 

227 # the input processor.) 

228 "\x1b[1;3A": (Keys.Escape, Keys.Up), 

229 "\x1b[1;3B": (Keys.Escape, Keys.Down), 

230 "\x1b[1;3C": (Keys.Escape, Keys.Right), 

231 "\x1b[1;3D": (Keys.Escape, Keys.Left), 

232 "\x1b[1;3F": (Keys.Escape, Keys.End), 

233 "\x1b[1;3H": (Keys.Escape, Keys.Home), 

234 # Alt+shift+number. 

235 "\x1b[1;4A": (Keys.Escape, Keys.ShiftDown), 

236 "\x1b[1;4B": (Keys.Escape, Keys.ShiftUp), 

237 "\x1b[1;4C": (Keys.Escape, Keys.ShiftRight), 

238 "\x1b[1;4D": (Keys.Escape, Keys.ShiftLeft), 

239 "\x1b[1;4F": (Keys.Escape, Keys.ShiftEnd), 

240 "\x1b[1;4H": (Keys.Escape, Keys.ShiftHome), 

241 # Control + arrows. 

242 "\x1b[1;5A": Keys.ControlUp, # Cursor Mode 

243 "\x1b[1;5B": Keys.ControlDown, # Cursor Mode 

244 "\x1b[1;5C": Keys.ControlRight, # Cursor Mode 

245 "\x1b[1;5D": Keys.ControlLeft, # Cursor Mode 

246 "\x1b[1;5F": Keys.ControlEnd, 

247 "\x1b[1;5H": Keys.ControlHome, 

248 # Tmux sends following keystrokes when control+arrow is pressed, but for 

249 # Emacs ansi-term sends the same sequences for normal arrow keys. Consider 

250 # it a normal arrow press, because that's more important. 

251 "\x1b[5A": Keys.ControlUp, 

252 "\x1b[5B": Keys.ControlDown, 

253 "\x1b[5C": Keys.ControlRight, 

254 "\x1b[5D": Keys.ControlLeft, 

255 "\x1bOc": Keys.ControlRight, # rxvt 

256 "\x1bOd": Keys.ControlLeft, # rxvt 

257 # Control + shift + arrows. 

258 "\x1b[1;6A": Keys.ControlShiftDown, 

259 "\x1b[1;6B": Keys.ControlShiftUp, 

260 "\x1b[1;6C": Keys.ControlShiftRight, 

261 "\x1b[1;6D": Keys.ControlShiftLeft, 

262 "\x1b[1;6F": Keys.ControlShiftEnd, 

263 "\x1b[1;6H": Keys.ControlShiftHome, 

264 # Control + Meta + arrows. 

265 "\x1b[1;7A": (Keys.Escape, Keys.ControlDown), 

266 "\x1b[1;7B": (Keys.Escape, Keys.ControlUp), 

267 "\x1b[1;7C": (Keys.Escape, Keys.ControlRight), 

268 "\x1b[1;7D": (Keys.Escape, Keys.ControlLeft), 

269 "\x1b[1;7F": (Keys.Escape, Keys.ControlEnd), 

270 "\x1b[1;7H": (Keys.Escape, Keys.ControlHome), 

271 # Meta + Shift + arrows. 

272 "\x1b[1;8A": (Keys.Escape, Keys.ControlShiftDown), 

273 "\x1b[1;8B": (Keys.Escape, Keys.ControlShiftUp), 

274 "\x1b[1;8C": (Keys.Escape, Keys.ControlShiftRight), 

275 "\x1b[1;8D": (Keys.Escape, Keys.ControlShiftLeft), 

276 "\x1b[1;8F": (Keys.Escape, Keys.ControlShiftEnd), 

277 "\x1b[1;8H": (Keys.Escape, Keys.ControlShiftHome), 

278 # Meta + arrow on (some?) Macs when using iTerm defaults (see issue #483). 

279 "\x1b[1;9A": (Keys.Escape, Keys.Up), 

280 "\x1b[1;9B": (Keys.Escape, Keys.Down), 

281 "\x1b[1;9C": (Keys.Escape, Keys.Right), 

282 "\x1b[1;9D": (Keys.Escape, Keys.Left), 

283 # -- 

284 # Control/shift/meta + number in mintty. 

285 # (c-2 will actually send c-@ and c-6 will send c-^.) 

286 "\x1b[1;5p": Keys.Control0, 

287 "\x1b[1;5q": Keys.Control1, 

288 "\x1b[1;5r": Keys.Control2, 

289 "\x1b[1;5s": Keys.Control3, 

290 "\x1b[1;5t": Keys.Control4, 

291 "\x1b[1;5u": Keys.Control5, 

292 "\x1b[1;5v": Keys.Control6, 

293 "\x1b[1;5w": Keys.Control7, 

294 "\x1b[1;5x": Keys.Control8, 

295 "\x1b[1;5y": Keys.Control9, 

296 "\x1b[1;6p": Keys.ControlShift0, 

297 "\x1b[1;6q": Keys.ControlShift1, 

298 "\x1b[1;6r": Keys.ControlShift2, 

299 "\x1b[1;6s": Keys.ControlShift3, 

300 "\x1b[1;6t": Keys.ControlShift4, 

301 "\x1b[1;6u": Keys.ControlShift5, 

302 "\x1b[1;6v": Keys.ControlShift6, 

303 "\x1b[1;6w": Keys.ControlShift7, 

304 "\x1b[1;6x": Keys.ControlShift8, 

305 "\x1b[1;6y": Keys.ControlShift9, 

306 "\x1b[1;7p": (Keys.Escape, Keys.Control0), 

307 "\x1b[1;7q": (Keys.Escape, Keys.Control1), 

308 "\x1b[1;7r": (Keys.Escape, Keys.Control2), 

309 "\x1b[1;7s": (Keys.Escape, Keys.Control3), 

310 "\x1b[1;7t": (Keys.Escape, Keys.Control4), 

311 "\x1b[1;7u": (Keys.Escape, Keys.Control5), 

312 "\x1b[1;7v": (Keys.Escape, Keys.Control6), 

313 "\x1b[1;7w": (Keys.Escape, Keys.Control7), 

314 "\x1b[1;7x": (Keys.Escape, Keys.Control8), 

315 "\x1b[1;7y": (Keys.Escape, Keys.Control9), 

316 "\x1b[1;8p": (Keys.Escape, Keys.ControlShift0), 

317 "\x1b[1;8q": (Keys.Escape, Keys.ControlShift1), 

318 "\x1b[1;8r": (Keys.Escape, Keys.ControlShift2), 

319 "\x1b[1;8s": (Keys.Escape, Keys.ControlShift3), 

320 "\x1b[1;8t": (Keys.Escape, Keys.ControlShift4), 

321 "\x1b[1;8u": (Keys.Escape, Keys.ControlShift5), 

322 "\x1b[1;8v": (Keys.Escape, Keys.ControlShift6), 

323 "\x1b[1;8w": (Keys.Escape, Keys.ControlShift7), 

324 "\x1b[1;8x": (Keys.Escape, Keys.ControlShift8), 

325 "\x1b[1;8y": (Keys.Escape, Keys.ControlShift9), 

326} 

327 

328 

329def _get_reverse_ansi_sequences() -> dict[Keys, str]: 

330 """ 

331 Create a dictionary that maps prompt_toolkit keys back to the VT100 escape 

332 sequences. 

333 """ 

334 result: dict[Keys, str] = {} 

335 

336 for sequence, key in ANSI_SEQUENCES.items(): 

337 if not isinstance(key, tuple): 

338 if key not in result: 

339 result[key] = sequence 

340 

341 return result 

342 

343 

344REVERSE_ANSI_SEQUENCES = _get_reverse_ansi_sequences()