mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
terminal/new: fix issue with resizing when cursor is in blank trailing
cell
This commit is contained in:
@ -6556,6 +6556,7 @@ test "Screen: resize (no reflow) more cols with scrollback scrolled up" {
|
|||||||
try testing.expectEqual(@as(usize, 2), s.cursor.y);
|
try testing.expectEqual(@as(usize, 2), s.cursor.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// X
|
||||||
// https://github.com/mitchellh/ghostty/issues/1159
|
// https://github.com/mitchellh/ghostty/issues/1159
|
||||||
test "Screen: resize (no reflow) less cols with scrollback scrolled up" {
|
test "Screen: resize (no reflow) less cols with scrollback scrolled up" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
@ -6583,6 +6584,11 @@ test "Screen: resize (no reflow) less cols with scrollback scrolled up" {
|
|||||||
defer alloc.free(contents);
|
defer alloc.free(contents);
|
||||||
try testing.expectEqualStrings(str, contents);
|
try testing.expectEqualStrings(str, contents);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
const contents = try s.testString(alloc, .active);
|
||||||
|
defer alloc.free(contents);
|
||||||
|
try testing.expectEqualStrings("6\n7\n8", contents);
|
||||||
|
}
|
||||||
|
|
||||||
// Cursor remains at bottom
|
// Cursor remains at bottom
|
||||||
try testing.expectEqual(@as(usize, 1), s.cursor.x);
|
try testing.expectEqual(@as(usize, 1), s.cursor.x);
|
||||||
|
@ -760,6 +760,29 @@ fn reflowPage(
|
|||||||
// Move both our cursors forward
|
// Move both our cursors forward
|
||||||
src_cursor.cursorForward();
|
src_cursor.cursorForward();
|
||||||
dst_cursor.cursorForward();
|
dst_cursor.cursorForward();
|
||||||
|
} else cursor: {
|
||||||
|
// We made it through all our source columns. As a final edge
|
||||||
|
// case, if our cursor is in one of the blanks, we update it
|
||||||
|
// to the edge of this page.
|
||||||
|
|
||||||
|
// If we have no trailing empty cells, it can't be in the blanks.
|
||||||
|
if (trailing_empty == 0) break :cursor;
|
||||||
|
|
||||||
|
// If we have no cursor, nothing to update.
|
||||||
|
const c = cursor orelse break :cursor;
|
||||||
|
const offset = c.offset orelse break :cursor;
|
||||||
|
|
||||||
|
// If our cursor is on this page, and our x is greater than
|
||||||
|
// our end, we update to the edge.
|
||||||
|
if (&offset.page.data == src_cursor.page and
|
||||||
|
offset.row_offset == src_cursor.y and
|
||||||
|
c.x >= cols_len)
|
||||||
|
{
|
||||||
|
c.offset = .{
|
||||||
|
.page = dst_node,
|
||||||
|
.row_offset = dst_cursor.y,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We made it through all our source rows, we're done.
|
// We made it through all our source rows, we're done.
|
||||||
@ -3297,6 +3320,68 @@ test "PageList resize reflow less cols cursor in unchanged row" {
|
|||||||
try testing.expectEqual(@as(size.CellCountInt, 0), cursor.y);
|
try testing.expectEqual(@as(size.CellCountInt, 0), cursor.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "PageList resize reflow less cols cursor in blank cell" {
|
||||||
|
const testing = std.testing;
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
|
var s = try init(alloc, 6, 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..2) |x| {
|
||||||
|
const rac = page.getRowAndCell(x, y);
|
||||||
|
rac.cell.* = .{
|
||||||
|
.content_tag = .codepoint,
|
||||||
|
.content = .{ .codepoint = @intCast(x) },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set our cursor to be in a blank cell
|
||||||
|
var cursor: Resize.Cursor = .{ .x = 2, .y = 0 };
|
||||||
|
|
||||||
|
// Resize
|
||||||
|
try s.resize(.{ .cols = 4, .reflow = true, .cursor = &cursor });
|
||||||
|
try testing.expectEqual(@as(usize, 4), s.cols);
|
||||||
|
try testing.expectEqual(@as(usize, 2), s.totalRows());
|
||||||
|
|
||||||
|
// Our cursor should move to the first row
|
||||||
|
try testing.expectEqual(@as(size.CellCountInt, 2), cursor.x);
|
||||||
|
try testing.expectEqual(@as(size.CellCountInt, 0), cursor.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "PageList resize reflow less cols cursor in final blank cell" {
|
||||||
|
const testing = std.testing;
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
|
var s = try init(alloc, 6, 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..2) |x| {
|
||||||
|
const rac = page.getRowAndCell(x, y);
|
||||||
|
rac.cell.* = .{
|
||||||
|
.content_tag = .codepoint,
|
||||||
|
.content = .{ .codepoint = @intCast(x) },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set our cursor to be in the final cell of our resized
|
||||||
|
var cursor: Resize.Cursor = .{ .x = 3, .y = 0 };
|
||||||
|
|
||||||
|
// Resize
|
||||||
|
try s.resize(.{ .cols = 4, .reflow = true, .cursor = &cursor });
|
||||||
|
try testing.expectEqual(@as(usize, 4), s.cols);
|
||||||
|
try testing.expectEqual(@as(usize, 2), s.totalRows());
|
||||||
|
|
||||||
|
// Our cursor should move to the first row
|
||||||
|
try testing.expectEqual(@as(size.CellCountInt, 3), cursor.x);
|
||||||
|
try testing.expectEqual(@as(size.CellCountInt, 0), cursor.y);
|
||||||
|
}
|
||||||
|
|
||||||
test "PageList resize reflow less cols blank lines" {
|
test "PageList resize reflow less cols blank lines" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
@ -2258,6 +2258,51 @@ test "Screen: resize (no reflow) more cols with scrollback scrolled up" {
|
|||||||
try testing.expectEqual(@as(size.CellCountInt, 2), s.cursor.y);
|
try testing.expectEqual(@as(size.CellCountInt, 2), s.cursor.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://github.com/mitchellh/ghostty/issues/1159
|
||||||
|
test "Screen: resize (no reflow) less cols with scrollback scrolled up" {
|
||||||
|
const testing = std.testing;
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
|
var s = try init(alloc, 5, 3, 5);
|
||||||
|
defer s.deinit();
|
||||||
|
const str = "1\n2\n3\n4\n5\n6\n7\n8";
|
||||||
|
try s.testWriteString(str);
|
||||||
|
|
||||||
|
// Cursor at bottom
|
||||||
|
try testing.expectEqual(@as(size.CellCountInt, 1), s.cursor.x);
|
||||||
|
try testing.expectEqual(@as(size.CellCountInt, 2), s.cursor.y);
|
||||||
|
|
||||||
|
s.scroll(.{ .delta_row = -4 });
|
||||||
|
{
|
||||||
|
const contents = try s.dumpStringAlloc(alloc, .{ .viewport = .{} });
|
||||||
|
defer alloc.free(contents);
|
||||||
|
try testing.expectEqualStrings("2\n3\n4", contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
try s.resize(4, 3);
|
||||||
|
{
|
||||||
|
const contents = try s.dumpStringAlloc(alloc, .{ .screen = .{} });
|
||||||
|
defer alloc.free(contents);
|
||||||
|
try testing.expectEqualStrings(str, contents);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const contents = try s.dumpStringAlloc(alloc, .{ .active = .{} });
|
||||||
|
defer alloc.free(contents);
|
||||||
|
try testing.expectEqualStrings("6\n7\n8", contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cursor remains at bottom
|
||||||
|
try testing.expectEqual(@as(size.CellCountInt, 1), s.cursor.x);
|
||||||
|
try testing.expectEqual(@as(size.CellCountInt, 2), s.cursor.y);
|
||||||
|
|
||||||
|
// Old implementation doesn't do this but it makes sense to me:
|
||||||
|
// {
|
||||||
|
// const contents = try s.dumpStringAlloc(alloc, .{ .viewport = .{} });
|
||||||
|
// defer alloc.free(contents);
|
||||||
|
// try testing.expectEqualStrings("2\n3\n4", contents);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
test "Screen: resize more cols with reflow that fits full width" {
|
test "Screen: resize more cols with reflow that fits full width" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
Reference in New Issue
Block a user