Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/mouse.py: 35%

96 statements  

« prev     ^ index     » next       coverage.py v7.2.2, created at 2023-03-26 06:07 +0000

1from __future__ import annotations 

2 

3import sys 

4from typing import TYPE_CHECKING, FrozenSet 

5 

6from prompt_toolkit.data_structures import Point 

7from prompt_toolkit.key_binding.key_processor import KeyPress, KeyPressEvent 

8from prompt_toolkit.keys import Keys 

9from prompt_toolkit.mouse_events import ( 

10 MouseButton, 

11 MouseEvent, 

12 MouseEventType, 

13 MouseModifier, 

14) 

15 

16from ..key_bindings import KeyBindings 

17 

18if TYPE_CHECKING: 

19 from prompt_toolkit.key_binding.key_bindings import NotImplementedOrNone 

20 

21__all__ = [ 

22 "load_mouse_bindings", 

23] 

24 

25E = KeyPressEvent 

26 

27# fmt: off 

28# flake8: noqa E201 

29SCROLL_UP = MouseEventType.SCROLL_UP 

30SCROLL_DOWN = MouseEventType.SCROLL_DOWN 

31MOUSE_DOWN = MouseEventType.MOUSE_DOWN 

32MOUSE_MOVE = MouseEventType.MOUSE_MOVE 

33MOUSE_UP = MouseEventType.MOUSE_UP 

34 

35NO_MODIFIER : frozenset[MouseModifier] = frozenset() 

36SHIFT : frozenset[MouseModifier] = frozenset({MouseModifier.SHIFT}) 

37ALT : frozenset[MouseModifier] = frozenset({MouseModifier.ALT}) 

38SHIFT_ALT : frozenset[MouseModifier] = frozenset({MouseModifier.SHIFT, MouseModifier.ALT}) 

39CONTROL : frozenset[MouseModifier] = frozenset({MouseModifier.CONTROL}) 

40SHIFT_CONTROL : frozenset[MouseModifier] = frozenset({MouseModifier.SHIFT, MouseModifier.CONTROL}) 

41ALT_CONTROL : frozenset[MouseModifier] = frozenset({MouseModifier.ALT, MouseModifier.CONTROL}) 

42SHIFT_ALT_CONTROL: frozenset[MouseModifier] = frozenset({MouseModifier.SHIFT, MouseModifier.ALT, MouseModifier.CONTROL}) 

43UNKNOWN_MODIFIER : frozenset[MouseModifier] = frozenset() 

44 

45LEFT = MouseButton.LEFT 

46MIDDLE = MouseButton.MIDDLE 

47RIGHT = MouseButton.RIGHT 

48NO_BUTTON = MouseButton.NONE 

49UNKNOWN_BUTTON = MouseButton.UNKNOWN 

50 

