terminal: use previous page width for cursor cells

cursorCellEndOfPrev moved its pin to the previous row but then set the
column from the desired screen width. If incomplete reflow left that
previous page narrower, resolving the cell used an out-of-bounds column
and panicked in runtime safety builds.

Set the column from the page reached by the cursor pin so the returned
cell is always the actual final cell of that row.
This commit is contained in:
Mitchell Hashimoto
2026-07-09 20:58:14 -07:00
parent a9f5b7eba2
commit a55850c981

View File

@@ -651,7 +651,7 @@ pub fn cursorCellEndOfPrev(self: *Screen) *pagepkg.Cell {
assert(self.cursor.y > 0);
var page_pin = self.cursor.page_pin.up(1).?;
page_pin.x = self.pages.cols - 1;
page_pin.x = page_pin.node.cols() - 1;
const page_rac = page_pin.rowAndCell();
return page_rac.cell;
}
@@ -4223,6 +4223,27 @@ test "Screen eraseRows active partial" {
}
}
test "Screen: cursorCellEndOfPrev across mixed-width pages" {
const testing = std.testing;
var s = try init(testing.allocator, .{
.cols = 4,
.rows = 2,
.max_scrollback = 0,
});
defer s.deinit();
try s.testWriteString("ABCDE");
const first = s.pages.pages.first.?;
try s.pages.split(.{ .node = first, .y = 1 });
s.cursorReload();
const second = first.next.?;
first.page().size.cols = 2;
try testing.expectEqual(second, s.cursor.page_pin.node);
const expected = (Pin{ .node = first, .x = 1 }).rowAndCell().cell;
try testing.expectEqual(expected, s.cursorCellEndOfPrev());
}
test "Screen: cursorDown across pages preserves style" {
const testing = std.testing;
const alloc = testing.allocator;