BufferLine rewrite [WIP]
This PR implements #4800. It also sort-of implements #4232 - it does reflow lazily, though it doesn't specifically use the "idle callbacks". Motivation is described in #4800; however, the implementation is different (though the same basic idea).
The NewBufferLine implementation is enabled if the newBufferLine option is true; otherwise the old implementation (renamed to OldBufferLine) is used. The goal is to merge the PR with newBufferLine defaulting to false to avoid breaking things, but allowing adventurous users and developers to try newBufferLine set to true. (Some more testing will be needed even for the newBufferLine false case; I believe there are regressions.)
Note that NewBufferLine is abstract and has two implementation classes:
-
LogicalBufferLinerepresents an unwrapped line, but it also contains the data for following wrapped lines. -
WrappedBufferLinerepresents a wrapped line (duh) and basically just indirects to the previousLogicalBufferLine.
Operations that are O(1) in OldBufferLine may require linear scanning in NewBufferLine. However, LogicalBufferLine has a cache (mapping column index to _data array index) to avoid linear scanning for common operations. There is some needless overhead in the interest of minimizing API changes.
Later, the newBufferLine default will change to true. Later still, we will remove the support for OldBufferLine and NewBufferLine will be renamed to plain BufferLine.
The AbstractBufferLine class is intended as a parent for both [New]BufferLine and future classes for "other" content. Specifically, general HTML "paragraphs" (<div> elements) are planned.
Tasks that must be done before merger:
- [ ] Fix any
oldBufferLineregressions. (Minor barely-measurable performance regressions may be OK.) - [ ] Update or replace any commented-out testcases.
- [ ] Fix remaining lint regressions. Note this issue.
- [ ] ...
Tasks that must be done before defaulting to newBufferLine true:
- [ ] Fix all testsuite regressions (at least all that may be in real usage).
- [ ]
IExtendedAttrshandling is incomplete (though basic data structure support is there). - [ ] The
imageaddon doesn't work. It uses custom classes that textually copy the old classes. - [ ] Fix at least noticeable performance regressions, if any.
- [ ] Evaluate any FIXME comments in the code.
- [ ] ...
The current buffer-cell-cursor branch supports both the old BufferLine structure (as OldBufferLine) and the new data structure (as NewBufferLine). They can selected at runtime based on the USE_NewBufferLine variable. See this note based on a request from Tyriar and follow-up discussion.
I now believe the disadvantages of run-time switching outweighs the benefits. A big problem is it makes it more difficult to understand and modify the code. It makes it more difficult to compare with master. And I think it makes it easier for changes in master to silently update the OldBufferLine logic without noticing that the NewBufferLine logic also needs to be changed. Similarly, if/when the code is merged into master, having two implementation makes it harder to understand, and it will be too easy for people to just modify OldBufferLine or NewBufferLine without updating both.
So I plan to sooner rather than later rip out all code to support OldBufferLine logic, unless I hear strong disagreement.
(Lately I've been focusing on other things, primarily construction expanding our house in Hayward. However, I'm spending a bit more time on xterm.js now.)
I went ahead and removed the code to support the old BufferLine data structure. That made things cleaner and simpler.