mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 17:26:09 +03:00
terminal: cloneFrom clears destination
This commit is contained in:
@ -220,9 +220,6 @@ pub const Page = struct {
|
||||
/// If the other page has more columns, the extra columns will be
|
||||
/// truncated. If the other page has fewer columns, the extra columns
|
||||
/// will be zeroed.
|
||||
///
|
||||
/// The current page is assumed to be empty. We will not clear any
|
||||
/// existing data in the current page.
|
||||
pub fn cloneFrom(
|
||||
self: *Page,
|
||||
other: *const Page,
|
||||
@ -232,11 +229,6 @@ pub const Page = struct {
|
||||
assert(y_start <= y_end);
|
||||
assert(y_end <= other.size.rows);
|
||||
assert(y_end - y_start <= self.size.rows);
|
||||
if (comptime std.debug.runtime_safety) {
|
||||
// The current page must be empty.
|
||||
assert(self.styles.count(self.memory) == 0);
|
||||
assert(self.graphemeCount() == 0);
|
||||
}
|
||||
|
||||
const other_rows = other.rows.ptr(other.memory)[y_start..y_end];
|
||||
const rows = self.rows.ptr(self.memory)[0 .. y_end - y_start];
|
||||
@ -254,15 +246,23 @@ pub const Page = struct {
|
||||
dst_row: *Row,
|
||||
src_row: *const Row,
|
||||
) !void {
|
||||
const cell_len = @min(self.size.cols, other.size.cols);
|
||||
const other_cells = src_row.cells.ptr(other.memory)[0..cell_len];
|
||||
const cells = dst_row.cells.ptr(self.memory)[0..cell_len];
|
||||
|
||||
// If our destination has styles or graphemes then we need to
|
||||
// clear some state.
|
||||
if (dst_row.grapheme or dst_row.styled) {
|
||||
self.clearCells(dst_row, 0, cells.len);
|
||||
assert(!dst_row.grapheme);
|
||||
assert(!dst_row.styled);
|
||||
}
|
||||
|
||||
// Copy all the row metadata but keep our cells offset
|
||||
const cells_offset = dst_row.cells;
|
||||
dst_row.* = src_row.*;
|
||||
dst_row.cells = cells_offset;
|
||||
|
||||
const cell_len = @min(self.size.cols, other.size.cols);
|
||||
const other_cells = src_row.cells.ptr(other.memory)[0..cell_len];
|
||||
const cells = dst_row.cells.ptr(self.memory)[0..cell_len];
|
||||
|
||||
// If we have no managed memory in the row, we can just copy.
|
||||
if (!dst_row.grapheme and !dst_row.styled) {
|
||||
fastmem.copy(Cell, cells, other_cells);
|
||||
@ -1278,3 +1278,47 @@ test "Page cloneFrom graphemes" {
|
||||
try testing.expectEqual(@as(u21, 0), rac.cell.content.codepoint);
|
||||
}
|
||||
}
|
||||
|
||||
test "Page cloneFrom frees dst graphemes" {
|
||||
var page = try Page.init(.{
|
||||
.cols = 10,
|
||||
.rows = 10,
|
||||
.styles = 8,
|
||||
});
|
||||
defer page.deinit();
|
||||
for (0..page.capacity.rows) |y| {
|
||||
const rac = page.getRowAndCell(1, y);
|
||||
rac.cell.* = .{
|
||||
.content_tag = .codepoint,
|
||||
.content = .{ .codepoint = @intCast(y + 1) },
|
||||
};
|
||||
}
|
||||
|
||||
// Clone
|
||||
var page2 = try Page.init(.{
|
||||
.cols = 10,
|
||||
.rows = 10,
|
||||
.styles = 8,
|
||||
});
|
||||
defer page2.deinit();
|
||||
for (0..page2.capacity.rows) |y| {
|
||||
const rac = page2.getRowAndCell(1, y);
|
||||
rac.cell.* = .{
|
||||
.content_tag = .codepoint,
|
||||
.content = .{ .codepoint = @intCast(y + 1) },
|
||||
};
|
||||
try page2.appendGrapheme(rac.row, rac.cell, 0x0A);
|
||||
}
|
||||
|
||||
// Clone from page which has no graphemes.
|
||||
try page2.cloneFrom(&page, 0, page.size.rows);
|
||||
|
||||
// Read it again
|
||||
for (0..page2.capacity.rows) |y| {
|
||||
const rac = page2.getRowAndCell(1, y);
|
||||
try testing.expectEqual(@as(u21, @intCast(y + 1)), rac.cell.content.codepoint);
|
||||
try testing.expect(!rac.row.grapheme);
|
||||
try testing.expect(!rac.cell.hasGrapheme());
|
||||
}
|
||||
try testing.expectEqual(@as(usize, 0), page2.graphemeCount());
|
||||
}
|
||||
|
Reference in New Issue
Block a user