51xterm_sgr_mouse_events = { 

52 ( 0, 'm') : (LEFT, MOUSE_UP, NO_MODIFIER), # left_up 0+ + + =0 

53 ( 4, 'm') : (LEFT, MOUSE_UP, SHIFT), # left_up Shift 0+4+ + =4 

54 ( 8, 'm') : (LEFT, MOUSE_UP, ALT), # left_up Alt 0+ +8+ =8 

55 (12, 'm') : (LEFT, MOUSE_UP, SHIFT_ALT), # left_up Shift Alt 0+4+8+ =12 

56 (16, 'm') : (LEFT, MOUSE_UP, CONTROL), # left_up Control 0+ + +16=16 

57 (20, 'm') : (LEFT, MOUSE_UP, SHIFT_CONTROL), # left_up Shift Control 0+4+ +16=20 

58 (24, 'm') : (LEFT, MOUSE_UP, ALT_CONTROL), # left_up Alt Control 0+ +8+16=24 

59 (28, 'm') : (LEFT, MOUSE_UP, SHIFT_ALT_CONTROL), # left_up Shift Alt Control 0+4+8+16=28 

60 

61 ( 1, 'm') : (MIDDLE, MOUSE_UP, NO_MODIFIER), # middle_up 1+ + + =1 

62 ( 5, 'm') : (MIDDLE, MOUSE_UP, SHIFT), # middle_up Shift 1+4+ + =5 

63 ( 9, 'm') : (MIDDLE, MOUSE_UP, ALT), # middle_up Alt 1+ +8+ =9 

64 (13, 'm') : (MIDDLE, MOUSE_UP, SHIFT_ALT), # middle_up Shift Alt 1+4+8+ =13 

65 (17, 'm') : (MIDDLE, MOUSE_UP, CONTROL), # middle_up Control 1+ + +16=17 

66 (21, 'm') : (MIDDLE, MOUSE_UP, SHIFT_CONTROL), # middle_up Shift Control 1+4+ +16=21 

67 (25, 'm') : (MIDDLE, MOUSE_UP, ALT_CONTROL), # middle_up Alt Control 1+ +8+16=25 

68 (29, 'm') : (MIDDLE, MOUSE_UP, SHIFT_ALT_CONTROL), # middle_up Shift Alt Control 1+4+8+16=29 

69 

70 ( 2, 'm') : (RIGHT, MOUSE_UP, NO_MODIFIER), # right_up 2+ + + =2 

71 ( 6, 'm') : (RIGHT, MOUSE_UP, SHIFT), # right_up Shift 2+4+ + =6 

72 (10, 'm') : (RIGHT, MOUSE_UP, ALT), # right_up Alt 2+ +8+ =10 

73 (14, 'm') : (RIGHT, MOUSE_UP, SHIFT_ALT), # right_up Shift Alt 2+4+8+ =14 

74 (18, 'm') : (RIGHT, MOUSE_UP, CONTROL), # right_up Control 2+ + +16=18 

75 (22, 'm') : (RIGHT, MOUSE_UP, SHIFT_CONTROL), # right_up Shift Control 2+4+ +16=22 

76 (26, 'm') : (RIGHT, MOUSE_UP, ALT_CONTROL), # right_up Alt Control 2+ +8+16=26 

77 (30, 'm') : (RIGHT, MOUSE_UP, SHIFT_ALT_CONTROL), # right_up Shift Alt Control 2+4+8+16=30 

78 

79 ( 0, 'M') : (LEFT, MOUSE_DOWN, NO_MODIFIER), # left_down 0+ + + =0 

80 ( 4, 'M') : (LEFT, MOUSE_DOWN, SHIFT), # left_down Shift 0+4+ + =4 

81 ( 8, 'M') : (LEFT, MOUSE_DOWN, ALT), # left_down Alt 0+ +8+ =8 

82 (12, 'M') : (LEFT, MOUSE_DOWN, SHIFT_ALT), # left_down Shift Alt 0+4+8+ =12 

83 (16, 'M') : (LEFT, MOUSE_DOWN, CONTROL), # left_down Control 0+ + +16=16 

84 (20, 'M') : (LEFT, MOUSE_DOWN, SHIFT_CONTROL), # left_down Shift Control 0+4+ +16=20 

85 (24, 'M') : (LEFT, MOUSE_DOWN, ALT_CONTROL), # left_down Alt Control 0+ +8+16=24 

86 (28, 'M') : (LEFT, MOUSE_DOWN, SHIFT_ALT_CONTROL), # left_down Shift Alt Control 0+4+8+16=28 

87 

88 ( 1, 'M') : (MIDDLE, MOUSE_DOWN, NO_MODIFIER), # middle_down 1+ + + =1 

89 ( 5, 'M') : (MIDDLE, MOUSE_DOWN, SHIFT), # middle_down Shift 1+4+ + =5 

90 ( 9, 'M') : (MIDDLE, MOUSE_DOWN, ALT), # middle_down Alt 1+ +8+ =9 

91 (13, 'M') : (MIDDLE, MOUSE_DOWN, SHIFT_ALT), # middle_down Shift Alt 1+4+8+ =13 

92 (17, 'M') : (MIDDLE, MOUSE_DOWN, CONTROL), # middle_down Control 1+ + +16=17 

93 (21, 'M') : (MIDDLE, MOUSE_DOWN, SHIFT_CONTROL), # middle_down Shift Control 1+4+ +16=21 

94 (25, 'M') : (MIDDLE, MOUSE_DOWN, ALT_CONTROL), # middle_down Alt Control 1+ +8+16=25 

95 (29, 'M') : (MIDDLE, MOUSE_DOWN, SHIFT_ALT_CONTROL), # middle_down Shift Alt Control 1+4+8+16=29 

96 

97 ( 2, 'M') : (RIGHT, MOUSE_DOWN, NO_MODIFIER), # right_down 2+ + + =2 

98 ( 6, 'M') : (RIGHT, MOUSE_DOWN, SHIFT), # right_down Shift 2+4+ + =6 

99 (10, 'M') : (RIGHT, MOUSE_DOWN, ALT), # right_down Alt 2+ +8+ =10 

100 (14, 'M') : (RIGHT, MOUSE_DOWN, SHIFT_ALT), # right_down Shift Alt 2+4+8+ =14 

101 (18, 'M') : (RIGHT, MOUSE_DOWN, CONTROL), # right_down Control 2+ + +16=18 

102 (22, 'M') : (RIGHT, MOUSE_DOWN, SHIFT_CONTROL), # right_down Shift Control 2+4+ +16=22 

103 (26, 'M') : (RIGHT, MOUSE_DOWN, ALT_CONTROL), # right_down Alt Control 2+ +8+16=26 

104 (30, 'M') : (RIGHT, MOUSE_DOWN, SHIFT_ALT_CONTROL), # right_down Shift Alt Control 2+4+8+16=30 

105 

106 (32, 'M') : (LEFT, MOUSE_MOVE, NO_MODIFIER), # left_drag 32+ + + =32 

107 (36, 'M') : (LEFT, MOUSE_MOVE, SHIFT), # left_drag Shift 32+4+ + =36 

108 (40, 'M') : (LEFT, MOUSE_MOVE, ALT), # left_drag Alt 32+ +8+ =40 

109 (44, 'M') : (LEFT, MOUSE_MOVE, SHIFT_ALT), # left_drag Shift Alt 32+4+8+ =44 

110 (48, 'M') : (LEFT, MOUSE_MOVE, CONTROL), # left_drag Control 32+ + +16=48 

111 (52, 'M') : (LEFT, MOUSE_MOVE, SHIFT_CONTROL), # left_drag Shift Control 32+4+ +16=52 

112 (56, 'M') : (LEFT, MOUSE_MOVE, ALT_CONTROL), # left_drag Alt Control 32+ +8+16=56 

113 (60, 'M') : (LEFT, MOUSE_MOVE, SHIFT_ALT_CONTROL), # left_drag Shift Alt Control 32+4+8+16=60 

114 

115 (33, 'M') : (MIDDLE, MOUSE_MOVE, NO_MODIFIER), # middle_drag 33+ + + =33 

116 (37, 'M') : (MIDDLE, MOUSE_MOVE, SHIFT), # middle_drag Shift 33+4+ + =37 

117 (41, 'M') : (MIDDLE, MOUSE_MOVE, ALT), # middle_drag Alt 33+ +8+ =41 

118 (45, 'M') : (MIDDLE, MOUSE_MOVE, SHIFT_ALT), # middle_drag Shift Alt 33+4+8+ =45 

119 (49, 'M') : (MIDDLE, MOUSE_MOVE, CONTROL), # middle_drag Control 33+ + +16=49 

120 (53, 'M') : (MIDDLE, MOUSE_MOVE, SHIFT_CONTROL), # middle_drag Shift Control 33+4+ +16=53 

121 (57, 'M') : (MIDDLE, MOUSE_MOVE, ALT_CONTROL), # middle_drag Alt Control 33+ +8+16=57 

122 (61, 'M') : (MIDDLE, MOUSE_MOVE, SHIFT_ALT_CONTROL), # middle_drag Shift Alt Control 33+4+8+16=61 

123 

124 (34, 'M') : (RIGHT, MOUSE_MOVE, NO_MODIFIER), # right_drag 34+ + + =34 

125 (38, 'M') : (RIGHT, MOUSE_MOVE, SHIFT), # right_drag Shift 34+4+ + =38 

126 (42, 'M') : (RIGHT, MOUSE_MOVE, ALT), # right_drag Alt 34+ +8+ =42 

127 (46, 'M') : (RIGHT, MOUSE_MOVE, SHIFT_ALT), # right_drag Shift Alt 34+4+8+ =46 

128 (50, 'M') : (RIGHT, MOUSE_MOVE, CONTROL), # right_drag Control 34+ + +16=50 

129 (54, 'M') : (RIGHT, MOUSE_MOVE, SHIFT_CONTROL), # right_drag Shift Control 34+4+ +16=54 

130 (58, 'M') : (RIGHT, MOUSE_MOVE, ALT_CONTROL), # right_drag Alt Control 34+ +8+16=58 

131 (62, 'M') : (RIGHT, MOUSE_MOVE, SHIFT_ALT_CONTROL), # right_drag Shift Alt Control 34+4+8+16=62 

132 

133 (35, 'M') : (NO_BUTTON, MOUSE_MOVE, NO_MODIFIER), # none_drag 35+ + + =35 

134 (39, 'M') : (NO_BUTTON, MOUSE_MOVE, SHIFT), # none_drag Shift 35+4+ + =39 

135 (43, 'M') : (NO_BUTTON, MOUSE_MOVE, ALT), # none_drag Alt 35+ +8+ =43 

136 (47, 'M') : (NO_BUTTON, MOUSE_MOVE, SHIFT_ALT), # none_drag Shift Alt 35+4+8+ =47 

137 (51, 'M') : (NO_BUTTON, MOUSE_MOVE, CONTROL), # none_drag Control 35+ + +16=51 

138 (55, 'M') : (NO_BUTTON, MOUSE_MOVE, SHIFT_CONTROL), # none_drag Shift Control 35+4+ +16=55 

139 (59, 'M') : (NO_BUTTON, MOUSE_MOVE, ALT_CONTROL), # none_drag Alt Control 35+ +8+16=59 

140 (63, 'M') : (NO_BUTTON, MOUSE_MOVE, SHIFT_ALT_CONTROL), # none_drag Shift Alt Control 35+4+8+16=63 

141 

142 (64, 'M') : (NO_BUTTON, SCROLL_UP, NO_MODIFIER), # scroll_up 64+ + + =64 

143 (68, 'M') : (NO_BUTTON, SCROLL_UP, SHIFT), # scroll_up Shift 64+4+ + =68 

144 (72, 'M') : (NO_BUTTON, SCROLL_UP, ALT), # scroll_up Alt 64+ +8+ =72 

145 (76, 'M') : (NO_BUTTON, SCROLL_UP, SHIFT_ALT), # scroll_up Shift Alt 64+4+8+ =76 

146 (80, 'M') : (NO_BUTTON, SCROLL_UP, CONTROL), # scroll_up Control 64+ + +16=80 

147 (84, 'M') : (NO_BUTTON, SCROLL_UP, SHIFT_CONTROL), # scroll_up Shift Control 64+4+ +16=84 

148 (88, 'M') : (NO_BUTTON, SCROLL_UP, ALT_CONTROL), # scroll_up Alt Control 64+ +8+16=88 

149 (92, 'M') : (NO_BUTTON, SCROLL_UP, SHIFT_ALT_CONTROL), # scroll_up Shift Alt Control 64+4+8+16=92 

150 

151 (65, 'M') : (NO_BUTTON, SCROLL_DOWN, NO_MODIFIER), # scroll_down 64+ + + =65 

152 (69, 'M') : (NO_BUTTON, SCROLL_DOWN, SHIFT), # scroll_down Shift 64+4+ + =69 

153 (73, 'M') : (NO_BUTTON, SCROLL_DOWN, ALT), # scroll_down Alt 64+ +8+ =73 

154 (77, 'M') : (NO_BUTTON, SCROLL_DOWN, SHIFT_ALT), # scroll_down Shift Alt 64+4+8+ =77 

155 (81, 'M') : (NO_BUTTON, SCROLL_DOWN, CONTROL), # scroll_down Control 64+ + +16=81 

156 (85, 'M') : (NO_BUTTON, SCROLL_DOWN, SHIFT_CONTROL), # scroll_down Shift Control 64+4+ +16=85 

157 (89, 'M') : (NO_BUTTON, SCROLL_DOWN, ALT_CONTROL), # scroll_down Alt Control 64+ +8+16=89 

158 (93, 'M') : (NO_BUTTON, SCROLL_DOWN, SHIFT_ALT_CONTROL), # scroll_down Shift Alt Control 64+4+8+16=93 

159} 

