SpanIndex keeps a sorted list of entries, each associated with a span. It can retrieve elements by aggregated span as well as their position in the list.
The editor always performs the more efficient row scan. This single-row-fetching method is actually only used in tests right now, but I see no reason to eliminate it, since it's just a convenience for retrieving a single row from the row scanning method.
For now it's not an efficient implementation… just sketching it into place. I want to move to using row ranges instead of individual rows because it will be more efficient than iterating over and over again to each individual row.
I *think* this is a good idea. It makes us more consistent in always passing around ScreenLine instances. We'll be able to put nice metadata on these objects, like the buffer line they correspond to etc.
ScreenLine encapsulates the idea of a single line on screen. ScreenLines are first generated by the highlighter. A ScreenLine contains tokens and text, and currently has a method called splitAt which the LineWrapper, and soon the LineFolder, use to fragment the line.
We consider the line as a whole string and decide where we want to
split it before working with tokens. findSplitColumn just looks at the
character at the boundary... if it's a whitespace it looks forward for
a word. If it's not whitespace it looks backward for whitespace. This
ensures we always break on whitespace boundaries if possible.
Basically... splitTokens will never put whitespace at the beginning of
wrapped display line. It also splits tokens without regard for
whitespace if the token has no whitespace but is too wide to display on
a single line.
If we detect leading whitespace, we replace the next token with the
result of splitting the next token into two tokens, one containing any
leading whitespace and one with the rest. Then the leading whitespace
is added to the current line. When the second half of the split is
processed, it no longer has leading whitespace and is split to the next
line.