Module visual_line

Module visual_line 

Source
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 with vline in the name
  • RVLine: Variables are often written with rvline in 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§

ConfigId
Lines
The main structure for tracking visual line information.
RVLine
A visual line relative to some other line within the editor view.
TextLayoutCache
VLine
A line within the editor view.
VLineInfo
Information about the visual line and how it relates to the underlying buffer line.

Enums§

LayoutEvent
Layout events
ResolvedWrap

Traits§

LineFontSizeProvider
TextLayoutProvider
The TextLayoutProvider serves two primary roles:

Type Aliases§

FontSizeCacheId
Layouts
(Font Size -> (Buffer Line Number -> Text Layout))