mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-21 19:26:09 +03:00
terminal/new: use new pagelist grow mechanism that prunes
This commit is contained in:
@ -258,7 +258,9 @@ pub fn scroll(self: *PageList, behavior: Scroll) void {
|
||||
/// This may allocate, but also may not if our current page has more
|
||||
/// capacity we can use. This will prune scrollback if necessary to
|
||||
/// adhere to max_size.
|
||||
pub fn grow2(self: *PageList) !?*List.Node {
|
||||
///
|
||||
/// This returns the newly allocated page node if there is one.
|
||||
pub fn grow(self: *PageList) !?*List.Node {
|
||||
const last = self.pages.last.?;
|
||||
if (last.data.capacity.rows > last.data.size.rows) {
|
||||
// Fast path: we have capacity in the last page.
|
||||
@ -305,16 +307,6 @@ pub fn grow2(self: *PageList) !?*List.Node {
|
||||
return next_page;
|
||||
}
|
||||
|
||||
/// Grow the page list by exactly one page and return the new page. The
|
||||
/// newly allocated page will be size 0 (but capacity is set).
|
||||
pub fn grow(self: *PageList) !*List.Node {
|
||||
const next_page = try self.createPage();
|
||||
// we don't errdefer this because we've added it to the linked
|
||||
// list and its fine to have dangling unused pages.
|
||||
self.pages.append(next_page);
|
||||
return next_page;
|
||||
}
|
||||
|
||||
/// Create a new page node. This does not add it to the list and this
|
||||
/// does not do any memory size accounting with max_size/page_size.
|
||||
fn createPage(self: *PageList) !*List.Node {
|
||||
@ -461,7 +453,7 @@ fn growRows(self: *PageList, n: usize) !void {
|
||||
}
|
||||
|
||||
while (n_rem > 0) {
|
||||
page = try self.grow();
|
||||
page = (try self.grow()).?;
|
||||
const add = @min(n_rem, page.data.capacity.rows);
|
||||
page.data.size.rows = add;
|
||||
n_rem -= add;
|
||||
@ -847,7 +839,7 @@ test "PageList grow fit in capacity" {
|
||||
try testing.expect(last.size.rows < last.capacity.rows);
|
||||
|
||||
// Grow
|
||||
try testing.expect(try s.grow2() == null);
|
||||
try testing.expect(try s.grow() == null);
|
||||
{
|
||||
const pt = s.getCell(.{ .active = .{} }).?.screenPoint();
|
||||
try testing.expectEqual(point.Point{ .screen = .{
|
||||
@ -868,11 +860,11 @@ test "PageList grow allocate" {
|
||||
const last_node = s.pages.last.?;
|
||||
const last = &s.pages.last.?.data;
|
||||
for (0..last.capacity.rows - last.size.rows) |_| {
|
||||
try testing.expect(try s.grow2() == null);
|
||||
try testing.expect(try s.grow() == null);
|
||||
}
|
||||
|
||||
// Grow, should allocate
|
||||
const new = (try s.grow2()).?;
|
||||
const new = (try s.grow()).?;
|
||||
try testing.expect(s.pages.last.? == new);
|
||||
try testing.expect(last_node.next.? == new);
|
||||
{
|
||||
@ -897,14 +889,14 @@ test "PageList grow prune scrollback" {
|
||||
const page1_node = s.pages.last.?;
|
||||
const page1 = page1_node.data;
|
||||
for (0..page1.capacity.rows - page1.size.rows) |_| {
|
||||
try testing.expect(try s.grow2() == null);
|
||||
try testing.expect(try s.grow() == null);
|
||||
}
|
||||
|
||||
// Grow and allocate one more page. Then fill that page up.
|
||||
const page2_node = (try s.grow2()).?;
|
||||
const page2_node = (try s.grow()).?;
|
||||
const page2 = page2_node.data;
|
||||
for (0..page2.capacity.rows - page2.size.rows) |_| {
|
||||
try testing.expect(try s.grow2() == null);
|
||||
try testing.expect(try s.grow() == null);
|
||||
}
|
||||
|
||||
// Get our page size
|
||||
@ -912,7 +904,7 @@ test "PageList grow prune scrollback" {
|
||||
|
||||
// Next should create a new page, but it should reuse our first
|
||||
// page since we're at max size.
|
||||
const new = (try s.grow2()).?;
|
||||
const new = (try s.grow()).?;
|
||||
try testing.expect(s.pages.last.? == new);
|
||||
try testing.expectEqual(s.page_size, old_page_size);
|
||||
|
||||
|
@ -226,31 +226,14 @@ pub fn cursorAbsolute(self: *Screen, x: size.CellCountInt, y: size.CellCountInt)
|
||||
pub fn cursorDownScroll(self: *Screen) !void {
|
||||
assert(self.cursor.y == self.pages.rows - 1);
|
||||
|
||||
const cursor_page = self.cursor.page_offset.page;
|
||||
if (cursor_page.data.capacity.rows > cursor_page.data.size.rows) {
|
||||
// If we have cap space in our current cursor page then we can take
|
||||
// a fast path: update the size, recalculate the row/cell cursor pointers.
|
||||
cursor_page.data.size.rows += 1;
|
||||
|
||||
// Grow our pages by one row. The PageList will handle if we need to
|
||||
// allocate, prune scrollback, whatever.
|
||||
_ = try self.pages.grow();
|
||||
const page_offset = self.cursor.page_offset.forward(1).?;
|
||||
const page_rac = page_offset.rowAndCell(self.cursor.x);
|
||||
self.cursor.page_offset = page_offset;
|
||||
self.cursor.page_row = page_rac.row;
|
||||
self.cursor.page_cell = page_rac.cell;
|
||||
} else {
|
||||
// No space, we need to allocate a new page and move the cursor to it.
|
||||
const new_page = try self.pages.grow();
|
||||
assert(new_page.data.size.rows == 0);
|
||||
new_page.data.size.rows = 1;
|
||||
const page_offset: PageList.RowOffset = .{
|
||||
.page = new_page,
|
||||
.row_offset = 0,
|
||||
};
|
||||
const page_rac = page_offset.rowAndCell(self.cursor.x);
|
||||
self.cursor.page_offset = page_offset;
|
||||
self.cursor.page_row = page_rac.row;
|
||||
self.cursor.page_cell = page_rac.cell;
|
||||
}
|
||||
|
||||
// The newly created line needs to be styled according to the bg color
|
||||
// if it is set.
|
||||
|
Reference in New Issue
Block a user