terminal: expose scrollback line limit

This commit is contained in:
Mitchell Hashimoto
2026-07-26 19:31:01 -07:00
parent 5b2d3b7df1
commit 86f81fb5b1
14 changed files with 359 additions and 315 deletions

View File

@@ -138,7 +138,7 @@ pub fn create(
.terminal = try .init(global.io(), alloc, .{
.rows = opts.@"terminal-rows",
.cols = opts.@"terminal-cols",
.max_scrollback = opts.@"max-scrollback",
.max_scrollback_bytes = opts.@"max-scrollback",
}),
};
return ptr;

File diff suppressed because it is too large Load Diff

View File

@@ -512,7 +512,7 @@ pub fn adjust(
test "Selection: adjust right" {
const testing = std.testing;
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback = 0 });
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback_bytes = 0 });
defer s.deinit();
try s.testWriteString("A1234\nB5678\nC1234\nD5678");
@@ -579,7 +579,7 @@ test "Selection: adjust right" {
test "Selection: adjust left" {
const testing = std.testing;
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback = 0 });
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback_bytes = 0 });
defer s.deinit();
try s.testWriteString("A1234\nB5678\nC1234\nD5678");
@@ -628,7 +628,7 @@ test "Selection: adjust left" {
test "Selection: adjust left skips blanks" {
const testing = std.testing;
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback = 0 });
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback_bytes = 0 });
defer s.deinit();
try s.testWriteString("A1234\nB5678\nC12\nD56");
@@ -677,7 +677,7 @@ test "Selection: adjust left skips blanks" {
test "Selection: adjust up" {
const testing = std.testing;
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback = 0 });
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback_bytes = 0 });
defer s.deinit();
try s.testWriteString("A\nB\nC\nD\nE");
@@ -724,7 +724,7 @@ test "Selection: adjust up" {
test "Selection: adjust down" {
const testing = std.testing;
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback = 0 });
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback_bytes = 0 });
defer s.deinit();
try s.testWriteString("A\nB\nC\nD\nE");
@@ -771,7 +771,7 @@ test "Selection: adjust down" {
test "Selection: adjust down with not full screen" {
const testing = std.testing;
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback = 0 });
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback_bytes = 0 });
defer s.deinit();
try s.testWriteString("A\nB\nC");
@@ -799,7 +799,7 @@ test "Selection: adjust down with not full screen" {
test "Selection: adjust home" {
const testing = std.testing;
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback = 0 });
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback_bytes = 0 });
defer s.deinit();
try s.testWriteString("A\nB\nC");
@@ -827,7 +827,7 @@ test "Selection: adjust home" {
test "Selection: adjust end with not full screen" {
const testing = std.testing;
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback = 0 });
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback_bytes = 0 });
defer s.deinit();
try s.testWriteString("A\nB\nC");
@@ -855,7 +855,7 @@ test "Selection: adjust end with not full screen" {
test "Selection: adjust beginning of line" {
const testing = std.testing;
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 8, .rows = 10, .max_scrollback = 0 });
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 8, .rows = 10, .max_scrollback_bytes = 0 });
defer s.deinit();
try s.testWriteString("A12 B34\nC12 D34");
@@ -925,7 +925,7 @@ test "Selection: adjust beginning of line" {
test "Selection: adjust end of line" {
const testing = std.testing;
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 8, .rows = 10, .max_scrollback = 0 });
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 8, .rows = 10, .max_scrollback_bytes = 0 });
defer s.deinit();
try s.testWriteString("A12 B34\nC12 D34");
@@ -996,7 +996,7 @@ test "Selection: order, standard" {
const alloc = testing.allocator;
const io = testing.io;
var s = try Screen.init(io, alloc, .{ .cols = 100, .rows = 100, .max_scrollback = 1 });
var s = try Screen.init(io, alloc, .{ .cols = 100, .rows = 100, .max_scrollback_bytes = 1 });
defer s.deinit();
{
@@ -1061,7 +1061,7 @@ test "Selection: rectangle corners clamp across mixed-width pages" {
var s = try Screen.init(testing.io, testing.allocator, .{
.cols = 4,
.rows = 2,
.max_scrollback = 0,
.max_scrollback_bytes = 0,
});
defer s.deinit();
@@ -1087,7 +1087,7 @@ test "Selection: order, rectangle" {
const alloc = testing.allocator;
const io = testing.io;
var s = try Screen.init(io, alloc, .{ .cols = 100, .rows = 100, .max_scrollback = 1 });
var s = try Screen.init(io, alloc, .{ .cols = 100, .rows = 100, .max_scrollback_bytes = 1 });
defer s.deinit();
// Conventions:
@@ -1199,7 +1199,7 @@ test "Selection: order, rectangle" {
test "topLeft" {
const testing = std.testing;
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback = 0 });
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback_bytes = 0 });
defer s.deinit();
{
// forward
@@ -1262,7 +1262,7 @@ test "topLeft" {
test "bottomRight" {
const testing = std.testing;
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback = 0 });
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback_bytes = 0 });
defer s.deinit();
{
// forward
@@ -1325,7 +1325,7 @@ test "bottomRight" {
test "ordered" {
const testing = std.testing;
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback = 0 });
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback_bytes = 0 });
defer s.deinit();
{
// forward
@@ -1406,7 +1406,7 @@ test "ordered" {
test "Selection: contains" {
const testing = std.testing;
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback = 0 });
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 10, .max_scrollback_bytes = 0 });
defer s.deinit();
{
const sel = Selection.init(
@@ -1452,7 +1452,7 @@ test "Selection: contains" {
test "Selection: contains, rectangle" {
const testing = std.testing;
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 15, .rows = 15, .max_scrollback = 0 });
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 15, .rows = 15, .max_scrollback_bytes = 0 });
defer s.deinit();
{
const sel = Selection.init(
@@ -1514,7 +1514,7 @@ test "Selection: contains, rectangle" {
test "Selection: containedRow" {
const testing = std.testing;
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 5, .max_scrollback = 0 });
var s = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 5, .max_scrollback_bytes = 0 });
defer s.deinit();
{
@@ -1637,7 +1637,7 @@ test "Selection: containedRow clamps mixed-width pages" {
var s = try Screen.init(testing.io, testing.allocator, .{
.cols = 4,
.rows = 3,
.max_scrollback = 0,
.max_scrollback_bytes = 0,
});
defer s.deinit();

View File

@@ -1029,7 +1029,7 @@ fn testDragSelection(
.padding_left = 5,
.screen_height = 110,
};
var screen = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 5, .max_scrollback = 0 });
var screen = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 5, .max_scrollback_bytes = 0 });
defer screen.deinit();
const click_pin = screen.pages.pin(.{
@@ -1090,7 +1090,7 @@ fn testDragSelectionIsNull(
.padding_left = 5,
.screen_height = 110,
};
var screen = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 5, .max_scrollback = 0 });
var screen = try Screen.init(testing.io, testing.allocator, .{ .cols = 10, .rows = 5, .max_scrollback_bytes = 0 });
defer screen.deinit();
const click_pin = screen.pages.pin(.{
@@ -1724,7 +1724,7 @@ test "SelectionGesture autoscroll tick scrolls and continues drag" {
}
test "SelectionGesture autoscroll tick resolves drag pin after scrolling" {
var t = try Terminal.init(testing.io, testing.allocator, .{ .cols = 5, .rows = 3, .max_scrollback = 10 });
var t = try Terminal.init(testing.io, testing.allocator, .{ .cols = 5, .rows = 3, .max_scrollback_bytes = 10 });
defer t.deinit(testing.allocator);
try t.printString("1111\n2222\n3333\n4444\n5555");
t.scrollViewport(.{ .delta = -2 });

View File

@@ -131,7 +131,7 @@ test "StringMap searchIterator" {
defer re.deinit();
// Initialize our screen
var s = try Screen.init(io, alloc, .{ .cols = 5, .rows = 5, .max_scrollback = 0 });
var s = try Screen.init(io, alloc, .{ .cols = 5, .rows = 5, .max_scrollback_bytes = 0 });
defer s.deinit();
const str = "1ABCD2EFGH\n3IJKL";
try s.testWriteString(str);
@@ -190,7 +190,7 @@ test "StringMap searchIterator URL detection" {
defer re.deinit();
// Initialize our screen with text containing a URL
var s = try Screen.init(io, alloc, .{ .cols = 40, .rows = 5, .max_scrollback = 0 });
var s = try Screen.init(io, alloc, .{ .cols = 40, .rows = 5, .max_scrollback_bytes = 0 });
defer s.deinit();
try s.testWriteString("hello https://example.com/path world");
@@ -252,7 +252,7 @@ test "StringMap searchIterator URL with click position" {
defer re.deinit();
// Initialize our screen with text containing a URL
var s = try Screen.init(io, alloc, .{ .cols = 40, .rows = 5, .max_scrollback = 0 });
var s = try Screen.init(io, alloc, .{ .cols = 40, .rows = 5, .max_scrollback_bytes = 0 });
defer s.deinit();
try s.testWriteString("hello https://example.com world");

View File

@@ -256,7 +256,15 @@ pub const Cursor = struct {
pub const Options = struct {
cols: size.CellCountInt,
rows: size.CellCountInt,
max_scrollback: usize = 10_000,
/// The maximum size of scrollback in bytes. Zero disables scrollback.
max_scrollback_bytes: usize = 10_000,
/// The maximum number of physical scrollback rows, excluding the active
/// area. Null is unlimited. The effective limit permits at least one
/// standard page and only complete historical pages are pruned.
max_scrollback_lines: ?usize = null,
colors: Colors = .default,
/// The default mode state. When the terminal gets a reset, it
@@ -300,7 +308,8 @@ pub fn init(
var screen_set: ScreenSet = try .init(io_impl, alloc, .{
.cols = cols,
.rows = rows,
.max_scrollback = opts.max_scrollback,
.max_scrollback_bytes = opts.max_scrollback_bytes,
.max_scrollback_lines = opts.max_scrollback_lines,
.kitty_image_storage_limit = opts.kitty_image_storage_limit,
.kitty_image_loading_limits = opts.kitty_image_loading_limits,
});
@@ -3823,7 +3832,7 @@ pub fn resize(
.{
.cols = opts.cols,
.rows = opts.rows,
.max_scrollback = 0,
.max_scrollback_bytes = 0,
.kitty_image_storage_limit = if (comptime build_options.kitty_graphics)
primary.kitty_images.total_limit
else
@@ -3871,6 +3880,21 @@ pub fn resize(
};
}
test "Terminal forwards max scrollback lines" {
const max_lines: usize = 123;
var t = try init(testing.io, testing.allocator, .{
.cols = 80,
.rows = 24,
.max_scrollback_lines = max_lines,
});
defer t.deinit(testing.allocator);
try testing.expectEqual(
max_lines,
t.screens.active.pages.explicit_max_lines,
);
}
test "Terminal: resize resets synchronized output" {
const alloc = testing.allocator;
const io_impl = testing.io;
@@ -4287,7 +4311,7 @@ pub fn switchScreen(self: *Terminal, key: ScreenSet.Key) !?*Screen {
.{
.cols = self.cols,
.rows = self.rows,
.max_scrollback = switch (key) {
.max_scrollback_bytes = switch (key) {
.primary => primary.pages.explicit_max_size,
.alternate => 0,
},
@@ -7656,7 +7680,7 @@ test "Terminal: insertLines top/bottom scroll region" {
test "Terminal: insertLines across page boundary marks all shifted rows dirty" {
const alloc = testing.allocator;
const io_impl = testing.io;
var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 10, .max_scrollback = 1024 });
var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 10, .max_scrollback_bytes = 1024 });
defer t.deinit(alloc);
const first_page = t.screens.active.pages.pages.first.?;
@@ -7711,7 +7735,7 @@ test "Terminal: insertLines hyperlink-dense row crosses page boundary" {
// page's capacity and retry rather than corrupting the page list.
const alloc = testing.allocator;
const io_impl = testing.io;
var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 10, .max_scrollback = 1024 });
var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 10, .max_scrollback_bytes = 1024 });
defer t.deinit(alloc);
const pages = &t.screens.active.pages;
@@ -8403,7 +8427,7 @@ test "Terminal: scrollUp creates scrollback in primary screen" {
// scrollUp (CSI S) should push lines into scrollback like xterm.
const alloc = testing.allocator;
const io_impl = testing.io;
var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 5, .max_scrollback = 10 });
var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 5, .max_scrollback_bytes = 10 });
defer t.deinit(alloc);
// Fill the screen with content
@@ -8446,11 +8470,11 @@ test "Terminal: scrollUp creates scrollback in primary screen" {
}
}
test "Terminal: scrollUp with max_scrollback zero" {
// When max_scrollback is 0, scrollUp should still work but not retain history
test "Terminal: scrollUp with max_scrollback_bytes zero" {
// When max_scrollback_bytes is 0, scrollUp should still work but not retain history
const alloc = testing.allocator;
const io_impl = testing.io;
var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 5, .max_scrollback = 0 });
var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 5, .max_scrollback_bytes = 0 });
defer t.deinit(alloc);
try t.printString("AAAAA");
@@ -8479,11 +8503,11 @@ test "Terminal: scrollUp with max_scrollback zero" {
}
}
test "Terminal: scrollUp with max_scrollback zero and top margin" {
// When max_scrollback is 0 and top margin is set, should use deleteLines path
test "Terminal: scrollUp with max_scrollback_bytes zero and top margin" {
// When max_scrollback_bytes is 0 and top margin is set, should use deleteLines path
const alloc = testing.allocator;
const io_impl = testing.io;
var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 5, .max_scrollback = 0 });
var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 5, .max_scrollback_bytes = 0 });
defer t.deinit(alloc);
try t.printString("AAAAA");
@@ -8510,11 +8534,11 @@ test "Terminal: scrollUp with max_scrollback zero and top margin" {
}
}
test "Terminal: scrollUp with max_scrollback zero and left/right margin" {
// When max_scrollback is 0 with left/right margins, uses deleteLines path
test "Terminal: scrollUp with max_scrollback_bytes zero and left/right margin" {
// When max_scrollback_bytes is 0 with left/right margins, uses deleteLines path
const alloc = testing.allocator;
const io_impl = testing.io;
var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 10, .max_scrollback = 0 });
var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 10, .max_scrollback_bytes = 0 });
defer t.deinit(alloc);
try t.printString("AAAAABBBBB");
@@ -9696,7 +9720,7 @@ test "Terminal: index bottom of scroll region with hyperlinks" {
test "Terminal: index bottom of scroll region clear hyperlinks" {
const alloc = testing.allocator;
const io_impl = testing.io;
var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 5, .max_scrollback = 0 });
var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 5, .max_scrollback_bytes = 0 });
defer t.deinit(alloc);
t.setTopAndBottomMargin(2, 3);
@@ -9889,7 +9913,7 @@ test "Terminal: index bottom of scroll region creates scrollback" {
test "Terminal: index bottom of scroll region no scrollback" {
const alloc = testing.allocator;
const io_impl = testing.io;
var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 5, .max_scrollback = 0 });
var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 5, .max_scrollback_bytes = 0 });
defer t.deinit(alloc);
t.setTopAndBottomMargin(1, 3);
@@ -10056,7 +10080,7 @@ test "Terminal: index bottom of alt screen top region" {
test "Terminal: scrollUp top region no scrollback" {
const alloc = testing.allocator;
const io_impl = testing.io;
var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 5, .max_scrollback = 0 });
var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 5, .max_scrollback_bytes = 0 });
defer t.deinit(alloc);
try t.printString("A\nB\nC\nD\nE");
@@ -10641,7 +10665,7 @@ test "Terminal: deleteLines colors with bg color" {
test "Terminal: deleteLines across page boundary marks all shifted rows dirty" {
const alloc = testing.allocator;
const io_impl = testing.io;
var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 10, .max_scrollback = 1024 });
var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 10, .max_scrollback_bytes = 1024 });
defer t.deinit(alloc);
const first_page = t.screens.active.pages.pages.first.?;
@@ -10701,7 +10725,7 @@ test "Terminal: deleteLines hyperlink-dense row crosses page boundary" {
// this exercises the cursor accounting of the capacity increase.
const alloc = testing.allocator;
const io_impl = testing.io;
var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 10, .max_scrollback = 1024 });
var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 10, .max_scrollback_bytes = 1024 });
defer t.deinit(alloc);
const pages = &t.screens.active.pages;

