mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 16:26:08 +03:00
terminal/new: copy graphemes for reflow
This commit is contained in:
@ -6643,6 +6643,7 @@ test "Screen: resize more cols no reflow preserves semantic prompt" {
|
||||
}
|
||||
}
|
||||
|
||||
// X
|
||||
test "Screen: resize more cols grapheme map" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
@ -7139,6 +7140,7 @@ test "Screen: resize less cols trailing background colors" {
|
||||
}
|
||||
}
|
||||
|
||||
// X
|
||||
test "Screen: resize less cols with graphemes" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
@ -714,12 +714,29 @@ fn reflowPage(
|
||||
|
||||
.codepoint => {
|
||||
dst_cursor.page_cell.* = src_cursor.page_cell.*;
|
||||
// TODO: style copy
|
||||
},
|
||||
|
||||
else => @panic("TODO"),
|
||||
.codepoint_grapheme => {
|
||||
// We copy the cell like normal but we have to reset the
|
||||
// tag because this is used for fast-path detection in
|
||||
// appendGrapheme.
|
||||
dst_cursor.page_cell.* = src_cursor.page_cell.*;
|
||||
dst_cursor.page_cell.content_tag = .codepoint;
|
||||
|
||||
// Copy the graphemes
|
||||
const src_cps = src_cursor.page.lookupGrapheme(src_cursor.page_cell).?;
|
||||
for (src_cps) |cp| {
|
||||
try dst_cursor.page.appendGrapheme(
|
||||
dst_cursor.page_row,
|
||||
dst_cursor.page_cell,
|
||||
cp,
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// TODO: style copy
|
||||
|
||||
// If our original cursor was on this page, this x/y then
|
||||
// we need to update to the new location.
|
||||
if (cursor) |c| cursor: {
|
||||
@ -3253,6 +3270,89 @@ test "PageList resize reflow less cols wrapped rows" {
|
||||
}
|
||||
}
|
||||
|
||||
test "PageList resize reflow less cols wrapped rows with graphemes" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var s = try init(alloc, 4, 2, null);
|
||||
defer s.deinit();
|
||||
{
|
||||
try testing.expect(s.pages.first == s.pages.last);
|
||||
const page = &s.pages.first.?.data;
|
||||
for (0..s.rows) |y| {
|
||||
for (0..s.cols) |x| {
|
||||
const rac = page.getRowAndCell(x, y);
|
||||
rac.cell.* = .{
|
||||
.content_tag = .codepoint,
|
||||
.content = .{ .codepoint = @intCast(x) },
|
||||
};
|
||||
}
|
||||
|
||||
const rac = page.getRowAndCell(2, y);
|
||||
try page.appendGrapheme(rac.row, rac.cell, 'A');
|
||||
}
|
||||
}
|
||||
|
||||
// Resize
|
||||
try s.resize(.{ .cols = 2, .reflow = true });
|
||||
try testing.expectEqual(@as(usize, 2), s.cols);
|
||||
try testing.expectEqual(@as(usize, 4), s.totalRows());
|
||||
|
||||
// Active moves due to scrollback
|
||||
{
|
||||
const pt = s.getCell(.{ .active = .{} }).?.screenPoint();
|
||||
try testing.expectEqual(point.Point{ .screen = .{
|
||||
.x = 0,
|
||||
.y = 2,
|
||||
} }, pt);
|
||||
}
|
||||
|
||||
try testing.expect(s.pages.first == s.pages.last);
|
||||
const page = &s.pages.first.?.data;
|
||||
var it = s.rowIterator(.{ .screen = .{} }, null);
|
||||
{
|
||||
// First row should be wrapped
|
||||
const offset = it.next().?;
|
||||
const rac = offset.rowAndCell(0);
|
||||
const cells = offset.page.data.getCells(rac.row);
|
||||
try testing.expect(rac.row.wrap);
|
||||
try testing.expectEqual(@as(usize, 2), cells.len);
|
||||
try testing.expectEqual(@as(u21, 0), cells[0].content.codepoint);
|
||||
}
|
||||
{
|
||||
const offset = it.next().?;
|
||||
const rac = offset.rowAndCell(0);
|
||||
const cells = offset.page.data.getCells(rac.row);
|
||||
try testing.expect(!rac.row.wrap);
|
||||
try testing.expectEqual(@as(usize, 2), cells.len);
|
||||
try testing.expectEqual(@as(u21, 2), cells[0].content.codepoint);
|
||||
|
||||
const cps = page.lookupGrapheme(rac.cell).?;
|
||||
try testing.expectEqual(@as(usize, 1), cps.len);
|
||||
try testing.expectEqual(@as(u21, 'A'), cps[0]);
|
||||
}
|
||||
{
|
||||
// First row should be wrapped
|
||||
const offset = it.next().?;
|
||||
const rac = offset.rowAndCell(0);
|
||||
const cells = offset.page.data.getCells(rac.row);
|
||||
try testing.expect(rac.row.wrap);
|
||||
try testing.expectEqual(@as(usize, 2), cells.len);
|
||||
try testing.expectEqual(@as(u21, 0), cells[0].content.codepoint);
|
||||
}
|
||||
{
|
||||
const offset = it.next().?;
|
||||
const rac = offset.rowAndCell(0);
|
||||
const cells = offset.page.data.getCells(rac.row);
|
||||
try testing.expect(!rac.row.wrap);
|
||||
try testing.expectEqual(@as(usize, 2), cells.len);
|
||||
try testing.expectEqual(@as(u21, 2), cells[0].content.codepoint);
|
||||
|
||||
const cps = page.lookupGrapheme(rac.cell).?;
|
||||
try testing.expectEqual(@as(usize, 1), cps.len);
|
||||
try testing.expectEqual(@as(u21, 'A'), cps[0]);
|
||||
}
|
||||
}
|
||||
test "PageList resize reflow less cols cursor in wrapped row" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
Reference in New Issue
Block a user