160 

161typical_mouse_events = { 

162 32: (LEFT , MOUSE_DOWN , UNKNOWN_MODIFIER), 

163 33: (MIDDLE , MOUSE_DOWN , UNKNOWN_MODIFIER), 

164 34: (RIGHT , MOUSE_DOWN , UNKNOWN_MODIFIER), 

165 35: (UNKNOWN_BUTTON , MOUSE_UP , UNKNOWN_MODIFIER), 

166 

167 64: (LEFT , MOUSE_MOVE , UNKNOWN_MODIFIER), 

168 65: (MIDDLE , MOUSE_MOVE , UNKNOWN_MODIFIER), 

169 66: (RIGHT , MOUSE_MOVE , UNKNOWN_MODIFIER), 

170 67: (NO_BUTTON , MOUSE_MOVE , UNKNOWN_MODIFIER), 

171 

172 96: (NO_BUTTON , SCROLL_UP , UNKNOWN_MODIFIER), 

173 97: (NO_BUTTON , SCROLL_DOWN, UNKNOWN_MODIFIER), 

174} 

175 

176urxvt_mouse_events={ 

177 32: (UNKNOWN_BUTTON, MOUSE_DOWN , UNKNOWN_MODIFIER), 

178 35: (UNKNOWN_BUTTON, MOUSE_UP , UNKNOWN_MODIFIER), 

179 96: (NO_BUTTON , SCROLL_UP , UNKNOWN_MODIFIER), 

180 97: (NO_BUTTON , SCROLL_DOWN, UNKNOWN_MODIFIER), 

181} 

