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

1""" 

2Key bindings, for scrolling up and down through pages. 

3 

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 

9 

10from prompt_toolkit.key_binding.key_processor import KeyPressEvent 

11 

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] 

20 

21E = KeyPressEvent 

22 

23 

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 

30 

31 if w and w.render_info: 

32 info = w.render_info 

33 ui_content = info.ui_content 

34 

35 # Height to scroll. 

36 scroll_height = info.window_height 

37 if half: 

38 scroll_height //= 2 

39 

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) 

45 

46 if height + line_height < scroll_height: 

47 height += line_height 

48 y += 1 

49 else: 

50 break 

51 

52 b.cursor_position = b.document.translate_row_col_to_index(y, 0) 

53 

54 

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 

61 

62 if w and w.render_info: 

63 info = w.render_info 

64 

65 # Height to scroll. 

66 scroll_height = info.window_height 

67 if half: 

68 scroll_height //= 2 

69 

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) 

75 

76 if height + line_height < scroll_height: 

77 height += line_height 

78 y -= 1 

79 else: 

80 break 

81 

82 b.cursor_position = b.document.translate_row_col_to_index(y, 0) 

83 

84 

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) 

90 

91 

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) 

97 

98 

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 

105 

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 

110 

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() 

114 

115 w.vertical_scroll += 1 

116 

117 

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 

124 

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 

129 

130 if w.vertical_scroll > 0: 

131 first_line_height = info.get_height_for_line(info.first_visible_line()) 

132 

133 cursor_up = info.cursor_position.y - ( 

134 info.window_height 

135 - 1 

136 - first_line_height 

137 - info.configured_scroll_offsets.bottom 

138 ) 

139 

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() 

144 

145 # Scroll window 

146 w.vertical_scroll -= 1 

147 

148 

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 

155 

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 

160 

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 ) 

165 

166 

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 

173 

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 ) 

181 

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 ) 

186 

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