3636 process_prompt as build_prompt_content ,
3737)
3838from .layout import LayoutMap , LayoutResult , LayoutRow , WrappedRow , layout_content_lines
39- from .render import RenderCell , RenderLine , RenderedScreen , StyleRef
39+ from .render import RenderCell , RenderLine , RenderedScreen , ScreenOverlay , StyleRef
4040from .utils import ANSI_ESCAPE_SEQUENCE , wlen , gen_colors
4141from .trace import trace
4242
@@ -380,7 +380,7 @@ def collect_keymap(self) -> tuple[tuple[KeySpec, CommandName], ...]:
380380 return default_keymap
381381
382382 def calc_screen (self ) -> RenderedScreen :
383- """Translate changes in self. buffer into a structured rendered screen."""
383+ """Translate the editable buffer into a base rendered screen."""
384384 num_common_lines = 0
385385 offset = 0
386386 if self .last_refresh_cache .valid (self ):
@@ -427,12 +427,7 @@ def calc_screen(self) -> RenderedScreen:
427427 layout_rows ,
428428 last_refresh_line_end_offsets ,
429429 )
430-
431- render_lines = base_render_lines .copy ()
432- render_lines .extend (self ._render_message_lines ())
433-
434- self .rendered_screen = RenderedScreen (tuple (render_lines ), self .cxy )
435- return self .rendered_screen
430+ return RenderedScreen (tuple (base_render_lines ), self .cxy )
436431
437432 def _buffer_refresh_from_pos (self ) -> int | None :
438433 buffer_from_pos = self .invalidation .buffer_rebuild_from_pos
@@ -536,9 +531,9 @@ def _render_wrapped_rows(
536531 for row in wrapped_rows
537532 ]
538533
539- def _render_message_lines (self ) -> list [RenderLine ]:
534+ def _render_message_lines (self ) -> tuple [RenderLine , ... ]:
540535 if not self .msg :
541- return []
536+ return ()
542537 width = self .console .width
543538 render_lines : list [RenderLine ] = []
544539 for message_line in self .msg .split ("\n " ):
@@ -551,7 +546,19 @@ def _render_message_lines(self) -> list[RenderLine]:
551546 render_lines .append (
552547 RenderLine .from_rendered_text (message_line [offset : offset + width ])
553548 )
554- return render_lines
549+ return tuple (render_lines )
550+
551+ def get_screen_overlays (self ) -> tuple [ScreenOverlay , ...]:
552+ return ()
553+
554+ def compose_rendered_screen (self , base_screen : RenderedScreen ) -> RenderedScreen :
555+ overlays = list (self .get_screen_overlays ())
556+ message_lines = self ._render_message_lines ()
557+ if message_lines :
558+ overlays .append (ScreenOverlay (len (base_screen .lines ), message_lines ))
559+ if not overlays :
560+ return base_screen
561+ return RenderedScreen (base_screen .lines , base_screen .cursor , tuple (overlays ))
555562
556563 def _render_line (
557564 self ,
@@ -763,7 +770,8 @@ def prepare(self) -> None:
763770 self .rendered_screen = RenderedScreen .empty ()
764771 self .invalidate_full ()
765772 self .last_command = None
766- self .calc_screen ()
773+ base_screen = self .calc_screen ()
774+ self .rendered_screen = self .compose_rendered_screen (base_screen )
767775 except BaseException :
768776 self .restore ()
769777 raise
@@ -821,7 +829,9 @@ def update_screen(self) -> None:
821829 def refresh (self ) -> None :
822830 """Recalculate and refresh the screen."""
823831 # this call sets up self.cxy, so call it first.
824- rendered_screen = self .calc_screen ()
832+ base_screen = self .calc_screen ()
833+ rendered_screen = self .compose_rendered_screen (base_screen )
834+ self .rendered_screen = rendered_screen
825835 trace (
826836 "reader.refresh cursor={cursor} lines={lines} "
827837 "dims=({width},{height}) invalidation={invalidation}" ,
0 commit comments