mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
terminal/new: fix up cursor on grow cols
This commit is contained in:
@ -6442,6 +6442,7 @@ test "Screen: resize more rows with populated scrollback" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// X
|
||||||
test "Screen: resize more rows and cols with wrapping" {
|
test "Screen: resize more rows and cols with wrapping" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
@ -457,6 +457,46 @@ fn resizeGrowCols(
|
|||||||
} else {
|
} else {
|
||||||
for (total..self.rows) |_| _ = try self.grow();
|
for (total..self.rows) |_| _ = try self.grow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we have a cursor, we need to update the correct y value. I'm
|
||||||
|
// not at all happy about this, I wish we could do this in a more
|
||||||
|
// efficient way as we resize the pages. But at the time of typing this
|
||||||
|
// I can't think of a way and I'd rather get things working. Someone please
|
||||||
|
// help!
|
||||||
|
//
|
||||||
|
// The challenge is that as rows are unwrapped, we want to preserve the
|
||||||
|
// cursor. So for examle if you have "A\nB" where AB is soft-wrapped and
|
||||||
|
// the cursor is on 'B' (x=0, y=1) and you grow the columns, we want
|
||||||
|
// the cursor to remain on B (x=1, y=0) as it grows.
|
||||||
|
//
|
||||||
|
// The easy thing to do would be to count how many rows we unwrapped
|
||||||
|
// and then subtract that from the original y. That's how I started. The
|
||||||
|
// challenge is that if we unwrap with scrollback, our scrollback is
|
||||||
|
// "pulled down" so that the original (x=0,y=0) line is now pushed down.
|
||||||
|
// Detecting this while resizing seems non-obvious. This is a tested case
|
||||||
|
// so if you change this logic, you should see failures or passes if it
|
||||||
|
// works.
|
||||||
|
//
|
||||||
|
// The approach I take instead is if we have a cursor offset, I work
|
||||||
|
// backwards to find the offset we marked while reflowing and update
|
||||||
|
// the y from that. This is _not terrible_ because active areas are
|
||||||
|
// generally small and this is a more or less linear search. Its just
|
||||||
|
// kind of clunky.
|
||||||
|
if (cursor) |c| cursor: {
|
||||||
|
const offset = c.offset orelse break :cursor;
|
||||||
|
var active_it = self.rowIterator(.{ .active = .{} }, null);
|
||||||
|
var y: size.CellCountInt = 0;
|
||||||
|
while (active_it.next()) |it_offset| {
|
||||||
|
if (it_offset.page == offset.page and
|
||||||
|
it_offset.row_offset == offset.row_offset)
|
||||||
|
{
|
||||||
|
c.y = y;
|
||||||
|
break :cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
y += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We use a cursor to track where we are in the src/dst. This is very
|
// We use a cursor to track where we are in the src/dst. This is very
|
||||||
@ -672,6 +712,9 @@ fn reflowPage(
|
|||||||
// better calculate the CHANGE in coordinate by subtracting
|
// better calculate the CHANGE in coordinate by subtracting
|
||||||
// our dst from src which will calculate how many rows
|
// our dst from src which will calculate how many rows
|
||||||
// we unwrapped to get here.
|
// we unwrapped to get here.
|
||||||
|
//
|
||||||
|
// Note this doesn't handle when we pull down scrollback.
|
||||||
|
// See the cursor updates in resizeGrowCols for that.
|
||||||
c.y -|= src_cursor.y - dst_cursor.y;
|
c.y -|= src_cursor.y - dst_cursor.y;
|
||||||
|
|
||||||
c.offset = .{
|
c.offset = .{
|
||||||
|
@ -2476,14 +2476,13 @@ test "Screen: resize more cols with populated scrollback" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cursor should still be on the "5"
|
// Cursor should still be on the "5"
|
||||||
// TODO
|
{
|
||||||
// {
|
const list_cell = s.pages.getCell(.{ .active = .{
|
||||||
// const list_cell = s.pages.getCell(.{ .active = .{
|
.x = s.cursor.x,
|
||||||
// .x = s.cursor.x,
|
.y = s.cursor.y,
|
||||||
// .y = s.cursor.y,
|
} }).?;
|
||||||
// } }).?;
|
try testing.expectEqual(@as(u21, '5'), list_cell.cell.content.codepoint);
|
||||||
// try testing.expectEqual(@as(u21, '5'), list_cell.cell.content.codepoint);
|
}
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test "Screen: resize more cols with reflow" {
|
test "Screen: resize more cols with reflow" {
|
||||||
@ -2523,9 +2522,41 @@ test "Screen: resize more cols with reflow" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Our cursor should've moved
|
// Our cursor should've moved
|
||||||
// TODO
|
try testing.expectEqual(@as(size.CellCountInt, 2), s.cursor.x);
|
||||||
// try testing.expectEqual(@as(size.CellCountInt, 2), s.cursor.x);
|
try testing.expectEqual(@as(size.CellCountInt, 2), s.cursor.y);
|
||||||
// try testing.expectEqual(@as(size.CellCountInt, 2), s.cursor.y);
|
}
|
||||||
|
|
||||||
|
test "Screen: resize more rows and cols with wrapping" {
|
||||||
|
const testing = std.testing;
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
|
var s = try init(alloc, 2, 4, 0);
|
||||||
|
defer s.deinit();
|
||||||
|
const str = "1A2B\n3C4D";
|
||||||
|
try s.testWriteString(str);
|
||||||
|
{
|
||||||
|
const contents = try s.dumpStringAlloc(alloc, .{ .viewport = .{} });
|
||||||
|
defer alloc.free(contents);
|
||||||
|
const expected = "1A\n2B\n3C\n4D";
|
||||||
|
try testing.expectEqualStrings(expected, contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
try s.resize(5, 10);
|
||||||
|
|
||||||
|
// Cursor should move due to wrapping
|
||||||
|
try testing.expectEqual(@as(size.CellCountInt, 3), s.cursor.x);
|
||||||
|
try testing.expectEqual(@as(size.CellCountInt, 1), s.cursor.y);
|
||||||
|
|
||||||
|
{
|
||||||
|
const contents = try s.dumpStringAlloc(alloc, .{ .viewport = .{} });
|
||||||
|
defer alloc.free(contents);
|
||||||
|
try testing.expectEqualStrings(str, contents);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const contents = try s.dumpStringAlloc(alloc, .{ .screen = .{} });
|
||||||
|
defer alloc.free(contents);
|
||||||
|
try testing.expectEqualStrings(str, contents);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test "Screen: resize less rows no scrollback" {
|
test "Screen: resize less rows no scrollback" {
|
||||||
|
Reference in New Issue
Block a user