Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/scroll.py: 15%
81 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
1"""
2Key bindings, for scrolling up and down through pages.
4This are separate bindings, because GNU readline doesn't have them, but
5they are very useful for navigating through long multiline buffers, like in
6Vi, Emacs, etc...
7"""
8from __future__ import annotations
10from prompt_toolkit.key_binding.key_processor import KeyPressEvent
12__all__ = [
13 "scroll_forward",
14 "scroll_backward",
15 "scroll_half_page_up",
16 "scroll_half_page_down",
17 "scroll_one_line_up",
18 "scroll_one_line_down",
19]
21E = KeyPressEvent
24def scroll_forward(event: E, half: bool = False) -> None:
25 """
26 Scroll window down.
27 """
28 w = event.app.layout.current_window
29 b = event.app.current_buffer
31 if w and w.render_info:
32 info = w.render_info
33 ui_content = info.ui_content
35 # Height to scroll.
36 scroll_height = info.window_height
37 if half:
38 scroll_height //= 2
40 # Calculate how many lines is equivalent to that vertical space.
41 y = b.document.cursor_position_row + 1
42 height = 0
43 while y < ui_content.line_count:
44 line_height = info.get_height_for_line(y)
46 if height + line_height < scroll_height:
47 height += line_height
48 y += 1
49 else:
50 break
52 b.cursor_position = b.document.translate_row_col_to_index(y, 0)
55def scroll_backward(event: E, half: bool = False) -> None:
56 """
57 Scroll window up.
58 """
59 w = event.app.layout.current_window
60 b = event.app.current_buffer
62 if w and w.render_info:
63 info = w.render_info
65 # Height to scroll.
66 scroll_height = info.window_height
67 if half:
68 scroll_height //= 2
70 # Calculate how many lines is equivalent to that vertical space.
71 y = max(0, b.document.cursor_position_row - 1)
72 height = 0
73 while y > 0:
74 line_height = info.get_height_for_line(y)
76 if height + line_height < scroll_height:
77 height += line_height
78 y -= 1
79 else:
80 break
82 b.cursor_position = b.document.translate_row_col_to_index(y, 0)
85def scroll_half_page_down(event: E) -> None:
86 """
87 Same as ControlF, but only scroll half a page.
88 """
89 scroll_forward(event, half=True)
92def scroll_half_page_up(event: E) -> None:
93 """
94 Same as ControlB, but only scroll half a page.
95 """
96 scroll_backward(event, half=True)
99def scroll_one_line_down(event: E) -> None:
100 """
101 scroll_offset += 1
102 """
103 w = event.app.layout.current_window
104 b = event.app.current_buffer
106 if w:
107 # When the cursor is at the top, move to the next line. (Otherwise, only scroll.)
108 if w.render_info:
109 info = w.render_info
111 if w.vertical_scroll < info.content_height - info.window_height:
112 if info.cursor_position.y <= info.configured_scroll_offsets.top:
113 b.cursor_position += b.document.get_cursor_down_position()
115 w.vertical_scroll += 1
118def scroll_one_line_up(event: E) -> None:
119 """
120 scroll_offset -= 1
121 """
122 w = event.app.layout.current_window
123 b = event.app.current_buffer
125 if w:
126 # When the cursor is at the bottom, move to the previous line. (Otherwise, only scroll.)
127 if w.render_info:
128 info = w.render_info
130 if w.vertical_scroll > 0:
131 first_line_height = info.get_height_for_line(info.first_visible_line())
133 cursor_up = info.cursor_position.y - (
134 info.window_height
135 - 1
136 - first_line_height
137 - info.configured_scroll_offsets.bottom
138 )
140 # Move cursor up, as many steps as the height of the first line.
141 # TODO: not entirely correct yet, in case of line wrapping and many long lines.
142 for _ in range(max(0, cursor_up)):
143 b.cursor_position += b.document.get_cursor_up_position()
145 # Scroll window
146 w.vertical_scroll -= 1
149def scroll_page_down(event: E) -> None:
150 """
151 Scroll page down. (Prefer the cursor at the top of the page, after scrolling.)
152 """
153 w = event.app.layout.current_window
154 b = event.app.current_buffer
156 if w and w.render_info:
157 # Scroll down one page.
158 line_index = max(w.render_info.last_visible_line(), w.vertical_scroll + 1)
159 w.vertical_scroll = line_index
161 b.cursor_position = b.document.translate_row_col_to_index(line_index, 0)
162 b.cursor_position += b.document.get_start_of_line_position(
163 after_whitespace=True
164 )
167def scroll_page_up(event: E) -> None:
168 """
169 Scroll page up. (Prefer the cursor at the bottom of the page, after scrolling.)
170 """
171 w = event.app.layout.current_window
172 b = event.app.current_buffer
174 if w and w.render_info:
175 # Put cursor at the first visible line. (But make sure that the cursor
176 # moves at least one line up.)
177 line_index = max(
178 0,
179 min(w.render_info.first_visible_line(), b.document.cursor_position_row - 1),
180 )
182 b.cursor_position = b.document.translate_row_col_to_index(line_index, 0)
183 b.cursor_position += b.document.get_start_of_line_position(
184 after_whitespace=True
185 )
187 # Set the scroll offset. We can safely set it to zero; the Window will
188 # make sure that it scrolls at least until the cursor becomes visible.
189 w.vertical_scroll = 0