View File

@@ -365,7 +365,7 @@ fn new_(
.{
.cols = opts.cols,
.rows = opts.rows,
.max_scrollback = opts.max_scrollback,
.max_scrollback_bytes = opts.max_scrollback,
},
);
errdefer t.deinit(alloc);

View File

@@ -1427,7 +1427,7 @@ test "incremental updates match full rebuild" {
var t = try Terminal.init(io, alloc, .{
.cols = 20,
.rows = 8,
.max_scrollback = 500,
.max_scrollback_bytes = 500,
});
defer t.deinit(alloc);
@@ -2010,7 +2010,7 @@ test "linkCells with scrollback spanning pages" {
var t = try Terminal.init(io, alloc, .{
.cols = page.std_capacity.cols,
.rows = viewport_rows,
.max_scrollback = 10_000,
.max_scrollback_bytes = 10_000,
});
defer t.deinit(alloc);

View File

@@ -381,7 +381,7 @@ test "compressed history match spanning page boundary remains compressed" {
var t: Terminal = try .init(io, alloc, .{
.cols = 80,
.rows = 24,
.max_scrollback = 10 * 1024 * 1024,
.max_scrollback_bytes = 10 * 1024 * 1024,
});
defer t.deinit(alloc);

View File

@@ -977,7 +977,7 @@ test "simple search with history" {
var t: Terminal = try .init(io, alloc, .{
.cols = 10,
.rows = 2,
.max_scrollback = std.math.maxInt(usize),
.max_scrollback_bytes = std.math.maxInt(usize),
});
defer t.deinit(alloc);
const list: *PageList = &t.screens.active.pages;
@@ -1019,7 +1019,7 @@ test "reload active with history change" {
var t: Terminal = try .init(io, alloc, .{
.cols = 10,
.rows = 2,
.max_scrollback = std.math.maxInt(usize),
.max_scrollback_bytes = std.math.maxInt(usize),
});
defer t.deinit(alloc);
const list: *PageList = &t.screens.active.pages;
@@ -1207,7 +1207,7 @@ test "select after resize resets stale flattened results" {
var t: Terminal = try .init(io, alloc, .{
.cols = 10,
.rows = 3,
.max_scrollback = std.math.maxInt(usize),
.max_scrollback_bytes = std.math.maxInt(usize),
});
defer t.deinit(alloc);
@@ -1307,7 +1307,7 @@ test "select into history" {
var t: Terminal = try .init(io, alloc, .{
.cols = 10,
.rows = 2,
.max_scrollback = std.math.maxInt(usize),
.max_scrollback_bytes = std.math.maxInt(usize),
});
defer t.deinit(alloc);
const list: *PageList = &t.screens.active.pages;
@@ -1485,7 +1485,7 @@ test "select prev with history" {
var t: Terminal = try .init(io, alloc, .{
.cols = 10,
.rows = 2,
.max_scrollback = std.math.maxInt(usize),
.max_scrollback_bytes = std.math.maxInt(usize),
});
defer t.deinit(alloc);
const list: *PageList = &t.screens.active.pages;
@@ -1540,7 +1540,7 @@ test "select prev wraps when all matches are in history" {
var t: Terminal = try .init(io, alloc, .{
.cols = 10,
.rows = 2,
.max_scrollback = std.math.maxInt(usize),
.max_scrollback_bytes = std.math.maxInt(usize),
});
defer t.deinit(alloc);
const list: *PageList = &t.screens.active.pages;
@@ -1605,7 +1605,7 @@ test "select after partial history erase drops a pruned selection" {
var t: Terminal = try .init(io, alloc, .{
.cols = 10,
.rows = 2,
.max_scrollback = std.math.maxInt(usize),
.max_scrollback_bytes = std.math.maxInt(usize),
});
defer t.deinit(alloc);
const list: *PageList = &t.screens.active.pages;
@@ -1638,7 +1638,7 @@ test "select after history compaction ignores replaced results" {
var t: Terminal = try .init(io, alloc, .{
.cols = 10,
.rows = 2,
.max_scrollback = std.math.maxInt(usize),
.max_scrollback_bytes = std.math.maxInt(usize),
});
defer t.deinit(alloc);
const list: *PageList = &t.screens.active.pages;
@@ -1673,7 +1673,7 @@ test "select after partial history page erase ignores shifted results" {
var t: Terminal = try .init(io, alloc, .{
.cols = 10,
.rows = 2,
.max_scrollback = std.math.maxInt(usize),
.max_scrollback_bytes = std.math.maxInt(usize),
});
defer t.deinit(alloc);
const list: *PageList = &t.screens.active.pages;
@@ -1707,7 +1707,7 @@ test "reload defers pruning unselected history results" {
var t: Terminal = try .init(io, alloc, .{
.cols = 10,
.rows = 2,
.max_scrollback = std.math.maxInt(usize),
.max_scrollback_bytes = std.math.maxInt(usize),
});
defer t.deinit(alloc);
const list: *PageList = &t.screens.active.pages;
@@ -1742,7 +1742,7 @@ test "reload after partial history page erase drops shifted selection first" {
var t: Terminal = try .init(io, alloc, .{
.cols = 10,
.rows = 2,
.max_scrollback = std.math.maxInt(usize),
.max_scrollback_bytes = std.math.maxInt(usize),
});
defer t.deinit(alloc);
const list: *PageList = &t.screens.active.pages;
@@ -1781,7 +1781,7 @@ test "select after history page split ignores moved results" {
var t: Terminal = try .init(io, alloc, .{
.cols = 10,
.rows = 2,
.max_scrollback = std.math.maxInt(usize),
.max_scrollback_bytes = std.math.maxInt(usize),
});
defer t.deinit(alloc);
const list: *PageList = &t.screens.active.pages;
@@ -1815,7 +1815,7 @@ test "screen search no scrollback has no history" {
var t: Terminal = try .init(io, alloc, .{
.cols = 10,
.rows = 2,
.max_scrollback = 0,
.max_scrollback_bytes = 0,
});
defer t.deinit(alloc);
@@ -1852,7 +1852,7 @@ test "reloadActive partial history cleanup on appendSlice error" {
var t: Terminal = try .init(io, alloc, .{
.cols = 10,
.rows = 2,
.max_scrollback = std.math.maxInt(usize),
.max_scrollback_bytes = std.math.maxInt(usize),
});
defer t.deinit(alloc);
const list: *PageList = &t.screens.active.pages;
@@ -1900,7 +1900,7 @@ test "reloadActive partial history cleanup on loop append error" {
var t: Terminal = try .init(io, alloc, .{
.cols = 10,
.rows = 2,
.max_scrollback = std.math.maxInt(usize),
.max_scrollback_bytes = std.math.maxInt(usize),
});
defer t.deinit(alloc);
const list: *PageList = &t.screens.active.pages;
@@ -1947,7 +1947,7 @@ test "select after clearing scrollback" {
var t: Terminal = try .init(io, alloc, .{
.cols = 10,
.rows = 2,
.max_scrollback = std.math.maxInt(usize),
.max_scrollback_bytes = std.math.maxInt(usize),
});
defer t.deinit(alloc);
const list: *PageList = &t.screens.active.pages;

View File

@@ -722,7 +722,7 @@ test "SlidingWindow empty needle has no matches" {
var s = try Screen.init(io, alloc, .{
.cols = 80,
.rows = 24,
.max_scrollback = 0,
.max_scrollback_bytes = 0,
});
defer s.deinit();
try s.testWriteString("hello");
@@ -739,7 +739,7 @@ test "SlidingWindow single append" {
var w: SlidingWindow = try .init(alloc, .forward, "boo!");
defer w.deinit();
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback = 0 });
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback_bytes = 0 });
defer s.deinit();
try s.testWriteString("hello. boo! hello. boo!");
@@ -785,7 +785,7 @@ test "SlidingWindow single append case insensitive ASCII" {
var w: SlidingWindow = try .init(alloc, .forward, "Boo!");
defer w.deinit();
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback = 0 });
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback_bytes = 0 });
defer s.deinit();
try s.testWriteString("hello. boo! hello. boo!");
@@ -831,7 +831,7 @@ test "SlidingWindow single append single char" {
var w: SlidingWindow = try .init(alloc, .forward, "b");
defer w.deinit();
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback = 0 });
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback_bytes = 0 });
defer s.deinit();
try s.testWriteString("hello. boo! hello. boo!");
@@ -877,7 +877,7 @@ test "SlidingWindow single append no match" {
var w: SlidingWindow = try .init(alloc, .forward, "nope!");
defer w.deinit();
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback = 0 });
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback_bytes = 0 });
defer s.deinit();
try s.testWriteString("hello. boo! hello. boo!");
@@ -902,7 +902,7 @@ test "SlidingWindow two pages" {
var w: SlidingWindow = try .init(alloc, .forward, "boo!");
defer w.deinit();
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback = 1000 });
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback_bytes = 1000 });
defer s.deinit();
// Fill up the first page. The final bytes in the first page
@@ -958,7 +958,7 @@ test "SlidingWindow two pages single char" {
var w: SlidingWindow = try .init(alloc, .forward, "b");
defer w.deinit();
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback = 1000 });
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback_bytes = 1000 });
defer s.deinit();
// Fill up the first page. The final bytes in the first page
@@ -1014,7 +1014,7 @@ test "SlidingWindow two pages match across boundary" {
var w: SlidingWindow = try .init(alloc, .forward, "hello, world");
defer w.deinit();
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback = 1000 });
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback_bytes = 1000 });
defer s.deinit();
// Fill up the first page. The final bytes in the first page
@@ -1060,7 +1060,7 @@ test "SlidingWindow two pages no match across boundary with newline" {
var w: SlidingWindow = try .init(alloc, .forward, "hello, world");
defer w.deinit();
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback = 1000 });
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback_bytes = 1000 });
defer s.deinit();
// Fill up the first page. The final bytes in the first page
@@ -1094,7 +1094,7 @@ test "SlidingWindow two pages no match across boundary with newline reverse" {
var w: SlidingWindow = try .init(alloc, .reverse, "hello, world");
defer w.deinit();
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback = 1000 });
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback_bytes = 1000 });
defer s.deinit();
// Fill up the first page. The final bytes in the first page
@@ -1125,7 +1125,7 @@ test "SlidingWindow two pages no match prunes first page" {
var w: SlidingWindow = try .init(alloc, .forward, "nope!");
defer w.deinit();
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback = 1000 });
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback_bytes = 1000 });
defer s.deinit();
// Fill up the first page. The final bytes in the first page
@@ -1158,7 +1158,7 @@ test "SlidingWindow two pages no match keeps both pages" {
const alloc = testing.allocator;
const io = testing.io;
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback = 1000 });
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback_bytes = 1000 });
defer s.deinit();
// Fill up the first page. The final bytes in the first page
@@ -1202,7 +1202,7 @@ test "SlidingWindow single append across circular buffer boundary" {
var w: SlidingWindow = try .init(alloc, .forward, "abc");
defer w.deinit();
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback = 0 });
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback_bytes = 0 });
defer s.deinit();
try s.testWriteString("XXXXXXXXXXXXXXXXXXXboo!XXXXX");
@@ -1259,7 +1259,7 @@ test "SlidingWindow single append match on boundary" {
var w: SlidingWindow = try .init(alloc, .forward, "abcd");
defer w.deinit();
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback = 0 });
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback_bytes = 0 });
defer s.deinit();
try s.testWriteString("o!XXXXXXXXXXXXXXXXXXXbo");
@@ -1319,7 +1319,7 @@ test "SlidingWindow single append reversed" {
var w: SlidingWindow = try .init(alloc, .reverse, "boo!");
defer w.deinit();
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback = 0 });
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback_bytes = 0 });
defer s.deinit();
try s.testWriteString("hello. boo! hello. boo!");
@@ -1365,7 +1365,7 @@ test "SlidingWindow single append no match reversed" {
var w: SlidingWindow = try .init(alloc, .reverse, "nope!");
defer w.deinit();
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback = 0 });
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback_bytes = 0 });
defer s.deinit();
try s.testWriteString("hello. boo! hello. boo!");
@@ -1390,7 +1390,7 @@ test "SlidingWindow two pages reversed" {
var w: SlidingWindow = try .init(alloc, .reverse, "boo!");
defer w.deinit();
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback = 1000 });
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback_bytes = 1000 });
defer s.deinit();
// Fill up the first page. The final bytes in the first page
@@ -1446,7 +1446,7 @@ test "SlidingWindow two pages match across boundary reversed" {
var w: SlidingWindow = try .init(alloc, .reverse, "hello, world");
defer w.deinit();
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback = 1000 });
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback_bytes = 1000 });
defer s.deinit();
// Fill up the first page. The final bytes in the first page
@@ -1502,7 +1502,7 @@ test "SlidingWindow two pages no match prunes first page reversed" {
var w: SlidingWindow = try .init(alloc, .reverse, "nope!");
defer w.deinit();
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback = 1000 });
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback_bytes = 1000 });
defer s.deinit();
// Fill up the first page. The final bytes in the first page
@@ -1535,7 +1535,7 @@ test "SlidingWindow two pages no match keeps both pages reversed" {
const alloc = testing.allocator;
const io = testing.io;
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback = 1000 });
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback_bytes = 1000 });
defer s.deinit();
// Fill up the first page. The final bytes in the first page
@@ -1579,7 +1579,7 @@ test "SlidingWindow single append across circular buffer boundary reversed" {
var w: SlidingWindow = try .init(alloc, .reverse, "abc");
defer w.deinit();
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback = 0 });
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback_bytes = 0 });
defer s.deinit();
try s.testWriteString("XXXXXXXXXXXXXXXXXXXboo!XXXXX");
@@ -1637,7 +1637,7 @@ test "SlidingWindow single append match on boundary reversed" {
var w: SlidingWindow = try .init(alloc, .reverse, "abcd");
defer w.deinit();
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback = 0 });
var s = try Screen.init(io, alloc, .{ .cols = 80, .rows = 24, .max_scrollback_bytes = 0 });
defer s.deinit();
try s.testWriteString("o!XXXXXXXXXXXXXXXXXXXbo");
@@ -1779,7 +1779,7 @@ test "SlidingWindow append whitespace only node" {
var s = try Screen.init(io, alloc, .{
.cols = 80,
.rows = 24,
.max_scrollback = 0,
.max_scrollback_bytes = 0,
});
defer s.deinit();

View File

@@ -2108,7 +2108,7 @@ test "stream: CSI W with intermediate but no params" {
var t: Terminal = try .init(testing.io, testing.allocator, .{
.cols = 80,
.rows = 24,
.max_scrollback = 100,
.max_scrollback_bytes = 100,
});
defer t.deinit(testing.allocator);

View File

@@ -246,7 +246,7 @@ pub fn init(self: *Termio, alloc: Allocator, opts: termio.Options) !void {
break :opts .{
.cols = grid_size.columns,
.rows = grid_size.rows,
.max_scrollback = opts.full_config.@"scrollback-limit",
.max_scrollback_bytes = opts.full_config.@"scrollback-limit",
.default_modes = default_modes,
.default_cursor_style = opts.config.cursor_style,
.default_cursor_blink = opts.config.cursor_blink,

View File

@@ -44,7 +44,7 @@ pub export fn zig_fuzz_test(
var t = Terminal.init(threaded.io(), alloc, .{
.cols = 80,
.rows = 24,
.max_scrollback = 100,
.max_scrollback_bytes = 100,
}) catch return;
defer t.deinit(alloc);