Expand description
Visual Line implementation
Files are easily broken up into buffer lines by just splitting on \n or \r\n.
However, editors require features like wrapping and multiline phantom text. These break the
nice one-to-one correspondence between buffer lines and visual lines.
When rendering with those, we have to display based on visual lines rather than the underlying buffer lines. As well, it is expected for interaction - like movement and clicking - to work in a similar intuitive manner as it would be if there was no wrapping or phantom text. Ex: Moving down a line should move to the next visual line, not the next buffer line by default. (Sometimes! Some vim defaults are to move to the next buffer line, or there might be other differences)
There’s two types of ways of talking about Visual Lines:
VLine: Variables are often written withvlinein the nameRVLine: Variables are often written withrvlinein the name
VLine is an absolute visual line within the file. This is useful for some positioning tasks
but is more expensive to calculate due to the nontriviality of the buffer line <-> visual line
conversion when the file has any wrapping or multiline phantom text.
Typically, code should prefer to use RVLine. This simply stores the underlying
buffer line, and a line index. This is not enough for absolute positioning within the display,
but it is enough for most other things (like movement). This is easier to calculate since it
only needs to find the right (potentially wrapped or multiline) layout for the easy-to-work
with buffer line.
VLine is a single usize internally which can be multiplied by the line-height to get the
absolute position. This means that it is not stable across text layouts being changed.
An RVLine holds the buffer line and the ‘line index’ within the layout. The line index
would be 0 for the first line, 1 if it is on the second wrapped line, etc. This is more
stable across text layouts being changed, as it is only relative to a specific line.
Lines is the main structure. It is responsible for holding the text layouts, as well as
providing the functions to convert between (r)vlines and buffer lines.
Many of Lines functions are passed a TextLayoutProvider.
This serves the dual-purpose of giving us the text of the underlying file, as well as
for constructing the text layouts that we use for rendering.
Having a trait that is passed in simplifies the logic, since the caller is the one who tracks
the text in whatever manner they chose.
Structs§
- Config
Id - Lines
- The main structure for tracking visual line information.
- RVLine
- A visual line relative to some other line within the editor view.
- Text
Layout Cache - VLine
- A line within the editor view.
- VLine
Info - Information about the visual line and how it relates to the underlying buffer line.
Enums§
- Layout
Event - Layout events
- Resolved
Wrap
Traits§
- Line
Font Size Provider - Text
Layout Provider - The
TextLayoutProviderserves two primary roles:
Type Aliases§
- Font
Size Cache Id - Layouts
- (Font Size -> (Buffer Line Number -> Text Layout))