It was causing the entire last line to be re-scanned to find the
cursor drawing position if the cursor was at the end of the buffer.
This was both slow and resulted in an incorrect position, since
all the rest of the drawing assumes line blocks.
They were two pretty much identical bugs in both index_offset_vertical_v2d()
and index_set_horizontal_v2d(). Neither method was checking for slipping
off the end of a line block.
The prior version worked fine for the typical single insertion/removal
cases. But when larger imbalances happened due to bulk insertion or
removal it wouldn't work correctly.
The new improved version works on any tree whose children are themselves
balanced, even if they are extremely different heights when compared to
each other. It works in O(log N) time.
It doesn't use an intermediate conversion to a string anymore, and should
execute in O(log N) as long as the right-hand rope is equal length or
smaller than the left.
It may also be O(log N) for the left-hand rope being smaller, but that
depends on whether the rebalance code executes in O(log N) time when
the left and right hand side are individually balanced. I haven't
analysed it yet, so dunno.
Very slightly favor larger indentations, instead of very slight favor
smaller indentations. This is more likely to do the right thing on
very small files.
The formatters now work on grapheme iterators instead of directly on
lines, which frees up the LineFormatter to break up long lines into
smaller blocks of text. This is partially taken advantage of right
now in various parts of the code, but more work is still needed to
get it both working properly and fast.
The rope uses a large leaf-node text length, so in the vast majority of
cases this ends up being the same as directly storing the string data.
But in the case that the line becomes extremely long, this will allow
for reasonable performance
This is a big shift in the formatter API's. It simplifies the
responsibilities of the implementers so that pretty much all they
have to do it implement an iterator. Everything else will be
automatically derived from that. (Or, at least, that's the hope.)