182# fmt:on 

183 

184 

185def load_mouse_bindings() -> KeyBindings: 

186 """ 

187 Key bindings, required for mouse support. 

188 (Mouse events enter through the key binding system.) 

189 """ 

190 key_bindings = KeyBindings() 

191 

192 @key_bindings.add(Keys.Vt100MouseEvent) 

193 def _(event: E) -> NotImplementedOrNone: 

194 """ 

195 Handling of incoming mouse event. 

196 """ 

197 # TypicaL: "eSC[MaB*" 

198 # Urxvt: "Esc[96;14;13M" 

199 # Xterm SGR: "Esc[<64;85;12M" 

200 

201 # Parse incoming packet. 

202 if event.data[2] == "M": 

203 # Typical. 

204 mouse_event, x, y = map(ord, event.data[3:]) 

205 

206 # TODO: Is it possible to add modifiers here? 

207 mouse_button, mouse_event_type, mouse_modifiers = typical_mouse_events[ 

208 mouse_event 

209 ] 

210 

211 # Handle situations where `PosixStdinReader` used surrogateescapes. 

212 if x >= 0xDC00: 

213 x -= 0xDC00 

214 if y >= 0xDC00: 

215 y -= 0xDC00 

216 

217 x -= 32 

218 y -= 32 

