contour
contour copied to clipboard
Dynamically manage the scrollback buffer and remove (prompt, output) blocks atomically
More complex alternative of #835.
Abstract
Currently the scrollback buffer size is an explicit hard limit, which means that in case multiple long commands exceed the limit, the top of the buffer is cleared, potentially resulting in one command's output being cleared partially. Instead, if the shell integration is enabled and Contour has tracked where the prompts are in the scrollback, the clearing should be done for one atomic unit of executed command-line, not in a way that it "cuts" the history in the "middle".
Motivation
C++ SFINAE outputs.
Specification
- If Contour does not detect prompt markers in the VT buffer, this feature should be skipped due to unreliable output.
history.limitshould have asoftand ahardkey.- Assume that
X,Y,Zandαare prompt markers, in the presented order, with the following constraints:Xis the line where the oldest visible prompt is now beyond thesoftlimit,Yis the second oldest, beyond thesoftlimit, andZis a prompt still visible after a hypothetical clearing (so it's line is between(-∞, Soft))αis a prompt that is newer thanZ.
- The range
[X, Y)should be cleared (as it exceeded the requested history size), but[Y, Z)should not.- Current behaviour:
[X, Soft]is cleared, and only(Soft, Z]and[Z, ∞)remain. - This should happen even if all the remaining scrollback buffer would not be exactly the requested history size.
- Current behaviour:
- Once
Zreaches thesoftlimit and the entire range[Z, α)is beyond thesoftlimit, the entire range is cleared. - The
hardlimit should be there to prevent memory overflows. It could be user-configurable, with twice thesoftlimit being a good default. If thehardlimit is reached, lines are cleared no matter what.
Expected outcome: as long as the terminal does not exceed the hard limit, the oldest line in the scrollback buffer is a proper prompt, with the full output of said command.
After some conversations... this actually sounds like we want something similar towards the Blocks feature that also comes with Warp. Except that this ticket's request only cares about proper eviction of prompt + output rather than cutting it off in the middle.
The question I am having is how to implement it without severely sacrificing performance. The grid buffer (scrollback + main page area) is currently actually a ring buffer of lines.
We could design a double-layer principle where we still have that ring buffer for the current block to be constructed (if integration provides that meta data) and whenever a block is completed, it's then promoted into another data structure that keeps the historic blocks. for convenient rendering, viewport jumping actions through the scrollback and atomic eviction.
EDIT: The cool thing about this solution is (or should be) that users could still have commands with huge output (like cat 4gb.txt which would all go into a single block, not evicting older blocks, but actually truncating this block's history instead. That sounds like useful to me (not necessarily to everyone).