Ports ZIG/src/terminal/{Screen,ScreenSet,Tabstops,Selection}.zig on top
of the page/PageList layer. The cursor holds a TrackedPin; Zig's cached
page_row/page_cell pointers become accessor methods. Selection methods
take the PageList explicitly because tracked bounds are handles.
Screen tests use minimal plain-text dump/selection-string helpers that
follow the formatter's semantics; they will delegate to the real
formatter once formatter.zig is ported.
Gaps found in the PageList layer are recorded for the parity pass in
docs/rewrite/notes/ghostty-terminal-pagelist-requests.md; three resize
tests are #[ignore]d pending those fixes (PageList::resize keeps
trailing blank rows Zig drops). Kitty image storage and StringMap are
placeholders.
Test Plan:
- cargo test -p ghostty-terminal (443 passed, 3 ignored; Screen 183/184,
Selection 18/18, Tabstops 4/5 - skipped tests use allocator failure
injection)
1.8 KiB
1.8 KiB
Requests for page.rs / page_list.rs (from the Screen port)
- Pin-based iterators (Zig
PageList.zig~5100-5170):Pin::{row_iterator, cell_iterator, page_iterator, prompt_iterator}(direction, limit: Option<Pin>). The limit pin is inclusive and applies at row granularity. Screen uses a local copy inpin_iter.rs. PageList::set_tracked_pinvalidity: it rejects pins withy >= node.size.rows. Zig writes the pin raw;Screen::split_for_capacitytemporarily restores the cursor to the pre-split node, which may have shrunk. Worked around with a clamped stand-in.- Cross-page row clone: Zig
Page.cloneRowFrom(other_page, ...)between two nodes of one list needs two page borrows. Screen implements it withexport_cell/import_cell(Screen::clone_row_between). APageList::clone_row_between(src_pin, dst_pin)would be better. - String allocator probing:
Page.string_allocis private; ZigcursorSetHyperlinkprobes it before growing. Screen instead re-adds the cursor hyperlink afterincrease_capacity. Alsoinsert_hyperlinkallocates strings before checking set dedup, so near-full pages can fail needlessly. fixup_viewportmust handleViewport::Topaftererase_rows(Zig PageList.zig ~3043-3070). Worked around inScreen::erase_rows.- Resize reflow / no-reflow fewer rows must drop trailing blank rows, including rows holding only bg-color cells (Zig
resizeCols/resizeWithoutReflow). Three Screen tests are#[ignore = "pagelist: ..."]:screen_resize_no_reflow_less_rows_trims_blank_lines,screen_resize_less_cols_with_reflow_but_row_space,screen_resize_less_cols_to_wrap_wide_char. PageList::resetanderase_rowsreturnResult;erase_rowswith an empty history start point returnsInvalidCoordinate(Zig would assert). Screen guards/ignores.