Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/rich/live_render.py: 34%

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

50 statements  

1import sys 

2from typing import Optional, Tuple 

3 

4if sys.version_info >= (3, 8): 

5 from typing import Literal 

6else: 

7 from typing_extensions import Literal # pragma: no cover 

8 

9 

10from ._loop import loop_last 

11from .console import Console, ConsoleOptions, RenderableType, RenderResult 

12from .control import Control 

13from .segment import ControlType, Segment 

14from .style import StyleType 

15from .text import Text 

16 

17VerticalOverflowMethod = Literal["crop", "ellipsis", "visible"] 

18 

19 

20class LiveRender: 

21 """Creates a renderable that may be updated. 

22 

23 Args: 

24 renderable (RenderableType): Any renderable object. 

25 style (StyleType, optional): An optional style to apply to the renderable. Defaults to "". 

26 """ 

27 

28 def __init__( 

29 self, 

30 renderable: RenderableType, 

31 style: StyleType = "", 

32 vertical_overflow: VerticalOverflowMethod = "ellipsis", 

33 ) -> None: 

34 self.renderable = renderable 

35 self.style = style 

36 self.vertical_overflow = vertical_overflow 

37 self._shape: Optional[Tuple[int, int]] = None 

38 

39 def set_renderable(self, renderable: RenderableType) -> None: 

40 """Set a new renderable. 

41 

42 Args: 

43 renderable (RenderableType): Any renderable object, including str. 

44 """ 

45 self.renderable = renderable 

46 

47 def position_cursor(self) -> Control: 

48 """Get control codes to move cursor to beginning of live render. 

49 

50 Returns: 

51 Control: A control instance that may be printed. 

52 """ 

53 if self._shape is not None: 

54 _, height = self._shape 

55 return Control( 

56 ControlType.CARRIAGE_RETURN, 

57 (ControlType.ERASE_IN_LINE, 2), 

58 *( 

59 ( 

60 (ControlType.CURSOR_UP, 1), 

61 (ControlType.ERASE_IN_LINE, 2), 

62 ) 

63 * (height - 1) 

64 ) 

65 ) 

66 return Control() 

67 

68 def restore_cursor(self) -> Control: 

69 """Get control codes to clear the render and restore the cursor to its previous position. 

70 

71 Returns: 

72 Control: A Control instance that may be printed. 

73 """ 

74 if self._shape is not None: 

75 _, height = self._shape 

76 return Control( 

77 ControlType.CARRIAGE_RETURN, 

78 *((ControlType.CURSOR_UP, 1), (ControlType.ERASE_IN_LINE, 2)) * height 

79 ) 

80 return Control() 

81 

82 def __rich_console__( 

83 self, console: Console, options: ConsoleOptions 

84 ) -> RenderResult: 

85 renderable = self.renderable 

86 style = console.get_style(self.style) 

87 lines = console.render_lines(renderable, options, style=style, pad=False) 

88 shape = Segment.get_shape(lines) 

89 

90 _, height = shape 

91 if height > options.size.height: 

92 if self.vertical_overflow == "crop": 

93 lines = lines[: options.size.height] 

94 shape = Segment.get_shape(lines) 

95 elif self.vertical_overflow == "ellipsis": 

96 lines = lines[: (options.size.height - 1)] 

97 overflow_text = Text( 

98 "...", 

99 overflow="crop", 

100 justify="center", 

101 end="", 

102 style="live.ellipsis", 

103 ) 

104 lines.append(list(console.render(overflow_text))) 

105 shape = Segment.get_shape(lines) 

106 self._shape = shape 

107 

108 new_line = Segment.line() 

109 for last, line in loop_last(lines): 

110 yield from line 

111 if not last: 

112 yield new_line