219 else: 

220 # Urxvt and Xterm SGR. 

221 # When the '<' is not present, we are not using the Xterm SGR mode, 

222 # but Urxvt instead. 

223 data = event.data[2:] 

224 if data[:1] == "<": 

225 sgr = True 

226 data = data[1:] 

227 else: 

228 sgr = False 

229 

230 # Extract coordinates. 

231 mouse_event, x, y = map(int, data[:-1].split(";")) 

232 m = data[-1] 

233 

234 # Parse event type. 

235 if sgr: 

236 try: 

237 ( 

238 mouse_button, 

239 mouse_event_type, 

240 mouse_modifiers, 

241 ) = xterm_sgr_mouse_events[mouse_event, m] 

242 except KeyError: 

243 return NotImplemented 

244 

245 else: 

246 # Some other terminals, like urxvt, Hyper terminal, ... 

247 ( 

248 mouse_button, 

249 mouse_event_type, 

250 mouse_modifiers, 

251 ) = urxvt_mouse_events.get( 

252 mouse_event, (UNKNOWN_BUTTON, MOUSE_MOVE, UNKNOWN_MODIFIER) 

253 ) 

254 

255 x -= 1 

256 y -= 1 

257 

258 # Only handle mouse events when we know the window height. 

259 if event.app.renderer.height_is_known and mouse_event_type is not None: 

