The rendering flow — prompt_toolkit 3.0.50 documentation (original) (raw)
- Start
- Advanced topics
- The rendering flow
Understanding the rendering flow is important for understanding howContainer andUIControl objects interact. We will demonstrate it by explaining the flow around aBufferControl.
Note
A BufferControl is aUIControl for displaying the content of aBuffer. A buffer is the object that holds any editable region of text. Like all controls, it has to be wrapped into aWindow.
Let’s take the following code:
from prompt_toolkit.enums import DEFAULT_BUFFER from prompt_toolkit.layout.containers import Window from prompt_toolkit.layout.controls import BufferControl from prompt_toolkit.buffer import Buffer
b = Buffer(name=DEFAULT_BUFFER) Window(content=BufferControl(buffer=b))
What happens when a Renderer objects wants aContainer to be rendered on a certainScreen?
The visualization happens in several steps:
- The Renderer calls thewrite_to_screen() method of a Container. This is a request to paint the layout in a rectangle of a certain size.
The Window object then requests the UIControl to create aUIContent instance (by callingcreate_content()). The user control receives the dimensions of the window, but can still decide to create more or less content.
Inside the create_content()method of UIControl, there are several steps:- First, the buffer’s text is passed to thelex_document() method of aLexer. This returns a function which for a given line number, returns a “formatted text list” for that line (that’s a list of
(style_string, text)
tuples). - This list is passed through a list ofProcessor objects. Each processor can do a transformation for each line. (For instance, they can insert or replace some text, highlight the selection or search string, etc…)
- The UIControl returns aUIContent instance which generates such a token lists for each lines.
- First, the buffer’s text is passed to thelex_document() method of aLexer. This returns a function which for a given line number, returns a “formatted text list” for that line (that’s a list of
The Window receives theUIContent and then:
- It calculates the horizontal and vertical scrolling, if applicable (if the content would take more space than what is available).
- The content is copied to the correct absolute positionScreen, as requested by theRenderer. While doing this, theWindow can possible wrap the lines, if line wrapping was configured.
Note that this process is lazy: if a certain line is not displayed in theWindow, then it is not requested from the UIContent. And from there, the line is not passed through the processors or even asked from theLexer.