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.4.4, created at 2024-04-20 06:09 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-20 06:09 +0000
1from __future__ import annotations
3import sys
4from typing import TYPE_CHECKING
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)
16from ..key_bindings import KeyBindings
18if TYPE_CHECKING:
19 from prompt_toolkit.key_binding.key_bindings import NotImplementedOrNone
21__all__ = [
22 "load_mouse_bindings",
23]
25E = KeyPressEvent
27# fmt: off
28SCROLL_UP = MouseEventType.SCROLL_UP
29SCROLL_DOWN = MouseEventType.SCROLL_DOWN
30MOUSE_DOWN = MouseEventType.MOUSE_DOWN
31MOUSE_MOVE = MouseEventType.MOUSE_MOVE
32MOUSE_UP = MouseEventType.MOUSE_UP
34NO_MODIFIER : frozenset[MouseModifier] = frozenset()
35SHIFT : frozenset[MouseModifier] = frozenset({MouseModifier.SHIFT})
36ALT : frozenset[MouseModifier] = frozenset({MouseModifier.ALT})
37SHIFT_ALT : frozenset[MouseModifier] = frozenset({MouseModifier.SHIFT, MouseModifier.ALT})
38CONTROL : frozenset[MouseModifier] = frozenset({MouseModifier.CONTROL})
39SHIFT_CONTROL : frozenset[MouseModifier] = frozenset({MouseModifier.SHIFT, MouseModifier.CONTROL})
40ALT_CONTROL : frozenset[MouseModifier] = frozenset({MouseModifier.ALT, MouseModifier.CONTROL})
41SHIFT_ALT_CONTROL: frozenset[MouseModifier] = frozenset({MouseModifier.SHIFT, MouseModifier.ALT, MouseModifier.CONTROL})
42UNKNOWN_MODIFIER : frozenset[MouseModifier] = frozenset()
44LEFT = MouseButton.LEFT
45MIDDLE = MouseButton.MIDDLE
46RIGHT = MouseButton.RIGHT
47NO_BUTTON = MouseButton.NONE
48UNKNOWN_BUTTON = MouseButton.UNKNOWN
50xterm_sgr_mouse_events = {
51 ( 0, "m") : (LEFT, MOUSE_UP, NO_MODIFIER), # left_up 0+ + + =0
52 ( 4, "m") : (LEFT, MOUSE_UP, SHIFT), # left_up Shift 0+4+ + =4
53 ( 8, "m") : (LEFT, MOUSE_UP, ALT), # left_up Alt 0+ +8+ =8
54 (12, "m") : (LEFT, MOUSE_UP, SHIFT_ALT), # left_up Shift Alt 0+4+8+ =12
55 (16, "m") : (LEFT, MOUSE_UP, CONTROL), # left_up Control 0+ + +16=16
56 (20, "m") : (LEFT, MOUSE_UP, SHIFT_CONTROL), # left_up Shift Control 0+4+ +16=20
57 (24, "m") : (LEFT, MOUSE_UP, ALT_CONTROL), # left_up Alt Control 0+ +8+16=24
58 (28, "m") : (LEFT, MOUSE_UP, SHIFT_ALT_CONTROL), # left_up Shift Alt Control 0+4+8+16=28
60 ( 1, "m") : (MIDDLE, MOUSE_UP, NO_MODIFIER), # middle_up 1+ + + =1
61 ( 5, "m") : (MIDDLE, MOUSE_UP, SHIFT), # middle_up Shift 1+4+ + =5
62 ( 9, "m") : (MIDDLE, MOUSE_UP, ALT), # middle_up Alt 1+ +8+ =9
63 (13, "m") : (MIDDLE, MOUSE_UP, SHIFT_ALT), # middle_up Shift Alt 1+4+8+ =13
64 (17, "m") : (MIDDLE, MOUSE_UP, CONTROL), # middle_up Control 1+ + +16=17
65 (21, "m") : (MIDDLE, MOUSE_UP, SHIFT_CONTROL), # middle_up Shift Control 1+4+ +16=21
66 (25, "m") : (MIDDLE, MOUSE_UP, ALT_CONTROL), # middle_up Alt Control 1+ +8+16=25
67 (29, "m") : (MIDDLE, MOUSE_UP, SHIFT_ALT_CONTROL), # middle_up Shift Alt Control 1+4+8+16=29
69 ( 2, "m") : (RIGHT, MOUSE_UP, NO_MODIFIER), # right_up 2+ + + =2
70 ( 6, "m") : (RIGHT, MOUSE_UP, SHIFT), # right_up Shift 2+4+ + =6
71 (10, "m") : (RIGHT, MOUSE_UP, ALT), # right_up Alt 2+ +8+ =10
72 (14, "m") : (RIGHT, MOUSE_UP, SHIFT_ALT), # right_up Shift Alt 2+4+8+ =14
73 (18, "m") : (RIGHT, MOUSE_UP, CONTROL), # right_up Control 2+ + +16=18
74 (22, "m") : (RIGHT, MOUSE_UP, SHIFT_CONTROL), # right_up Shift Control 2+4+ +16=22
75 (26, "m") : (RIGHT, MOUSE_UP, ALT_CONTROL), # right_up Alt Control 2+ +8+16=26
76 (30, "m") : (RIGHT, MOUSE_UP, SHIFT_ALT_CONTROL), # right_up Shift Alt Control 2+4+8+16=30
78 ( 0, "M") : (LEFT, MOUSE_DOWN, NO_MODIFIER), # left_down 0+ + + =0
79 ( 4, "M") : (LEFT, MOUSE_DOWN, SHIFT), # left_down Shift 0+4+ + =4
80 ( 8, "M") : (LEFT, MOUSE_DOWN, ALT), # left_down Alt 0+ +8+ =8
81 (12, "M") : (LEFT, MOUSE_DOWN, SHIFT_ALT), # left_down Shift Alt 0+4+8+ =12
82 (16, "M") : (LEFT, MOUSE_DOWN, CONTROL), # left_down Control 0+ + +16=16
83 (20, "M") : (LEFT, MOUSE_DOWN, SHIFT_CONTROL), # left_down Shift Control 0+4+ +16=20
84 (24, "M") : (LEFT, MOUSE_DOWN, ALT_CONTROL), # left_down Alt Control 0+ +8+16=24
85 (28, "M") : (LEFT, MOUSE_DOWN, SHIFT_ALT_CONTROL), # left_down Shift Alt Control 0+4+8+16=28
87 ( 1, "M") : (MIDDLE, MOUSE_DOWN, NO_MODIFIER), # middle_down 1+ + + =1
88 ( 5, "M") : (MIDDLE, MOUSE_DOWN, SHIFT), # middle_down Shift 1+4+ + =5
89 ( 9, "M") : (MIDDLE, MOUSE_DOWN, ALT), # middle_down Alt 1+ +8+ =9
90 (13, "M") : (MIDDLE, MOUSE_DOWN, SHIFT_ALT), # middle_down Shift Alt 1+4+8+ =13
91 (17, "M") : (MIDDLE, MOUSE_DOWN, CONTROL), # middle_down Control 1+ + +16=17
92 (21, "M") : (MIDDLE, MOUSE_DOWN, SHIFT_CONTROL), # middle_down Shift Control 1+4+ +16=21
93 (25, "M") : (MIDDLE, MOUSE_DOWN, ALT_CONTROL), # middle_down Alt Control 1+ +8+16=25
94 (29, "M") : (MIDDLE, MOUSE_DOWN, SHIFT_ALT_CONTROL), # middle_down Shift Alt Control 1+4+8+16=29
96 ( 2, "M") : (RIGHT, MOUSE_DOWN, NO_MODIFIER), # right_down 2+ + + =2
97 ( 6, "M") : (RIGHT, MOUSE_DOWN, SHIFT), # right_down Shift 2+4+ + =6
98 (10, "M") : (RIGHT, MOUSE_DOWN, ALT), # right_down Alt 2+ +8+ =10
99 (14, "M") : (RIGHT, MOUSE_DOWN, SHIFT_ALT), # right_down Shift Alt 2+4+8+ =14
100 (18, "M") : (RIGHT, MOUSE_DOWN, CONTROL), # right_down Control 2+ + +16=18
101 (22, "M") : (RIGHT, MOUSE_DOWN, SHIFT_CONTROL), # right_down Shift Control 2+4+ +16=22
102 (26, "M") : (RIGHT, MOUSE_DOWN, ALT_CONTROL), # right_down Alt Control 2+ +8+16=26
103 (30, "M") : (RIGHT, MOUSE_DOWN, SHIFT_ALT_CONTROL), # right_down Shift Alt Control 2+4+8+16=30
105 (32, "M") : (LEFT, MOUSE_MOVE, NO_MODIFIER), # left_drag 32+ + + =32
106 (36, "M") : (LEFT, MOUSE_MOVE, SHIFT), # left_drag Shift 32+4+ + =36
107 (40, "M") : (LEFT, MOUSE_MOVE, ALT), # left_drag Alt 32+ +8+ =40
108 (44, "M") : (LEFT, MOUSE_MOVE, SHIFT_ALT), # left_drag Shift Alt 32+4+8+ =44
109 (48, "M") : (LEFT, MOUSE_MOVE, CONTROL), # left_drag Control 32+ + +16=48
110 (52, "M") : (LEFT, MOUSE_MOVE, SHIFT_CONTROL), # left_drag Shift Control 32+4+ +16=52
111 (56, "M") : (LEFT, MOUSE_MOVE, ALT_CONTROL), # left_drag Alt Control 32+ +8+16=56
112 (60, "M") : (LEFT, MOUSE_MOVE, SHIFT_ALT_CONTROL), # left_drag Shift Alt Control 32+4+8+16=60
114 (33, "M") : (MIDDLE, MOUSE_MOVE, NO_MODIFIER), # middle_drag 33+ + + =33
115 (37, "M") : (MIDDLE, MOUSE_MOVE, SHIFT), # middle_drag Shift 33+4+ + =37
116 (41, "M") : (MIDDLE, MOUSE_MOVE, ALT), # middle_drag Alt 33+ +8+ =41
117 (45, "M") : (MIDDLE, MOUSE_MOVE, SHIFT_ALT), # middle_drag Shift Alt 33+4+8+ =45
118 (49, "M") : (MIDDLE, MOUSE_MOVE, CONTROL), # middle_drag Control 33+ + +16=49
119 (53, "M") : (MIDDLE, MOUSE_MOVE, SHIFT_CONTROL), # middle_drag Shift Control 33+4+ +16=53
120 (57, "M") : (MIDDLE, MOUSE_MOVE, ALT_CONTROL), # middle_drag Alt Control 33+ +8+16=57
121 (61, "M") : (MIDDLE, MOUSE_MOVE, SHIFT_ALT_CONTROL), # middle_drag Shift Alt Control 33+4+8+16=61
123 (34, "M") : (RIGHT, MOUSE_MOVE, NO_MODIFIER), # right_drag 34+ + + =34
124 (38, "M") : (RIGHT, MOUSE_MOVE, SHIFT), # right_drag Shift 34+4+ + =38
125 (42, "M") : (RIGHT, MOUSE_MOVE, ALT), # right_drag Alt 34+ +8+ =42
126 (46, "M") : (RIGHT, MOUSE_MOVE, SHIFT_ALT), # right_drag Shift Alt 34+4+8+ =46
127 (50, "M") : (RIGHT, MOUSE_MOVE, CONTROL), # right_drag Control 34+ + +16=50
128 (54, "M") : (RIGHT, MOUSE_MOVE, SHIFT_CONTROL), # right_drag Shift Control 34+4+ +16=54
129 (58, "M") : (RIGHT, MOUSE_MOVE, ALT_CONTROL), # right_drag Alt Control 34+ +8+16=58
130 (62, "M") : (RIGHT, MOUSE_MOVE, SHIFT_ALT_CONTROL), # right_drag Shift Alt Control 34+4+8+16=62
132 (35, "M") : (NO_BUTTON, MOUSE_MOVE, NO_MODIFIER), # none_drag 35+ + + =35
133 (39, "M") : (NO_BUTTON, MOUSE_MOVE, SHIFT), # none_drag Shift 35+4+ + =39
134 (43, "M") : (NO_BUTTON, MOUSE_MOVE, ALT), # none_drag Alt 35+ +8+ =43
135 (47, "M") : (NO_BUTTON, MOUSE_MOVE, SHIFT_ALT), # none_drag Shift Alt 35+4+8+ =47
136 (51, "M") : (NO_BUTTON, MOUSE_MOVE, CONTROL), # none_drag Control 35+ + +16=51
137 (55, "M") : (NO_BUTTON, MOUSE_MOVE, SHIFT_CONTROL), # none_drag Shift Control 35+4+ +16=55
138 (59, "M") : (NO_BUTTON, MOUSE_MOVE, ALT_CONTROL), # none_drag Alt Control 35+ +8+16=59
139 (63, "M") : (NO_BUTTON, MOUSE_MOVE, SHIFT_ALT_CONTROL), # none_drag Shift Alt Control 35+4+8+16=63
141 (64, "M") : (NO_BUTTON, SCROLL_UP, NO_MODIFIER), # scroll_up 64+ + + =64
142 (68, "M") : (NO_BUTTON, SCROLL_UP, SHIFT), # scroll_up Shift 64+4+ + =68
143 (72, "M") : (NO_BUTTON, SCROLL_UP, ALT), # scroll_up Alt 64+ +8+ =72
144 (76, "M") : (NO_BUTTON, SCROLL_UP, SHIFT_ALT), # scroll_up Shift Alt 64+4+8+ =76
145 (80, "M") : (NO_BUTTON, SCROLL_UP, CONTROL), # scroll_up Control 64+ + +16=80
146 (84, "M") : (NO_BUTTON, SCROLL_UP, SHIFT_CONTROL), # scroll_up Shift Control 64+4+ +16=84
147 (88, "M") : (NO_BUTTON, SCROLL_UP, ALT_CONTROL), # scroll_up Alt Control 64+ +8+16=88
148 (92, "M") : (NO_BUTTON, SCROLL_UP, SHIFT_ALT_CONTROL), # scroll_up Shift Alt Control 64+4+8+16=92
150 (65, "M") : (NO_BUTTON, SCROLL_DOWN, NO_MODIFIER), # scroll_down 64+ + + =65
151 (69, "M") : (NO_BUTTON, SCROLL_DOWN, SHIFT), # scroll_down Shift 64+4+ + =69
152 (73, "M") : (NO_BUTTON, SCROLL_DOWN, ALT), # scroll_down Alt 64+ +8+ =73
153 (77, "M") : (NO_BUTTON, SCROLL_DOWN, SHIFT_ALT), # scroll_down Shift Alt 64+4+8+ =77
154 (81, "M") : (NO_BUTTON, SCROLL_DOWN, CONTROL), # scroll_down Control 64+ + +16=81
155 (85, "M") : (NO_BUTTON, SCROLL_DOWN, SHIFT_CONTROL), # scroll_down Shift Control 64+4+ +16=85
156 (89, "M") : (NO_BUTTON, SCROLL_DOWN, ALT_CONTROL), # scroll_down Alt Control 64+ +8+16=89
157 (93, "M") : (NO_BUTTON, SCROLL_DOWN, SHIFT_ALT_CONTROL), # scroll_down Shift Alt Control 64+4+8+16=93
158}
160typical_mouse_events = {
161 32: (LEFT , MOUSE_DOWN , UNKNOWN_MODIFIER),
162 33: (MIDDLE , MOUSE_DOWN , UNKNOWN_MODIFIER),
163 34: (RIGHT , MOUSE_DOWN , UNKNOWN_MODIFIER),
164 35: (UNKNOWN_BUTTON , MOUSE_UP , UNKNOWN_MODIFIER),
166 64: (LEFT , MOUSE_MOVE , UNKNOWN_MODIFIER),
167 65: (MIDDLE , MOUSE_MOVE , UNKNOWN_MODIFIER),
168 66: (RIGHT , MOUSE_MOVE , UNKNOWN_MODIFIER),
169 67: (NO_BUTTON , MOUSE_MOVE , UNKNOWN_MODIFIER),
171 96: (NO_BUTTON , SCROLL_UP , UNKNOWN_MODIFIER),
172 97: (NO_BUTTON , SCROLL_DOWN, UNKNOWN_MODIFIER),
173}
175urxvt_mouse_events={
176 32: (UNKNOWN_BUTTON, MOUSE_DOWN , UNKNOWN_MODIFIER),
177 35: (UNKNOWN_BUTTON, MOUSE_UP , UNKNOWN_MODIFIER),
178 96: (NO_BUTTON , SCROLL_UP , UNKNOWN_MODIFIER),
179 97: (NO_BUTTON , SCROLL_DOWN, UNKNOWN_MODIFIER),
180}
181# fmt:on
184def load_mouse_bindings() -> KeyBindings:
185 """
186 Key bindings, required for mouse support.
187 (Mouse events enter through the key binding system.)
188 """
189 key_bindings = KeyBindings()
191 @key_bindings.add(Keys.Vt100MouseEvent)
192 def _(event: E) -> NotImplementedOrNone:
193 """
194 Handling of incoming mouse event.
195 """
196 # TypicaL: "eSC[MaB*"
197 # Urxvt: "Esc[96;14;13M"
198 # Xterm SGR: "Esc[<64;85;12M"
200 # Parse incoming packet.
201 if event.data[2] == "M":
202 # Typical.
203 mouse_event, x, y = map(ord, event.data[3:])
205 # TODO: Is it possible to add modifiers here?
206 mouse_button, mouse_event_type, mouse_modifiers = typical_mouse_events[
207 mouse_event
208 ]
210 # Handle situations where `PosixStdinReader` used surrogateescapes.
211 if x >= 0xDC00:
212 x -= 0xDC00
213 if y >= 0xDC00:
214 y -= 0xDC00
216 x -= 32
217 y -= 32
218 else:
219 # Urxvt and Xterm SGR.
220 # When the '<' is not present, we are not using the Xterm SGR mode,
221 # but Urxvt instead.
222 data = event.data[2:]
223 if data[:1] == "<":
224 sgr = True
225 data = data[1:]
226 else:
227 sgr = False
229 # Extract coordinates.
230 mouse_event, x, y = map(int, data[:-1].split(";"))
231 m = data[-1]
233 # Parse event type.
234 if sgr:
235 try:
236 (
237 mouse_button,
238 mouse_event_type,
239 mouse_modifiers,
240 ) = xterm_sgr_mouse_events[mouse_event, m]
241 except KeyError:
242 return NotImplemented
244 else:
245 # Some other terminals, like urxvt, Hyper terminal, ...
246 (
247 mouse_button,
248 mouse_event_type,
249 mouse_modifiers,
250 ) = urxvt_mouse_events.get(
251 mouse_event, (UNKNOWN_BUTTON, MOUSE_MOVE, UNKNOWN_MODIFIER)
252 )
254 x -= 1
255 y -= 1
257 # Only handle mouse events when we know the window height.
258 if event.app.renderer.height_is_known and mouse_event_type is not None:
259 # Take region above the layout into account. The reported
260 # coordinates are absolute to the visible part of the terminal.
261 from prompt_toolkit.renderer import HeightIsUnknownError
263 try:
264 y -= event.app.renderer.rows_above_layout
265 except HeightIsUnknownError:
266 return NotImplemented
268 # Call the mouse handler from the renderer.
270 # Note: This can return `NotImplemented` if no mouse handler was
271 # found for this position, or if no repainting needs to
272 # happen. this way, we avoid excessive repaints during mouse
273 # movements.
274 handler = event.app.renderer.mouse_handlers.mouse_handlers[y][x]
275 return handler(
276 MouseEvent(
277 position=Point(x=x, y=y),
278 event_type=mouse_event_type,
279 button=mouse_button,
280 modifiers=mouse_modifiers,
281 )
282 )
284 return NotImplemented
286 @key_bindings.add(Keys.ScrollUp)
287 def _scroll_up(event: E) -> None:
288 """
289 Scroll up event without cursor position.
290 """
291 # We don't receive a cursor position, so we don't know which window to
292 # scroll. Just send an 'up' key press instead.
293 event.key_processor.feed(KeyPress(Keys.Up), first=True)
295 @key_bindings.add(Keys.ScrollDown)
296 def _scroll_down(event: E) -> None:
297 """
298 Scroll down event without cursor position.
299 """
300 event.key_processor.feed(KeyPress(Keys.Down), first=True)
302 @key_bindings.add(Keys.WindowsMouseEvent)
303 def _mouse(event: E) -> NotImplementedOrNone:
304 """
305 Handling of mouse events for Windows.
306 """
307 # This key binding should only exist for Windows.
308 if sys.platform == "win32":
309 # Parse data.
310 pieces = event.data.split(";")
312 button = MouseButton(pieces[0])
313 event_type = MouseEventType(pieces[1])
314 x = int(pieces[2])
315 y = int(pieces[3])
317 # Make coordinates absolute to the visible part of the terminal.
318 output = event.app.renderer.output
320 from prompt_toolkit.output.win32 import Win32Output
321 from prompt_toolkit.output.windows10 import Windows10_Output
323 if isinstance(output, (Win32Output, Windows10_Output)):
324 screen_buffer_info = output.get_win32_screen_buffer_info()
325 rows_above_cursor = (
326 screen_buffer_info.dwCursorPosition.Y
327 - event.app.renderer._cursor_pos.y
328 )
329 y -= rows_above_cursor
331 # Call the mouse event handler.
332 # (Can return `NotImplemented`.)
333 handler = event.app.renderer.mouse_handlers.mouse_handlers[y][x]
335 return handler(
336 MouseEvent(
337 position=Point(x=x, y=y),
338 event_type=event_type,
339 button=button,
340 modifiers=UNKNOWN_MODIFIER,
341 )
342 )
344 # No mouse handler found. Return `NotImplemented` so that we don't
345 # invalidate the UI.
346 return NotImplemented
348 return key_bindings