Files
ghostty-rs/docs/rewrite/notes/ghostty-terminal-pagelist-requests.md
T
ddidderr 677683b740 refactor(terminal): wire kitty graphics and drop PageList workarounds
Integration pass over the terminal core (Codex/gpt-6-astra, reviewed):
- Screen now owns the real kitty ImageStorage; new/reset/teardown,
  erase-display deletes and alternate-screen limit inheritance hook in
  where Zig does, and Terminal implements ExecTerminal so kitty APC
  commands execute against it. Exec tests use a real Terminal.
- The PageList gains the APIs Screen/Terminal needed (pin iterators,
  cross-page row/partial-row clone, string allocator probing, dedup
  before allocating hyperlinks, Top viewport fixup after erase, append_
  grapheme no longer marking rows dirty), and the Screen/Terminal
  workarounds for their absence are removed so the code mirrors Zig.

Public signatures are unchanged; downstream crates build as before.

Test Plan:
- cargo test -p ghostty-terminal (1252 passed, 0 ignored)
- cargo clippy -p ghostty-terminal --all-targets -- -D warnings
2026-10-11 22:57:35 +02:00

63 lines
3.8 KiB
Markdown

# Requests for page.rs / page_list.rs (from the Screen port)
All requests resolved and verified in the 2026-10-11 integration pass.
1. **Resolved — pin-based iterators.** `Pin::{row_iterator, cell_iterator,
page_iterator, prompt_iterator}` take the owning `&PageList`, direction, and
an inclusive optional limit pin. Limits apply to whole rows; cell iteration
begins at the starting column. Construction uses pins directly, without
point conversion or a list scan. Screen, Terminal, and Selection use these
methods. Public `pin_iter` functions/types remain as compatibility wrappers.
2. **Resolved — tracked-pin restoration.** `set_tracked_pin` validates the
handle and node lifetime, allowing a temporarily out-of-range row during
split recovery. Screen restores the exact old pin, with no clamped stand-in.
Cursor dirtying accesses the still-allocated row, matching Zig's cached
`page_row`. The maximum-style page-split regression passes.
3. **Resolved — cross-page row clone.** `PageList::clone_row_between(src, dst)`
borrows the two pages directly and calls `Page::clone_row_from`. Screen's
export/import row snapshot helper is removed.
4. **Resolved — string allocation and hyperlink deduplication.** Screen probes
`Page::can_allocate_string` before capacity growth in `cursor_set_hyperlink`,
following Zig's string-growth/hyperlink-growth/retry order. The probe frees
its temporary reservation in Rust; the page is then rebuilt. The cursor-link
recovery workaround is removed. `insert_hyperlink` retains existing live
entries before allocating strings; a full-allocator regression covers this.
5. **Resolved — Top viewport after erasure.** `fixup_viewport` handles `Top`
inside PageList; Screen has no viewport fixup. Resize still only fixes a
pinned viewport, preserving Zig's `Top` behavior (covered by the existing
resize-no-reflow-more-rows-contains-viewport test).
6. **Verified resolved — trailing blank rows during resize.** All three tests
are enabled and pass: `screen_resize_no_reflow_less_rows_trims_blank_lines`,
`screen_resize_less_cols_with_reflow_but_row_space`, and
`screen_resize_less_cols_to_wrap_wide_char`.
7. **Resolved — reset/erase error handling.** Existing public `Result` signatures
remain for backwards compatibility. Erasing empty history is a successful
no-op. Screen's extra history guard and error swallowing are removed;
valid internal erasure/reset calls assert success as in Zig.
- **Verified resolved (T3/p4):** `erase_row_bounded` clears the blanked row's
managed flags; `terminal_index_bottom_of_scroll_region_clear_hyperlinks`
is enabled and passes.
- **Verified resolved (T3/p8):** pending-wrap reflow retains the correct active
rows; `terminal_resize_with_wraparound_on` is enabled and passes.
- **Resolved (T3/p1):** `set_graphemes` and `append_grapheme` preserve row dirty
state, including allocation growth. Terminal's save/restore workaround is
removed; the VS16 test and a direct append regression pass.
- **Resolved (T3/terminal):** `PageList::clone_partial_row_between(src, dst,
left, right)` directly borrows distinct pages and delegates managed-memory
and row-metadata handling to `Page::clone_partial_row_from`. Terminal's
export/import implementation is removed. The regression checks graphemes,
hyperlinks, untouched columns, dirty/wrap flags, and Kitty placeholder flags.
## API changes
Additive methods: the four Pin iterators and both PageList row-copy helpers.
Existing iterator wrappers and `Result` signatures are retained. No downstream
caller edits were needed.
## Validation
`cargo test -p ghostty-terminal`: 1252 unit tests and 1 documentation test pass,
0 failed, 0 ignored. Clippy with `-D warnings`, rustfmt, and the combined build
of `ghostty-font`, `ghostty-renderer`, and `ghostty-termio` pass.