attach markers and decorations to LogicalLine#5853
Conversation
Instead to change isWrapped state use a Buffer.setWrapped method. This allows for potential flexibility in how BufferLine and line-wrapping are implemented.
A BufferLine is now the sub-range of a LogicalLine for a specific visible line, while LogicalLine is independent of window width.
|
It is probably possible to make a variation of this idea, but attach the Marker list to BufferLine, without the PR #5797 LogicalLine changes. However, that would complicate some other things, most notably buffer resize. You would need to maintain the invariant that for a marker You probably do want a Marker to have a column number, either way. |
Main thing is changing soe the CircularList's onTrim emitter gets called while lines are in the list, which means clearMarkers can be used. This complicates the slice function a bit.
Added LogicalLine.forEachMarker.
|
Merged from upstream/master. |
Other cleanups and improvements.
Add logical() accessor method. This makes _logicalLine not be enumerable, which should fix JSON cycles.
|
Merged in commit from PR #5879 - it is needed to avoid acsessing no-longer available BufferLine internals. All tests now pass. |
This is a moderately large change as it combines a number of separate changes that depend on each other. I'm sorry about that; the net code increase is modest as lots of code has also been removed and simplified (and some comments have been added). Parts have been proposed as smaller changes; OTOH it might be more useful to see how it all comes together..
High-level overview:
BufferLineare moved to a new classLogicalLine. The latter represents a group of wrapped lines: The data in theLogicalLineis invariant when buffer width is changed; eachBufferLineis basically a sub-range of the parentLogicalLine. (See PR move _data from BufferLine to new LogicalLine class #5797.)LogicalLineinto multipleBufferLineparts. There are hooks for lazy reflow if that appears worthwhile.Markernow belongs to aLogicalLinefor the corresponding line. The marker does not have an explicit line number that needs to be updated when the buffer changes. (You can calculate the line number of a marker, but that requires a linear scan through the buffer, so should only be used for tests and debugging.)Markerhas a newpayloadfield. This has multiple uses; for now it is mainly used to map fromLogicalLinetoMarkertoDecoration. This allows us to replace the slowforEachDecorationAtCellby the much fasterforEachDecorationAtCellLinemethod. Specifically, this speeds up search tremendously. (See issue Search is too slow #5176.)ExtendedAttrsis likewise extended by apayloadfield. This allows a cleanup of theImageStoragelogic, including getting rid of theExtendedAttrsImageclass. (See PR Change image storage to use new ExtendedAttrs payload field #5879.)Planned follow-up work:
_urlIdfield fromExtendedAttrs, using thepayloadfield instead.MarkerandDecorationchanges. (See issue supporting shell integration #5807.) The priority is supporting click event in the input area. (See closed issue Look into supporting OSC 133 click_events #5670.) We can probably share some logic with the click handling for URLs.Old text
This is a work-in-progress / proof-of-concept of the idea of attaching Markers to the corresponding LogicalLine, and attaching Decorations to Markers. It is a follow-up to this idea, but this update does not use sub-classing of Markers through sub-classin.
This builds on PR #5797 - i.e. a LogicalLine contains the cell contents of a line assuming infinite screen width; a visible BufferLine becomes a sub-range of a LogicalLine.
Each LogicalLine points to a list (array or linked list) of Markers associated with the LogicalLine.
The Marker does not have a line number. Therefore, it does not need to be updated on a window resize. Getting the line number of a Marker becomes possible but expensive.
A Marker has an assocated column number. This is relative to the start of the LogicalLine (i.e. assuming an infinitely-wide terminal). Therefore the column position does not need to be updated on terminal resize.
There is no global list of Markers associated with a buffer. If you really need to iterate over all Markers, you iterate over all lines, then each Marker associated with the line.
The Marker object has an extra
payloadfield. This can be used to quickly access application-specific data, such as the associated Decoration, image data, OSC url, shell integration prompt data, etc. I previously assumed one would extend the Marker class with sub-classes (and that is still possible), but that would be too big an API change.We might consider getting rid of ExtendedAttrs and just using markers.
A Decoration is attached to a Marker, and can be accessed by the latter's
payloadfield.Instead of the expensive
forEachDecorationAtCellmetod we use the much cheaper newforEachDecorationAtCellLine(which should be renamed). I only updated the dom renderer, but the webgl renderer should be handled similarly.This provides a solution to issue #5176.
To do:
payloadfield.