diff --git a/src/terminal/PageList.zig b/src/terminal/PageList.zig index dba3ca73f..5df2c2b91 100644 --- a/src/terminal/PageList.zig +++ b/src/terminal/PageList.zig @@ -10828,6 +10828,37 @@ test "PageList resize (no reflow) less rows and cols" { } } +test "PageList resize less rows and cols cursor at bottom" { + const testing = std.testing; + const alloc = testing.allocator; + + var s = try init(alloc, 80, 24, 0); + defer s.deinit(); + + const cursor_pin = try s.trackPin(s.pin(.{ .active = .{ + .x = 0, + .y = s.rows - 1, + } }).?); + defer s.untrackPin(cursor_pin); + + // Shrink both axes such that the original cursor.y is strictly past the + // new row count, so resizeWithoutReflow leaves self.rows < c.y + 1. + try s.resize(.{ + .cols = 79, + .rows = 20, + .reflow = true, + .cursor = .{ .x = 0, .y = 23, .pin = cursor_pin }, + }); + try testing.expectEqual(@as(usize, 79), s.cols); + try testing.expectEqual(@as(usize, 20), s.rows); + + // remaining_rows saturates to 0, so the cursor lands on the new bottom row. + try testing.expectEqual(point.Point{ .active = .{ + .x = 0, + .y = s.rows - 1, + } }, s.pointFromPin(.active, cursor_pin.*).?); +} + test "PageList resize (no reflow) more rows and less cols" { const testing = std.testing; const alloc = testing.allocator; diff --git a/src/terminal/c/terminal.zig b/src/terminal/c/terminal.zig index 5a5db2d6b..3832be62b 100644 --- a/src/terminal/c/terminal.zig +++ b/src/terminal/c/terminal.zig @@ -1005,6 +1005,30 @@ test "resize invalid value" { try testing.expectEqual(Result.invalid_value, resize(t, 80, 0, 9, 18)); } +test "resize shrinks both axes with cursor at bottom" { + var t: Terminal = null; + try testing.expectEqual(Result.success, new( + &lib.alloc.test_allocator, + &t, + .{ + .cols = 80, + .rows = 24, + .max_scrollback = 0, + }, + )); + defer free(t); + + // CSI 24;1H -> park the cursor on the bottom row (1-based). + const move = "\x1b[24;1H"; + vt_write(t, move, move.len); + + // Shrink both axes; pre-resize cursor.y sits past the new bottom row. + // Previously this underflowed in PageList.resizeCols. + try testing.expectEqual(Result.success, resize(t, 79, 23, 8, 16)); + try testing.expectEqual(79, t.?.terminal.cols); + try testing.expectEqual(23, t.?.terminal.rows); +} + test "mode_get and mode_set" { var t: Terminal = null; try testing.expectEqual(Result.success, new(