There are scenarios where this configuration looks bad. This commit
introduces some heuristics to prevent it. Here are the heuristics:
* Extension is always enabled on alt screen.
* Extension is disabled if a row contains any default bg color. The
thinking is that in this scenario, using the default bg color looks
just fine.
* Extension is disabled if a row is marked as a prompt (using semantic
prompt sequences). The thinking here is that prompts often contain
perfect fit glyphs such as Powerline glyphs and those look bad when
extended.
This introduces some CPU cost to the extension feature but it should be
minimal and respects dirty tracking. This is unfortunate but the feature
makes many terminal scenarios look much better and the performance cost
is minimal so I believe it is worth it.
Further heuristics are likely warranted but this should be a good
starting set.
Fixes#1990
This fixes and adds a unit test for an edge case where when printing
over the same cell with the same hyperlink ID, we were unsetting the
cell hyperlink state.
This commit also adds a number of integrity checks to verify hyperlinks
remain in a consistent state.
Fixes#1991
To check if a hyperlink from another page is already present in our
page's set, we need to dupe the hyperlink struct. If the hyperlink is
already present in our page, this dupe is a waste and is freed.
In the case where the hyperlink is present AND we don't have enough
memory to dupe the hyperlink to check if its present, we'd previous
simply crash out and fail rendering. Debug builds would crash with
integrity errors.
This commit resolves the issue by falling back to a slow path when our
string allocation table is full and iterating over the hyperlink map to
check one by one if we have the hyperlink. This O(N) is much slower than
allocating (in this case) but N is usually low on top of this case being
rare.
A better solution would probably be to ensure we always have some % of
available space free in our string allocation table. This would result
in some wasteful page reallocs but would speed up the render loop. We
can look into that later.
Two bugs:
1. If our pin is the top page, and self.y == top.y, then x will tell us
the answer. Before, we'd fall through.
2. If our pin is not the top or bottom, but the top == bottom, then we
can't possibly be between. Before, we'd incorrectly check the linked
list starting AFTER top.
OSC 133 defines distinct continuation (c) and secondary (s) prompt
kinds. They're both treated as prompt continuations but have different
semantic meanings: `c` allows the user to "go back" and edit previous
lines, while `s` does not.
We don't (yet) handle this "editable" distinction, but this change makes
our OSC parser slightly more correct.