Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/rich/live_render.py: 31%
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
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
1from typing import Literal, Optional, Tuple
3from ._loop import loop_last
4from .console import Console, ConsoleOptions, RenderableType, RenderResult
5from .control import Control
6from .segment import ControlType, Segment
7from .style import StyleType
8from .text import Text
10VerticalOverflowMethod = Literal["crop", "ellipsis", "visible"]
13class LiveRender:
14 """Creates a renderable that may be updated.
16 Args:
17 renderable (RenderableType): Any renderable object.
18 style (StyleType, optional): An optional style to apply to the renderable. Defaults to "".
19 """
21 def __init__(
22 self,
23 renderable: RenderableType,
24 style: StyleType = "",
25 vertical_overflow: VerticalOverflowMethod = "ellipsis",
26 ) -> None:
27 self.renderable = renderable
28 self.style = style
29 self.vertical_overflow = vertical_overflow
30 self._shape: Optional[Tuple[int, int]] = None
32 @property
33 def last_render_height(self) -> int:
34 """The number of lines in the last render (may be 0 if nothing was rendered).
36 Returns:
37 Height in lines
38 """
39 if self._shape is None:
40 return 0
41 return self._shape[1]
43 def set_renderable(self, renderable: RenderableType) -> None:
44 """Set a new renderable.
46 Args:
47 renderable (RenderableType): Any renderable object, including str.
48 """
49 self.renderable = renderable
51 def position_cursor(self) -> Control:
52 """Get control codes to move cursor to beginning of live render.
54 Returns:
55 Control: A control instance that may be printed.
56 """
57 if self._shape is not None:
58 _, height = self._shape
59 return Control(
60 ControlType.CARRIAGE_RETURN,
61 (ControlType.ERASE_IN_LINE, 2),
62 *(
63 (
64 (ControlType.CURSOR_UP, 1),
65 (ControlType.ERASE_IN_LINE, 2),
66 )
67 * (height - 1)
68 )
69 )
70 return Control()
72 def restore_cursor(self) -> Control:
73 """Get control codes to clear the render and restore the cursor to its previous position.
75 Returns:
76 Control: A Control instance that may be printed.
77 """
78 if self._shape is not None:
79 _, height = self._shape
80 return Control(
81 ControlType.CARRIAGE_RETURN,
82 *((ControlType.CURSOR_UP, 1), (ControlType.ERASE_IN_LINE, 2)) * height
83 )
84 return Control()
86 def __rich_console__(
87 self, console: Console, options: ConsoleOptions
88 ) -> RenderResult:
89 renderable = self.renderable
90 style = console.get_style(self.style)
91 lines = console.render_lines(renderable, options, style=style, pad=False)
92 shape = Segment.get_shape(lines)
94 _, height = shape
95 if height > options.size.height:
96 if self.vertical_overflow == "crop":
97 lines = lines[: options.size.height]
98 shape = Segment.get_shape(lines)
99 elif self.vertical_overflow == "ellipsis":
100 lines = lines[: (options.size.height - 1)]
101 overflow_text = Text(
102 "...",
103 overflow="crop",
104 justify="center",
105 end="",
106 style="live.ellipsis",
107 )
108 lines.append(list(console.render(overflow_text)))
109 shape = Segment.get_shape(lines)
110 self._shape = shape
112 new_line = Segment.line()
113 for last, line in loop_last(lines):
114 yield from line
115 if not last:
116 yield new_line