feat(terminal): bring PageList to full parity with Ghostty

Second pass over the page memory model (done by Codex/gpt-6-astra in an
isolated worktree, reviewed and merged here):
- Resize/reflow now port Zig's incremental ReflowCursor algorithm with
  page backfill and the same capacity growth/split sequence, instead of
  rebuilding a snapshot, so page boundaries, pruning and tracked-pin
  remapping match Ghostty.
- Point<->pin conversion for the active area starts at the list tail and
  the viewport offset is cached, so hot-path operations no longer walk
  the whole scrollback from the head.
- RefCountedSet reproduces Zig's observable ID reuse and error points.
- All 202 PageList tests are ported (plus 13 extra regressions).

With this, the five Screen/Terminal tests previously ignored as blocked
on PageList behaviour pass and are re-enabled.

Test Plan:
- cargo test -p ghostty-terminal (913 passed, 0 ignored)
- cargo clippy -p ghostty-terminal --all-targets -- -D warnings
This commit is contained in:
ddidderr committed 2026-10-11 22:41:14 +02:00
1 parent e495ae72f1
commit ed7c644438
9 files changed
+4613 -1770

No files matched your search

@@ -211,7 +211,6 @@ fn bg_fill_rows(s: &mut Screen) {
}
#[test]
#[ignore = "pagelist: PageList::resize (no reflow, fewer rows) does not trim trailing rows that only contain background-color cells; the content row is pushed to history instead"]
fn screen_resize_no_reflow_less_rows_trims_blank_lines() {
let mut s = init(10, 3, 0);
let str = "1ABCD";
@@ -886,7 +885,6 @@ fn screen_resize_less_cols_no_reflow() {
}
#[test]
#[ignore = "pagelist: reflow keeps trailing blank rows (total_rows 4 > 3) instead of trimming them like Zig, pushing the first row into history"]
fn screen_resize_less_cols_with_reflow_but_row_space() {
let mut s = init(5, 3, 1);
let str = "1ABCD";
@@ -1141,7 +1139,6 @@ fn screen_resize_less_cols_to_eliminate_wide_char() {
}
#[test]
#[ignore = "pagelist: reflow keeps trailing blank rows, pushing the wrapped first row into history (erased by no_scrollback)"]
fn screen_resize_less_cols_to_wrap_wide_char() {
let mut s = init(3, 3, 0);
let str = "x😀";