Also rename from screenPositionFrom… to screenPositionFor… and rename allowEOL parameter (which defaults to false) to eagerWrap (which defaults to true).
If eagerWrap is true, the default, then a position at the end of a wrapped line will move to the next screen line. If it's false, it will hang on the end of the screen line. This support the line wrapper, which needs to convert ranges to not wrap (so selections can go to the end of wrapped lines) but otherwise needs to wrap the cursor to the beginning of a wrapped line.
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.