Add resize reflow for the normal buffer#12
Open
buchmiet wants to merge 1 commit into
Open
Conversation
buchmiet
force-pushed
the
feature/reflow
branch
2 times, most recently
from
July 23, 2026 23:15
4c889d5 to
6fc6366
Compare
Ports xterm.js 5.5.0 resize reflow (BufferReflow.ts and the reflow orchestration in Buffer.ts) into XTerm.NET. Shrinking the column count now re-wraps long logical lines onto additional IsWrapped rows instead of truncating them; growing merges wrapped groups back upward. The alternate buffer is excluded via an explicit hasScrollback: false flag, matching xterm.js, so full-screen applications keep repainting themselves. Also fixes an independent latent bug: when the buffer was at capacity and the row count shrank, CircularList.Resize ran before any trimming and kept the oldest lines, silently discarding the bottom of the live screen including the cursor row. Resize now trims from the top (raising Trimmed) before shrinking capacity. Ported from xterm.js, (c) The xterm.js authors, MIT.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resize reflow for the normal buffer
Problem
XTerm.NET truncated every line independently on column shrink. Growing the window back did not restore wrapped content — long lines stayed cut at the narrowest width reached. Scrollback lines were lost silently when the buffer was at capacity and row count shrank.
Semantics
Ported from xterm.js 5.5.0 (MIT):
IsWrappedrows; no content is lost.hasScrollback: true). The alternate buffer uses explicithasScrollback: falseand keeps truncation behaviour.NormalLineAttribute(DECDWL/DECDHL) are excluded from reflow.Trimmed(n)is raised when reflow removes rows from the top (selection anchoring).SavedCursorState.Yis adjusted on trim, matching xterm.jssavedYhandling.The cursor line is deliberately not reflowed
Wrapped groups containing the cursor row are skipped in both directions, matching xterm.js — the running application is expected to redraw its current line on
SIGWINCH.This is worth knowing before testing by hand, because it is the first thing a reviewer is likely to try. Writing a long line and resizing immediately, with no application attached to redraw, leaves that line truncated while every other line round-trips intact. Moving the cursor off the line first (a trailing newline) shows the reflow working as intended: a 69-character line at 60 columns survives a 60 → 30 → 60 round trip byte for byte.
Provenance
Faithful port of:
src/common/buffer/BufferReflow.tssrc/common/buffer/Buffer.ts(resize,_reflow,_reflowLarger,_reflowSmaller,_reflowLargerAdjustViewport)BufferReflow.test.tsand reflowdescribeblocks inBuffer.test.tsCopyright (c) The xterm.js authors, MIT License.
Latent bug fix (independent)
When
Length == MaxLengthand rows shrink, the old code calledCircularList.Resizefirst, which kept the oldest entries and discarded the live screen bottom (including the cursor line). Resize now trims from the top (TrimStart+Trimmed) before shrinking capacity.Test coverage
BufferReflowTests.cs— pure-function port (reflowSmallerGetNewLineLengths, wide chars, null tail cells)BufferTests.cs— integration reflow cases (wrap/unwrap, wide chars in both directions, cursor,Trimmed,LineAttributeskip, alt buffer, capacity-shrink regression, wrapped group ending at the last buffer row)ConPTY note
xterm.js disables reflow under
windowsMode/windowsPtybecause ConPTY re-wraps the viewport. This port is unconditional — scrollback truncation is the visible defect either way, and non-ConPTY streams (SSH) benefit most. AwindowsPty-style toggle may be worth a follow-up; not included here.Files changed
src/XTerm.NET/Buffer/BufferReflow.cs(new)src/XTerm.NET/Buffer/TerminalBuffer.cs—Resizerestructure, reflow orchestration,hasScrollbackconstructor flagsrc/XTerm.NET/Buffer/BufferLine.cs—GetWidth,HasContent,ReplaceCells;GetTrimmedLengthwide-char fixsrc/XTerm.NET/Buffer/CircularList.cs—SetLengthfor reflow batchingsrc/XTerm.NET/Terminal.cs— alt bufferhasScrollback: falsesrc/XTerm.NET.Tests/Buffer/BufferReflowTests.cs(new)src/XTerm.NET.Tests/Buffer/BufferTests.cs— reflow integration testsFIXES.md— entry for this change