260 # Take region above the layout into account. The reported 

261 # coordinates are absolute to the visible part of the terminal. 

262 from prompt_toolkit.renderer import HeightIsUnknownError 

263 

264 try: 

265 y -= event.app.renderer.rows_above_layout 

266 except HeightIsUnknownError: 

267 return NotImplemented 

268 

269 # Call the mouse handler from the renderer. 

270 

271 # Note: This can return `NotImplemented` if no mouse handler was 

272 # found for this position, or if no repainting needs to 

273 # happen. this way, we avoid excessive repaints during mouse 

274 # movements. 

275 handler = event.app.renderer.mouse_handlers.mouse_handlers[y][x] 

276 return handler( 

277 MouseEvent( 

278 position=Point(x=x, y=y), 

279 event_type=mouse_event_type, 

280 button=mouse_button, 

281 modifiers=mouse_modifiers, 

282 ) 

283 ) 

284 

285 return NotImplemented 

286 

287 @key_bindings.add(Keys.ScrollUp) 

288 def _scroll_up(event: E) -> None: 

289 """ 

290 Scroll up event without cursor position. 

291 """ 

292 # We don't receive a cursor position, so we don't know which window to 

293 # scroll. Just send an 'up' key press instead. 

294 event.key_processor.feed(KeyPress(Keys.Up), first=True) 

295 

296 @key_bindings.add(Keys.ScrollDown) 

297 def _scroll_down(event: E) -> None: 

298 """ 

299 Scroll down event without cursor position. 

300 """ 

301 event.key_processor.feed(KeyPress(Keys.Down), first=True) 

302 

303 @key_bindings.add(Keys.WindowsMouseEvent) 

304 def _mouse(event: E) -> NotImplementedOrNone: 

305 """ 

306 Handling of mouse events for Windows. 

307 """ 

308 # This key binding should only exist for Windows. 

309 if sys.platform == "win32": 

310 # Parse data. 

311 pieces = event.data.split(";") 

312 

313 button = MouseButton(pieces[0]) 

314 event_type = MouseEventType(pieces[1]) 

315 x = int(pieces[2]) 

316 y = int(pieces[3]) 

317 

318 # Make coordinates absolute to the visible part of the terminal. 

319 output = event.app.renderer.output 

320 

321 from prompt_toolkit.output.win32 import Win32Output 

322 from prompt_toolkit.output.windows10 import Windows10_Output 

323 

324 if isinstance(output, (Win32Output, Windows10_Output)): 

325 screen_buffer_info = output.get_win32_screen_buffer_info() 

326 rows_above_cursor = ( 

327 screen_buffer_info.dwCursorPosition.Y 

328 - event.app.renderer._cursor_pos.y 

329 ) 

330 y -= rows_above_cursor 

331 

332 # Call the mouse event handler. 

333 # (Can return `NotImplemented`.) 

334 handler = event.app.renderer.mouse_handlers.mouse_handlers[y][x] 

335 

336 return handler( 

337 MouseEvent( 

338 position=Point(x=x, y=y), 

339 event_type=event_type, 

340 button=button, 

341 modifiers=UNKNOWN_MODIFIER, 

342 ) 

343 ) 

344 

345 # No mouse handler found. Return `NotImplemented` so that we don't 

346 # invalidate the UI. 

347 return NotImplemented 

348 

349 return key_bindings