mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 01:06:08 +03:00
terminal/new: pagelist resize to 1 col deletes wide chars
This commit is contained in:
@ -593,10 +593,6 @@ const ReflowCursor = struct {
|
||||
self.y = y;
|
||||
}
|
||||
|
||||
fn copyRowMetadata(self: *ReflowCursor, other: *const Row) void {
|
||||
self.page_row.semantic_prompt = other.semantic_prompt;
|
||||
}
|
||||
|
||||
fn countTrailingEmptyCells(self: *const ReflowCursor) usize {
|
||||
// If the row is wrapped, all empty cells are meaningful.
|
||||
if (self.page_row.wrap) return 0;
|
||||
@ -614,6 +610,10 @@ const ReflowCursor = struct {
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
fn copyRowMetadata(self: *ReflowCursor, other: *const Row) void {
|
||||
self.page_row.semantic_prompt = other.semantic_prompt;
|
||||
}
|
||||
};
|
||||
|
||||
/// Reflow the given page into the new capacity. The new capacity can have
|
||||
@ -728,6 +728,30 @@ fn reflowPage(
|
||||
dst_cursor.copyRowMetadata(src_cursor.page_row);
|
||||
}
|
||||
|
||||
// A rare edge case. If we're resizing down to 1 column
|
||||
// and the source is a non-narrow character, we reset the
|
||||
// cell to a narrow blank and we skip to the next cell.
|
||||
if (cap.cols == 1 and src_cursor.page_cell.wide != .narrow) {
|
||||
switch (src_cursor.page_cell.wide) {
|
||||
.narrow => unreachable,
|
||||
|
||||
// Wide char, we delete it, reset it to narrow,
|
||||
// and skip forward.
|
||||
.wide => {
|
||||
dst_cursor.page_cell.content.codepoint = 0;
|
||||
dst_cursor.page_cell.wide = .narrow;
|
||||
src_cursor.cursorForward();
|
||||
continue;
|
||||
},
|
||||
|
||||
// Skip spacer tails since we should've already
|
||||
// handled them in the previous cell.
|
||||
.spacer_tail => {},
|
||||
|
||||
// TODO: test?
|
||||
.spacer_head => {},
|
||||
}
|
||||
} else {
|
||||
switch (src_cursor.page_cell.content_tag) {
|
||||
// These are guaranteed to have no styling data and no
|
||||
// graphemes, a fast path.
|
||||
@ -776,6 +800,7 @@ fn reflowPage(
|
||||
dst_md.ref += 1;
|
||||
dst_cursor.page_cell.style_id = dst_md.id;
|
||||
}
|
||||
}
|
||||
|
||||
// If our original cursor was on this page, this x/y then
|
||||
// we need to update to the new location.
|
||||
@ -3787,3 +3812,48 @@ test "PageList resize reflow less cols copy style" {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test "PageList resize reflow less cols to eliminate a wide char" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var s = try init(alloc, 2, 1, 0);
|
||||
defer s.deinit();
|
||||
{
|
||||
try testing.expect(s.pages.first == s.pages.last);
|
||||
const page = &s.pages.first.?.data;
|
||||
|
||||
{
|
||||
const rac = page.getRowAndCell(0, 0);
|
||||
rac.cell.* = .{
|
||||
.content_tag = .codepoint,
|
||||
.content = .{ .codepoint = '😀' },
|
||||
.wide = .wide,
|
||||
};
|
||||
}
|
||||
{
|
||||
const rac = page.getRowAndCell(1, 0);
|
||||
rac.cell.* = .{
|
||||
.content_tag = .codepoint,
|
||||
.content = .{ .codepoint = ' ' },
|
||||
.wide = .spacer_tail,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Resize
|
||||
try s.resize(.{ .cols = 1, .reflow = true });
|
||||
try testing.expectEqual(@as(usize, 1), s.cols);
|
||||
try testing.expectEqual(@as(usize, 1), s.totalRows());
|
||||
|
||||
{
|
||||
try testing.expect(s.pages.first == s.pages.last);
|
||||
const page = &s.pages.first.?.data;
|
||||
|
||||
{
|
||||
const rac = page.getRowAndCell(0, 0);
|
||||
try testing.expectEqual(@as(u21, 0), rac.cell.content.codepoint);
|
||||
try testing.expectEqual(pagepkg.Cell.Wide.narrow, rac.cell.wide);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user