mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 09:16:11 +03:00
terminal2: lots more tracked pin logic
This commit is contained in:
@ -742,7 +742,7 @@ fn reflowPage(
|
|||||||
src_cursor.page_cell.wide == .wide and
|
src_cursor.page_cell.wide == .wide and
|
||||||
dst_cursor.x == cap.cols - 1)
|
dst_cursor.x == cap.cols - 1)
|
||||||
{
|
{
|
||||||
reflowUpdateCursor(cursor, &src_cursor, &dst_cursor, dst_node);
|
self.reflowUpdateCursor(cursor, &src_cursor, &dst_cursor, dst_node);
|
||||||
|
|
||||||
dst_cursor.page_cell.* = .{
|
dst_cursor.page_cell.* = .{
|
||||||
.content_tag = .codepoint,
|
.content_tag = .codepoint,
|
||||||
@ -758,7 +758,7 @@ fn reflowPage(
|
|||||||
src_cursor.page_cell.wide == .spacer_head and
|
src_cursor.page_cell.wide == .spacer_head and
|
||||||
dst_cursor.x != cap.cols - 1)
|
dst_cursor.x != cap.cols - 1)
|
||||||
{
|
{
|
||||||
reflowUpdateCursor(cursor, &src_cursor, &dst_cursor, dst_node);
|
self.reflowUpdateCursor(cursor, &src_cursor, &dst_cursor, dst_node);
|
||||||
src_cursor.cursorForward();
|
src_cursor.cursorForward();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -846,7 +846,7 @@ fn reflowPage(
|
|||||||
|
|
||||||
// If our original cursor was on this page, this x/y then
|
// If our original cursor was on this page, this x/y then
|
||||||
// we need to update to the new location.
|
// we need to update to the new location.
|
||||||
reflowUpdateCursor(cursor, &src_cursor, &dst_cursor, dst_node);
|
self.reflowUpdateCursor(cursor, &src_cursor, &dst_cursor, dst_node);
|
||||||
|
|
||||||
// Move both our cursors forward
|
// Move both our cursors forward
|
||||||
src_cursor.cursorForward();
|
src_cursor.cursorForward();
|
||||||
@ -859,6 +859,18 @@ fn reflowPage(
|
|||||||
// If we have no trailing empty cells, it can't be in the blanks.
|
// If we have no trailing empty cells, it can't be in the blanks.
|
||||||
if (trailing_empty == 0) break :cursor;
|
if (trailing_empty == 0) break :cursor;
|
||||||
|
|
||||||
|
// Update all our tracked pins
|
||||||
|
var it = self.tracked_pins.keyIterator();
|
||||||
|
while (it.next()) |p_ptr| {
|
||||||
|
const p = p_ptr.*;
|
||||||
|
if (&p.page.data != src_cursor.page or
|
||||||
|
p.y != src_cursor.y or
|
||||||
|
p.x < cols_len) continue;
|
||||||
|
|
||||||
|
p.page = dst_node;
|
||||||
|
p.y = dst_cursor.y;
|
||||||
|
}
|
||||||
|
|
||||||
// If we have no cursor, nothing to update.
|
// If we have no cursor, nothing to update.
|
||||||
const c = cursor orelse break :cursor;
|
const c = cursor orelse break :cursor;
|
||||||
const offset = c.offset orelse break :cursor;
|
const offset = c.offset orelse break :cursor;
|
||||||
@ -890,11 +902,25 @@ fn reflowPage(
|
|||||||
/// we're currently reflowing. This can then be fixed up later to an exact
|
/// we're currently reflowing. This can then be fixed up later to an exact
|
||||||
/// x/y (see resizeCols).
|
/// x/y (see resizeCols).
|
||||||
fn reflowUpdateCursor(
|
fn reflowUpdateCursor(
|
||||||
|
self: *const PageList,
|
||||||
cursor: ?*Resize.Cursor,
|
cursor: ?*Resize.Cursor,
|
||||||
src_cursor: *const ReflowCursor,
|
src_cursor: *const ReflowCursor,
|
||||||
dst_cursor: *const ReflowCursor,
|
dst_cursor: *const ReflowCursor,
|
||||||
dst_node: *List.Node,
|
dst_node: *List.Node,
|
||||||
) void {
|
) void {
|
||||||
|
// Update all our tracked pins
|
||||||
|
var it = self.tracked_pins.keyIterator();
|
||||||
|
while (it.next()) |p_ptr| {
|
||||||
|
const p = p_ptr.*;
|
||||||
|
if (&p.page.data != src_cursor.page or
|
||||||
|
p.y != src_cursor.y or
|
||||||
|
p.x != src_cursor.x) continue;
|
||||||
|
|
||||||
|
p.page = dst_node;
|
||||||
|
p.x = dst_cursor.x;
|
||||||
|
p.y = dst_cursor.y;
|
||||||
|
}
|
||||||
|
|
||||||
const c = cursor orelse return;
|
const c = cursor orelse return;
|
||||||
|
|
||||||
// If our original cursor was on this page, this x/y then
|
// If our original cursor was on this page, this x/y then
|
||||||
@ -3569,17 +3595,20 @@ test "PageList resize reflow more cols cursor in wrapped row" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set our cursor to be in the wrapped row
|
// Put a tracked pin in the history
|
||||||
var cursor: Resize.Cursor = .{ .x = 1, .y = 1 };
|
const p = try s.trackPin(s.pin(.{ .active = .{ .x = 1, .y = 1 } }).?);
|
||||||
|
defer s.untrackPin(p);
|
||||||
|
|
||||||
// Resize
|
// Resize
|
||||||
try s.resize(.{ .cols = 4, .reflow = true, .cursor = &cursor });
|
try s.resize(.{ .cols = 4, .reflow = true });
|
||||||
try testing.expectEqual(@as(usize, 4), s.cols);
|
try testing.expectEqual(@as(usize, 4), s.cols);
|
||||||
try testing.expectEqual(@as(usize, 4), s.totalRows());
|
try testing.expectEqual(@as(usize, 4), s.totalRows());
|
||||||
|
|
||||||
// Our cursor should move to the first row
|
// Our cursor should move to the first row
|
||||||
try testing.expectEqual(@as(size.CellCountInt, 3), cursor.x);
|
try testing.expectEqual(point.Point{ .active = .{
|
||||||
try testing.expectEqual(@as(size.CellCountInt, 0), cursor.y);
|
.x = 3,
|
||||||
|
.y = 0,
|
||||||
|
} }, s.pointFromPin(.active, p.*).?);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "PageList resize reflow more cols cursor in not wrapped row" {
|
test "PageList resize reflow more cols cursor in not wrapped row" {
|
||||||
@ -3617,17 +3646,20 @@ test "PageList resize reflow more cols cursor in not wrapped row" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set our cursor to be in the wrapped row
|
// Put a tracked pin in the history
|
||||||
var cursor: Resize.Cursor = .{ .x = 1, .y = 0 };
|
const p = try s.trackPin(s.pin(.{ .active = .{ .x = 1, .y = 0 } }).?);
|
||||||
|
defer s.untrackPin(p);
|
||||||
|
|
||||||
// Resize
|
// Resize
|
||||||
try s.resize(.{ .cols = 4, .reflow = true, .cursor = &cursor });
|
try s.resize(.{ .cols = 4, .reflow = true });
|
||||||
try testing.expectEqual(@as(usize, 4), s.cols);
|
try testing.expectEqual(@as(usize, 4), s.cols);
|
||||||
try testing.expectEqual(@as(usize, 4), s.totalRows());
|
try testing.expectEqual(@as(usize, 4), s.totalRows());
|
||||||
|
|
||||||
// Our cursor should move to the first row
|
// Our cursor should move to the first row
|
||||||
try testing.expectEqual(@as(size.CellCountInt, 1), cursor.x);
|
try testing.expectEqual(point.Point{ .active = .{
|
||||||
try testing.expectEqual(@as(size.CellCountInt, 0), cursor.y);
|
.x = 1,
|
||||||
|
.y = 0,
|
||||||
|
} }, s.pointFromPin(.active, p.*).?);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "PageList resize reflow more cols cursor in wrapped row that isn't unwrapped" {
|
test "PageList resize reflow more cols cursor in wrapped row that isn't unwrapped" {
|
||||||
@ -3679,17 +3711,20 @@ test "PageList resize reflow more cols cursor in wrapped row that isn't unwrappe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set our cursor to be in the wrapped row
|
// Put a tracked pin in the history
|
||||||
var cursor: Resize.Cursor = .{ .x = 1, .y = 2 };
|
const p = try s.trackPin(s.pin(.{ .active = .{ .x = 1, .y = 2 } }).?);
|
||||||
|
defer s.untrackPin(p);
|
||||||
|
|
||||||
// Resize
|
// Resize
|
||||||
try s.resize(.{ .cols = 4, .reflow = true, .cursor = &cursor });
|
try s.resize(.{ .cols = 4, .reflow = true });
|
||||||
try testing.expectEqual(@as(usize, 4), s.cols);
|
try testing.expectEqual(@as(usize, 4), s.cols);
|
||||||
try testing.expectEqual(@as(usize, 4), s.totalRows());
|
try testing.expectEqual(@as(usize, 4), s.totalRows());
|
||||||
|
|
||||||
// Our cursor should move to the first row
|
// Our cursor should move to the first row
|
||||||
try testing.expectEqual(@as(size.CellCountInt, 1), cursor.x);
|
try testing.expectEqual(point.Point{ .active = .{
|
||||||
try testing.expectEqual(@as(size.CellCountInt, 1), cursor.y);
|
.x = 1,
|
||||||
|
.y = 1,
|
||||||
|
} }, s.pointFromPin(.active, p.*).?);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "PageList resize reflow more cols no reflow preserves semantic prompt" {
|
test "PageList resize reflow more cols no reflow preserves semantic prompt" {
|
||||||
@ -4170,17 +4205,20 @@ test "PageList resize reflow less cols cursor in wrapped row" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set our cursor to be in the wrapped row
|
// Put a tracked pin in the history
|
||||||
var cursor: Resize.Cursor = .{ .x = 2, .y = 1 };
|
const p = try s.trackPin(s.pin(.{ .active = .{ .x = 2, .y = 1 } }).?);
|
||||||
|
defer s.untrackPin(p);
|
||||||
|
|
||||||
// Resize
|
// Resize
|
||||||
try s.resize(.{ .cols = 2, .reflow = true, .cursor = &cursor });
|
try s.resize(.{ .cols = 2, .reflow = true });
|
||||||
try testing.expectEqual(@as(usize, 2), s.cols);
|
try testing.expectEqual(@as(usize, 2), s.cols);
|
||||||
try testing.expectEqual(@as(usize, 4), s.totalRows());
|
try testing.expectEqual(@as(usize, 4), s.totalRows());
|
||||||
|
|
||||||
// Our cursor should move to the first row
|
// Our cursor should move to the first row
|
||||||
try testing.expectEqual(@as(size.CellCountInt, 0), cursor.x);
|
try testing.expectEqual(point.Point{ .active = .{
|
||||||
try testing.expectEqual(@as(size.CellCountInt, 1), cursor.y);
|
.x = 0,
|
||||||
|
.y = 1,
|
||||||
|
} }, s.pointFromPin(.active, p.*).?);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "PageList resize reflow less cols cursor goes to scrollback" {
|
test "PageList resize reflow less cols cursor goes to scrollback" {
|
||||||
@ -4201,17 +4239,17 @@ test "PageList resize reflow less cols cursor goes to scrollback" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set our cursor to be in the wrapped row
|
// Put a tracked pin in the history
|
||||||
var cursor: Resize.Cursor = .{ .x = 2, .y = 0 };
|
const p = try s.trackPin(s.pin(.{ .active = .{ .x = 2, .y = 0 } }).?);
|
||||||
|
defer s.untrackPin(p);
|
||||||
|
|
||||||
// Resize
|
// Resize
|
||||||
try s.resize(.{ .cols = 2, .reflow = true, .cursor = &cursor });
|
try s.resize(.{ .cols = 2, .reflow = true });
|
||||||
try testing.expectEqual(@as(usize, 2), s.cols);
|
try testing.expectEqual(@as(usize, 2), s.cols);
|
||||||
try testing.expectEqual(@as(usize, 4), s.totalRows());
|
try testing.expectEqual(@as(usize, 4), s.totalRows());
|
||||||
|
|
||||||
// Our cursor should move to the first row
|
// Our cursor should move to the first row
|
||||||
try testing.expectEqual(@as(size.CellCountInt, 0), cursor.x);
|
try testing.expect(s.pointFromPin(.active, p.*) == null);
|
||||||
try testing.expectEqual(@as(size.CellCountInt, 0), cursor.y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test "PageList resize reflow less cols cursor in unchanged row" {
|
test "PageList resize reflow less cols cursor in unchanged row" {
|
||||||
@ -4232,17 +4270,20 @@ test "PageList resize reflow less cols cursor in unchanged row" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set our cursor to be in the wrapped row
|
// Put a tracked pin in the history
|
||||||
var cursor: Resize.Cursor = .{ .x = 1, .y = 0 };
|
const p = try s.trackPin(s.pin(.{ .active = .{ .x = 1, .y = 0 } }).?);
|
||||||
|
defer s.untrackPin(p);
|
||||||
|
|
||||||
// Resize
|
// Resize
|
||||||
try s.resize(.{ .cols = 2, .reflow = true, .cursor = &cursor });
|
try s.resize(.{ .cols = 2, .reflow = true });
|
||||||
try testing.expectEqual(@as(usize, 2), s.cols);
|
try testing.expectEqual(@as(usize, 2), s.cols);
|
||||||
try testing.expectEqual(@as(usize, 2), s.totalRows());
|
try testing.expectEqual(@as(usize, 2), s.totalRows());
|
||||||
|
|
||||||
// Our cursor should move to the first row
|
// Our cursor should move to the first row
|
||||||
try testing.expectEqual(@as(size.CellCountInt, 1), cursor.x);
|
try testing.expectEqual(point.Point{ .active = .{
|
||||||
try testing.expectEqual(@as(size.CellCountInt, 0), cursor.y);
|
.x = 1,
|
||||||
|
.y = 0,
|
||||||
|
} }, s.pointFromPin(.active, p.*).?);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "PageList resize reflow less cols cursor in blank cell" {
|
test "PageList resize reflow less cols cursor in blank cell" {
|
||||||
@ -4263,17 +4304,20 @@ test "PageList resize reflow less cols cursor in blank cell" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set our cursor to be in a blank cell
|
// Put a tracked pin in the history
|
||||||
var cursor: Resize.Cursor = .{ .x = 2, .y = 0 };
|
const p = try s.trackPin(s.pin(.{ .active = .{ .x = 2, .y = 0 } }).?);
|
||||||
|
defer s.untrackPin(p);
|
||||||
|
|
||||||
// Resize
|
// Resize
|
||||||
try s.resize(.{ .cols = 4, .reflow = true, .cursor = &cursor });
|
try s.resize(.{ .cols = 4, .reflow = true });
|
||||||
try testing.expectEqual(@as(usize, 4), s.cols);
|
try testing.expectEqual(@as(usize, 4), s.cols);
|
||||||
try testing.expectEqual(@as(usize, 2), s.totalRows());
|
try testing.expectEqual(@as(usize, 2), s.totalRows());
|
||||||
|
|
||||||
// Our cursor should move to the first row
|
// Our cursor should not move
|
||||||
try testing.expectEqual(@as(size.CellCountInt, 2), cursor.x);
|
try testing.expectEqual(point.Point{ .active = .{
|
||||||
try testing.expectEqual(@as(size.CellCountInt, 0), cursor.y);
|
.x = 2,
|
||||||
|
.y = 0,
|
||||||
|
} }, s.pointFromPin(.active, p.*).?);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "PageList resize reflow less cols cursor in final blank cell" {
|
test "PageList resize reflow less cols cursor in final blank cell" {
|
||||||
|
Reference in New Issue
Block a user